diff --git a/CHANGELOG.md b/CHANGELOG.md index e54d3349b..4289388ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - The toolbar in the home UI now collapses when scrolling - The toolbar layout is now consistent with Material Design 3 - Genre parsing now handles multiple integer values and cover/remix indicators (May wipe playback state) + +#### What's Fixed - Playback bar now picks the larger inset in case that gesture inset is missing [#149] #### Dev/Meta diff --git a/app/src/main/java/org/oxycblt/auxio/image/BaseFetcher.kt b/app/src/main/java/org/oxycblt/auxio/image/BaseFetcher.kt index 50cfc0e67..2364f4998 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/BaseFetcher.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/BaseFetcher.kt @@ -74,8 +74,7 @@ abstract class BaseFetcher : Fetcher { fetchMediaStoreCovers(context, album) } } catch (e: Exception) { - logW("Unable to extract album art due to an error") - logW(e.stackTraceToString()) + logW("Unable to extract album art due to an error: $e") null } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/StyledSeekBar.kt b/app/src/main/java/org/oxycblt/auxio/playback/StyledSeekBar.kt index d3e1554c7..0033f3ed9 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/StyledSeekBar.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/StyledSeekBar.kt @@ -54,7 +54,7 @@ constructor( FrameLayout(context, attrs, defStyleAttr), Slider.OnSliderTouchListener, Slider.OnChangeListener { - private val binding = ViewSeekBarBinding.inflate(context.inflater, this, true) + private val binding = ViewSeekBarBinding.inflate(context.inflater, this) init { binding.seekBarSlider.addOnSliderTouchListener(this) diff --git a/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt b/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt index 792b6cc3f..8ac6a7094 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt @@ -29,6 +29,7 @@ import androidx.annotation.StringRes import androidx.appcompat.widget.AppCompatImageView import androidx.core.graphics.drawable.DrawableCompat import coil.dispose +import coil.drawable.CrossfadeDrawable import coil.load import com.google.android.material.shape.MaterialShapeDrawable import org.oxycblt.auxio.R @@ -50,19 +51,18 @@ import org.oxycblt.auxio.util.getDrawableSafe * of the view size, and corner radius application depending on user preference. * @author OxygenCobalt * - * TODO: Rework this layout into a total ViewGroup that enables more customization + an indicator + * TODO: I'll need to make it a whole ViewGroup eventually */ class StyledImageView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) : AppCompatImageView(context, attrs, defStyleAttr) { private var cornerRadius = 0f + private var indicator = StyledDrawable(context, R.drawable.ic_equalizer) init { val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StyledImageView) - cornerRadius = styledAttrs.getDimension(R.styleable.StyledImageView_cornerRadius, 0f) - styledAttrs.recycle() // Use clipToOutline and a background drawable to crop images. While Coil's transformation @@ -95,19 +95,35 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr } } + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + if (isActivated) { + // We can't modify the view alpha since that would change the background opacity, + // but we also can't modify the image alpha since that breaks CrossfadeDrawable. + // Instead, we just draw the background again when activated in order to obscure + // the actual image, and then draw the indicator. The only other option is to make + // a proper ViewGroup, and I really don't want that. + val src = drawable?.let { if (it is CrossfadeDrawable) it.end else it } + background.alpha = if (src is StyledDrawable) 255 else 128 + background.draw(canvas) + background.alpha = 255 + indicator.draw(canvas) + } + } + /** Bind the album cover for a [song]. */ - fun bind(song: Song) = load(song, R.drawable.ic_song, R.string.desc_album_cover) + fun bind(song: Song) = loadImpl(song, R.drawable.ic_song, R.string.desc_album_cover) /** Bind the album cover for an [album]. */ - fun bind(album: Album) = load(album, R.drawable.ic_album, R.string.desc_album_cover) + fun bind(album: Album) = loadImpl(album, R.drawable.ic_album, R.string.desc_album_cover) /** Bind the image for an [artist] */ - fun bind(artist: Artist) = load(artist, R.drawable.ic_artist, R.string.desc_artist_image) + fun bind(artist: Artist) = loadImpl(artist, R.drawable.ic_artist, R.string.desc_artist_image) /** Bind the image for a [genre] */ - fun bind(genre: Genre) = load(genre, R.drawable.ic_genre, R.string.desc_genre_image) + fun bind(genre: Genre) = loadImpl(genre, R.drawable.ic_genre, R.string.desc_genre_image) - private fun load(music: T, @DrawableRes error: Int, @StringRes desc: Int) { + private fun loadImpl(music: T, @DrawableRes error: Int, @StringRes desc: Int) { dispose() load(music) { error(StyledDrawable(context, error)) diff --git a/app/src/main/res/color/sel_track_cover.xml b/app/src/main/res/color/sel_track_cover.xml new file mode 100644 index 000000000..d7ade8a18 --- /dev/null +++ b/app/src/main/res/color/sel_track_cover.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_equalizer.xml b/app/src/main/res/drawable/ic_equalizer.xml new file mode 100644 index 000000000..c1aa427a0 --- /dev/null +++ b/app/src/main/res/drawable/ic_equalizer.xml @@ -0,0 +1,11 @@ + + + + diff --git a/app/src/main/res/layout/item_album_song.xml b/app/src/main/res/layout/item_album_song.xml index 0a2f760fe..ab77685b0 100644 --- a/app/src/main/res/layout/item_album_song.xml +++ b/app/src/main/res/layout/item_album_song.xml @@ -8,7 +8,8 @@ + view. The way we do this is odd, but it's designed this way. + --> - + android:layout_height="wrap_content" + tools:parentTag="android.widget.FrameLayout"> - \ No newline at end of file + \ No newline at end of file