ui: remove album name from song items
Remove the album name from the main song item in favor of a duration value. Auxio has traditionally used "Artist . Album" for song items. However, this had some shortcomings: 1. The way the artist and album names are packed probably results in truncation on small screens, which I doubt is very helpful. 2. All other items in Auxio have only one specific "subject" per line, which makes the song items a bit of an outlier since it has two (the artist and the album) 3. The empty space available could be used for another UI element, such as a duration or maybe a menu button in the future. For consistency, this also removes the song count from all album items as well.
This commit is contained in:
parent
c5be39774a
commit
d7babcba71
11 changed files with 39 additions and 25 deletions
|
@ -7,10 +7,13 @@
|
|||
- Shuffle and Repeat mode buttons now have more contrast when they are turned on
|
||||
|
||||
#### What's Fixed
|
||||
- Fixed crash on certain devices running Android 10 and lower when a differing theme from the system theme was used.
|
||||
- Fixed crash on certain devices running Android 10 and lower when a differing theme
|
||||
from the system theme was used.
|
||||
|
||||
#### What's Changed
|
||||
- All cover art is now cropped to a 1:1 aspect ratio
|
||||
- Song items no longer show an album in favor of a duration
|
||||
- Album items no longer show a song count
|
||||
|
||||
#### Dev/Meta
|
||||
- Enabled elevation drop shadows below Android P for consistency
|
||||
|
|
|
@ -24,7 +24,7 @@ import coil.ImageLoaderFactory
|
|||
import coil.request.CachePolicy
|
||||
import org.oxycblt.auxio.coil.AlbumArtFetcher
|
||||
import org.oxycblt.auxio.coil.ArtistImageFetcher
|
||||
import org.oxycblt.auxio.coil.ErrorCrossfadeFactory
|
||||
import org.oxycblt.auxio.coil.CrossfadeFactory
|
||||
import org.oxycblt.auxio.coil.GenreImageFetcher
|
||||
import org.oxycblt.auxio.coil.MusicKeyer
|
||||
import org.oxycblt.auxio.settings.SettingsManager
|
||||
|
@ -48,7 +48,7 @@ class AuxioApp : Application(), ImageLoaderFactory {
|
|||
add(GenreImageFetcher.Factory())
|
||||
add(MusicKeyer())
|
||||
}
|
||||
.transitionFactory(ErrorCrossfadeFactory())
|
||||
.transitionFactory(CrossfadeFactory())
|
||||
.diskCachePolicy(CachePolicy.DISABLED) // Not downloading anything, so no disk-caching
|
||||
.build()
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import android.util.Size as AndroidSize
|
|||
* @author OxygenCobalt
|
||||
* TODO: Artist images
|
||||
*/
|
||||
abstract class AuxioFetcher : Fetcher {
|
||||
abstract class BaseFetcher : Fetcher {
|
||||
private val settingsManager = SettingsManager.getInstance()
|
||||
|
||||
/**
|
||||
|
@ -193,7 +193,6 @@ abstract class AuxioFetcher : Fetcher {
|
|||
// In the case a front cover is not found, use the first image in the tag instead.
|
||||
// This can be corrected later on if a front cover frame is found.
|
||||
logW("No front cover image, using image of type $type instead")
|
||||
|
||||
stream = ByteArrayInputStream(pic)
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ import coil.transition.TransitionTarget
|
|||
* You know. Like they used to.
|
||||
* @author Coil Team
|
||||
*/
|
||||
class ErrorCrossfadeFactory : Transition.Factory {
|
||||
class CrossfadeFactory : Transition.Factory {
|
||||
override fun create(target: TransitionTarget, result: ImageResult): Transition {
|
||||
// Don't animate if the request was fulfilled by the memory cache.
|
||||
if (result is SuccessResult && result.dataSource == DataSource.MEMORY_CACHE) {
|
|
@ -43,7 +43,7 @@ import kotlin.math.min
|
|||
class AlbumArtFetcher private constructor(
|
||||
private val context: Context,
|
||||
private val album: Album
|
||||
) : AuxioFetcher() {
|
||||
) : BaseFetcher() {
|
||||
override suspend fun fetch(): FetchResult? {
|
||||
return fetchArt(context, album)?.let { stream ->
|
||||
SourceResult(
|
||||
|
@ -75,7 +75,7 @@ class ArtistImageFetcher private constructor(
|
|||
private val context: Context,
|
||||
private val size: Size,
|
||||
private val artist: Artist,
|
||||
) : AuxioFetcher() {
|
||||
) : BaseFetcher() {
|
||||
override suspend fun fetch(): FetchResult? {
|
||||
val albums = Sort.ByName(true)
|
||||
.sortAlbums(artist.albums)
|
||||
|
@ -101,7 +101,7 @@ class GenreImageFetcher private constructor(
|
|||
private val context: Context,
|
||||
private val size: Size,
|
||||
private val genre: Genre,
|
||||
) : AuxioFetcher() {
|
||||
) : BaseFetcher() {
|
||||
override suspend fun fetch(): FetchResult? {
|
||||
// We don't need to sort here, as the way we
|
||||
val albums = genre.songs.groupBy { it.album }.keys
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.oxycblt.auxio.music.Song
|
|||
class MusicKeyer : Keyer<Music> {
|
||||
override fun key(data: Music, options: Options): String {
|
||||
return if (data is Song) {
|
||||
// Group up song covers with album covers for better caching
|
||||
key(data.album, options)
|
||||
} else {
|
||||
"${data::class.simpleName}: ${data.id}"
|
||||
|
|
|
@ -34,10 +34,11 @@ class RoundableImageView @JvmOverloads constructor(
|
|||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
|
||||
// As for why we use clipToOutline instead of coils RoundedCornersTransformation, the radii
|
||||
// of an image's corners is dependent on the actual dimensions of the image, which would
|
||||
// force us to resize all images to a fixed size. clipToOutline is pretty much always
|
||||
// cheaper as long as we have a perfectly-square image.
|
||||
// Use clipToOutline and a background drawable to crop images. While Coil's transformation
|
||||
// could theoretically be used to round corners, the corner radius is dependent on the
|
||||
// dimensions of the image, which will result in inconsistent corners across different
|
||||
// album covers unless we resize all covers to be the same size. clipToOutline is both
|
||||
// cheaper and more elegant.
|
||||
val settingsManager = SettingsManager.getInstance()
|
||||
clipToOutline = settingsManager.roundCovers
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ class SquareFrameTransform : Transformation {
|
|||
get() = "SquareFrameTransform"
|
||||
|
||||
override suspend fun transform(input: Bitmap, size: Size): Bitmap {
|
||||
// Find the smaller dimension and then take a center portion of the image that
|
||||
// has that size.
|
||||
val dstSize = min(input.width, input.height)
|
||||
val x = (input.width - dstSize) / 2
|
||||
val y = (input.height - dstSize) / 2
|
||||
|
|
|
@ -131,11 +131,7 @@ fun TextView.bindSongInfo(song: Song?) {
|
|||
return
|
||||
}
|
||||
|
||||
text = context.getString(
|
||||
R.string.fmt_two,
|
||||
song.resolvedArtistName,
|
||||
song.resolvedAlbumName
|
||||
)
|
||||
text = song.resolvedArtistName
|
||||
}
|
||||
|
||||
@BindingAdapter("albumInfo")
|
||||
|
@ -145,10 +141,7 @@ fun TextView.bindAlbumInfo(album: Album?) {
|
|||
return
|
||||
}
|
||||
|
||||
text = context.getString(
|
||||
R.string.fmt_two, album.resolvedArtistName,
|
||||
context.getPluralSafe(R.plurals.fmt_song_count, album.songs.size)
|
||||
)
|
||||
text = album.resolvedArtistName
|
||||
}
|
||||
|
||||
@BindingAdapter("artistInfo")
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{song.name}"
|
||||
android:layout_marginEnd="@dimen/spacing_small"
|
||||
app:layout_constraintBottom_toTopOf="@+id/song_info"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/song_duration"
|
||||
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
|
@ -43,11 +44,26 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:songInfo="@{song}"
|
||||
android:layout_marginEnd="@dimen/spacing_small"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/song_duration"
|
||||
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
||||
app:layout_constraintTop_toBottomOf="@+id/song_name"
|
||||
tools:text="Artist / Album" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/song_duration"
|
||||
style="@style/Widget.Auxio.TextView.Item.Tertiary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="none"
|
||||
android:gravity="end"
|
||||
android:text="@{song.formattedDuration}"
|
||||
android:textAlignment="viewEnd"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="16:16" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
|
@ -4,7 +4,6 @@
|
|||
<string name="info_app_name" translatable="false">Auxio</string>
|
||||
|
||||
<!-- Format Namespace | Value formatting/plurals -->
|
||||
<string name="fmt_two" translatable="false">%1$s • %2$s</string>
|
||||
<string name="fmt_three" translatable="false">%1$s • %2$s • %3$s</string>
|
||||
<string name="fmt_counts" translatable="false">%1$s, %2$s</string>
|
||||
<string name="fmt_track" translatable="false">%d</string>
|
||||
|
|
Loading…
Reference in a new issue