diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad5ecae61..1e37ad868 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@
- Added disc number support
- Added ReplayGain support for below-reference volume tracks [i.e positive ReplayGain values]
- About screen now shows counts for multiple types of library items, alongside a total duration
+- New disc, track, song count, and duration sorting modes
+
+### What's Improved
+- The tab selector now hides itself when there is only one tab
#### What's Fixed
- Fixed incorrect ellipsizing on song items
diff --git a/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt b/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt
index 4f96102ff..a28e0d47a 100644
--- a/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt
+++ b/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt
@@ -21,11 +21,11 @@ import android.app.Application
import coil.ImageLoader
import coil.ImageLoaderFactory
import coil.request.CachePolicy
-import org.oxycblt.auxio.coil.AlbumArtFetcher
-import org.oxycblt.auxio.coil.ArtistImageFetcher
-import org.oxycblt.auxio.coil.CrossfadeFactory
-import org.oxycblt.auxio.coil.GenreImageFetcher
-import org.oxycblt.auxio.coil.MusicKeyer
+import org.oxycblt.auxio.image.AlbumArtFetcher
+import org.oxycblt.auxio.image.ArtistImageFetcher
+import org.oxycblt.auxio.image.CrossfadeFactory
+import org.oxycblt.auxio.image.GenreImageFetcher
+import org.oxycblt.auxio.image.MusicKeyer
import org.oxycblt.auxio.settings.SettingsManager
@Suppress("UNUSED")
diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
index 6e7f8906f..dac057bdf 100644
--- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
+++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
@@ -42,13 +42,11 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
*
* TODO: Custom language support
*
- * TODO: Rework menus [perhaps add multi-select]
- *
- * TODO: Rework some fragments to use listeners *even more*
- *
* TODO: Fix how selection works in the RecyclerViews (doing it poorly right now)
*
* TODO: Rework padding ethos
+ *
+ * @author OxygenCobalt
*/
class MainActivity : AppCompatActivity() {
private val playbackModel: PlaybackViewModel by viewModels()
diff --git a/app/src/main/java/org/oxycblt/auxio/coil/StyledImageView.kt b/app/src/main/java/org/oxycblt/auxio/coil/StyledImageView.kt
deleted file mode 100644
index 724f2589e..000000000
--- a/app/src/main/java/org/oxycblt/auxio/coil/StyledImageView.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2022 Auxio Project
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.oxycblt.auxio.coil
-
-import android.content.Context
-import android.graphics.Matrix
-import android.graphics.RectF
-import android.util.AttributeSet
-import android.widget.ImageView
-import androidx.annotation.AttrRes
-import androidx.annotation.DrawableRes
-import androidx.annotation.StringRes
-import androidx.appcompat.widget.AppCompatImageView
-import coil.dispose
-import coil.load
-import com.google.android.material.shape.MaterialShapeDrawable
-import kotlin.math.min
-import org.oxycblt.auxio.R
-import org.oxycblt.auxio.music.Album
-import org.oxycblt.auxio.music.Artist
-import org.oxycblt.auxio.music.Genre
-import org.oxycblt.auxio.music.Music
-import org.oxycblt.auxio.music.Song
-import org.oxycblt.auxio.settings.SettingsManager
-import org.oxycblt.auxio.util.getColorStateListSafe
-
-/**
- * An [AppCompatImageView] that applies many of the stylistic choices that Auxio uses regarding
- * images.
- */
-class StyledImageView
-@JvmOverloads
-constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
- AppCompatImageView(context, attrs, defStyleAttr) {
- private val centerMatrix = Matrix()
- private val matrixSrc = RectF()
- private val matrixDst = RectF()
- private var cornerRadius = 0f
-
- init {
- val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StyledImageView)
- cornerRadius = styledAttrs.getDimension(R.styleable.StyledImageView_cornerRadius, 0f)
- styledAttrs.recycle()
-
- clipToOutline = true
- background =
- MaterialShapeDrawable().apply {
- fillColor = context.getColorStateListSafe(R.color.sel_cover_bg)
- }
- }
-
- override fun onAttachedToWindow() {
- super.onAttachedToWindow()
-
- // 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.
- if (!isInEditMode) {
- val settingsManager = SettingsManager.getInstance()
- if (settingsManager.roundCovers) {
- (background as MaterialShapeDrawable).setCornerSize(cornerRadius)
- }
- }
- }
-
- override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec)
-
- // Scale the image down to half-size
- imageMatrix =
- centerMatrix.apply {
- reset()
- drawable?.let { drawable ->
- // Android is too good to allow us to set a fixed image size, so we instead need
- // to define a matrix to scale an image directly.
-
- // First scale the icon up to the desired size.
- val iconSize = min(measuredWidth, measuredHeight) / 2f
- matrixSrc.set(
- 0f,
- 0f,
- drawable.intrinsicWidth.toFloat(),
- drawable.intrinsicHeight.toFloat())
- matrixDst.set(0f, 0f, iconSize, iconSize)
- centerMatrix.setRectToRect(matrixSrc, matrixDst, Matrix.ScaleToFit.CENTER)
-
- // Then actually center it into the icon, which the previous call does not
- // actually do.
- centerMatrix.postTranslate(
- (measuredWidth - iconSize) / 2f, (measuredHeight - iconSize) / 2f)
- }
- }
- }
-}
-
-// TODO: Borg the extension methods into the view
-
-/** Bind the album cover for a [song]. */
-fun StyledImageView.bindAlbumCover(song: Song) =
- load(song, R.drawable.ic_song, R.string.desc_album_cover)
-
-/** Bind the album cover for an [album]. */
-fun StyledImageView.bindAlbumCover(album: Album) =
- load(album, R.drawable.ic_album, R.string.desc_album_cover)
-
-/** Bind the image for an [artist] */
-fun StyledImageView.bindArtistImage(artist: Artist) =
- load(artist, R.drawable.ic_artist, R.string.desc_artist_image)
-
-/** Bind the image for a [genre] */
-fun StyledImageView.bindGenreImage(genre: Genre) =
- load(genre, R.drawable.ic_genre, R.string.desc_genre_image)
-
-private fun StyledImageView.load(
- music: T,
- @DrawableRes error: Int,
- @StringRes desc: Int
-) {
- contentDescription = context.getString(desc, music.resolveName(context))
- dispose()
- load(music) {
- error(error)
- transformations(SquareFrameTransform.INSTANCE)
- listener(
- onSuccess = { _, _ ->
- // Using the matrix scale type will shrink the cover images, so set it back to
- // the default scale type.
- scaleType = ImageView.ScaleType.FIT_CENTER
- },
- onError = { _, _ ->
- // Error icons need to be scaled correctly, so set it to the custom matrix
- // that the ImageView applies
- scaleType = ImageView.ScaleType.MATRIX
- })
- }
-}
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/AlbumDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/AlbumDetailAdapter.kt
index 1042780c0..eb1860bd2 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/AlbumDetailAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/AlbumDetailAdapter.kt
@@ -22,7 +22,6 @@ import androidx.core.view.isInvisible
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.coil.bindAlbumCover
import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
import org.oxycblt.auxio.databinding.ItemDetailBinding
import org.oxycblt.auxio.databinding.ItemDiscHeaderBinding
@@ -123,7 +122,7 @@ private class AlbumDetailViewHolder private constructor(private val binding: Ite
BindingViewHolder(binding.root) {
override fun bind(item: Album, listener: AlbumDetailAdapter.Listener) {
- binding.detailCover.bindAlbumCover(item)
+ binding.detailCover.bind(item)
binding.detailName.textSafe = item.resolveName(binding.context)
binding.detailSubhead.apply {
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt
index 1e895089e..07faf46cd 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt
@@ -21,8 +21,6 @@ import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.coil.bindAlbumCover
-import org.oxycblt.auxio.coil.bindArtistImage
import org.oxycblt.auxio.databinding.ItemDetailBinding
import org.oxycblt.auxio.databinding.ItemParentBinding
import org.oxycblt.auxio.databinding.ItemSongBinding
@@ -139,7 +137,7 @@ private class ArtistDetailViewHolder private constructor(private val binding: It
BindingViewHolder(binding.root) {
override fun bind(item: Artist, listener: DetailAdapter.Listener) {
- binding.detailCover.bindArtistImage(item)
+ binding.detailCover.bind(item)
binding.detailName.textSafe = item.resolveName(binding.context)
// Get the genre that corresponds to the most songs in this artist, which would be
@@ -181,7 +179,7 @@ private constructor(
private val binding: ItemParentBinding,
) : BindingViewHolder(binding.root), Highlightable {
override fun bind(item: Album, listener: MenuItemListener) {
- binding.parentImage.bindAlbumCover(item)
+ binding.parentImage.bind(item)
binding.parentName.textSafe = item.resolveName(binding.context)
binding.parentInfo.textSafe =
if (item.year != null) {
@@ -226,7 +224,7 @@ private constructor(
private val binding: ItemSongBinding,
) : BindingViewHolder(binding.root), Highlightable {
override fun bind(item: Song, listener: MenuItemListener) {
- binding.songAlbumCover.bindAlbumCover(item)
+ binding.songAlbumCover.bind(item)
binding.songName.textSafe = item.resolveName(binding.context)
binding.songInfo.textSafe = item.album.resolveName(binding.context)
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt
index f9000854d..dc5e7ae4d 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt
@@ -21,8 +21,6 @@ import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.coil.bindAlbumCover
-import org.oxycblt.auxio.coil.bindGenreImage
import org.oxycblt.auxio.databinding.ItemDetailBinding
import org.oxycblt.auxio.databinding.ItemSongBinding
import org.oxycblt.auxio.music.Genre
@@ -114,7 +112,7 @@ class GenreDetailAdapter(listener: Listener) :
private class GenreDetailViewHolder private constructor(private val binding: ItemDetailBinding) :
BindingViewHolder(binding.root) {
override fun bind(item: Genre, listener: DetailAdapter.Listener) {
- binding.detailCover.bindGenreImage(item)
+ binding.detailCover.bind(item)
binding.detailName.textSafe = item.resolveName(binding.context)
binding.detailSubhead.textSafe =
binding.context.getPluralSafe(R.plurals.fmt_song_count, item.songs.size)
@@ -146,7 +144,7 @@ private class GenreDetailViewHolder private constructor(private val binding: Ite
class GenreSongViewHolder private constructor(private val binding: ItemSongBinding) :
BindingViewHolder(binding.root), Highlightable {
override fun bind(item: Song, listener: MenuItemListener) {
- binding.songAlbumCover.bindAlbumCover(item)
+ binding.songAlbumCover.bind(item)
binding.songName.textSafe = item.resolveName(binding.context)
binding.songInfo.textSafe = item.resolveIndividualArtistName(binding.context)
binding.root.apply {
diff --git a/app/src/main/java/org/oxycblt/auxio/coil/BaseFetcher.kt b/app/src/main/java/org/oxycblt/auxio/image/BaseFetcher.kt
similarity index 99%
rename from app/src/main/java/org/oxycblt/auxio/coil/BaseFetcher.kt
rename to app/src/main/java/org/oxycblt/auxio/image/BaseFetcher.kt
index 7370e59de..d7e465fc2 100644
--- a/app/src/main/java/org/oxycblt/auxio/coil/BaseFetcher.kt
+++ b/app/src/main/java/org/oxycblt/auxio/image/BaseFetcher.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.coil
+package org.oxycblt.auxio.image
import android.content.Context
import android.graphics.Bitmap
diff --git a/app/src/main/java/org/oxycblt/auxio/coil/BitmapProvider.kt b/app/src/main/java/org/oxycblt/auxio/image/BitmapProvider.kt
similarity index 98%
rename from app/src/main/java/org/oxycblt/auxio/coil/BitmapProvider.kt
rename to app/src/main/java/org/oxycblt/auxio/image/BitmapProvider.kt
index ec6b3fd04..52b794a74 100644
--- a/app/src/main/java/org/oxycblt/auxio/coil/BitmapProvider.kt
+++ b/app/src/main/java/org/oxycblt/auxio/image/BitmapProvider.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.coil
+package org.oxycblt.auxio.image
import android.content.Context
import android.graphics.Bitmap
diff --git a/app/src/main/java/org/oxycblt/auxio/coil/Components.kt b/app/src/main/java/org/oxycblt/auxio/image/Components.kt
similarity index 99%
rename from app/src/main/java/org/oxycblt/auxio/coil/Components.kt
rename to app/src/main/java/org/oxycblt/auxio/image/Components.kt
index d2c2e0da7..8d5e5613a 100644
--- a/app/src/main/java/org/oxycblt/auxio/coil/Components.kt
+++ b/app/src/main/java/org/oxycblt/auxio/image/Components.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.coil
+package org.oxycblt.auxio.image
import android.content.Context
import coil.ImageLoader
diff --git a/app/src/main/java/org/oxycblt/auxio/coil/CrossfadeFactory.kt b/app/src/main/java/org/oxycblt/auxio/image/CrossfadeFactory.kt
similarity index 98%
rename from app/src/main/java/org/oxycblt/auxio/coil/CrossfadeFactory.kt
rename to app/src/main/java/org/oxycblt/auxio/image/CrossfadeFactory.kt
index a5b1e730c..6ba95cf93 100644
--- a/app/src/main/java/org/oxycblt/auxio/coil/CrossfadeFactory.kt
+++ b/app/src/main/java/org/oxycblt/auxio/image/CrossfadeFactory.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.coil
+package org.oxycblt.auxio.image
import coil.decode.DataSource
import coil.drawable.CrossfadeDrawable
diff --git a/app/src/main/java/org/oxycblt/auxio/coil/SquareFrameTransform.kt b/app/src/main/java/org/oxycblt/auxio/image/SquareFrameTransform.kt
similarity index 98%
rename from app/src/main/java/org/oxycblt/auxio/coil/SquareFrameTransform.kt
rename to app/src/main/java/org/oxycblt/auxio/image/SquareFrameTransform.kt
index 6895cc657..f81fd962f 100644
--- a/app/src/main/java/org/oxycblt/auxio/coil/SquareFrameTransform.kt
+++ b/app/src/main/java/org/oxycblt/auxio/image/SquareFrameTransform.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.coil
+package org.oxycblt.auxio.image
import android.graphics.Bitmap
import coil.size.Size
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarFragment.kt
index de58a4cc3..3de34434d 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarFragment.kt
@@ -25,7 +25,6 @@ import androidx.core.view.updatePadding
import androidx.fragment.app.activityViewModels
import com.google.android.material.color.MaterialColors
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.coil.bindAlbumCover
import org.oxycblt.auxio.databinding.FragmentPlaybackBarBinding
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.ui.MainNavigationAction
@@ -104,7 +103,7 @@ class PlaybackBarFragment : ViewBindingFragment() {
if (song != null) {
val context = requireContext()
val binding = requireBinding()
- binding.playbackCover.bindAlbumCover(song)
+ binding.playbackCover.bind(song)
binding.playbackSong.textSafe = song.resolveName(context)
binding.playbackInfo.textSafe = song.resolveIndividualArtistName(context)
binding.playbackProgressBar.max = song.durationSecs.toInt()
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt
index d49a7f62c..fe2442370 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt
@@ -28,7 +28,6 @@ import com.google.android.material.color.MaterialColors
import com.google.android.material.slider.Slider
import kotlin.math.max
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.coil.bindAlbumCover
import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song
@@ -176,7 +175,7 @@ class PlaybackPanelFragment :
val binding = requireBinding()
val context = requireContext()
- binding.playbackCover.bindAlbumCover(song)
+ binding.playbackCover.bind(song)
binding.playbackSong.textSafe = song.resolveName(context)
binding.playbackArtist.textSafe = song.resolveIndividualArtistName(context)
binding.playbackAlbum.textSafe = song.album.resolveName(context)
@@ -186,7 +185,7 @@ class PlaybackPanelFragment :
binding.playbackDuration.textSafe = seconds.formatDuration(false)
binding.playbackSeekBar.apply {
isEnabled = seconds > 0L
- valueToSafe = max(seconds, 1L).toFloat()
+ valueTo = max(seconds, 1L).toFloat()
}
}
@@ -200,7 +199,7 @@ class PlaybackPanelFragment :
// around.
val binding = requireBinding()
if (!binding.playbackPosition.isActivated) {
- binding.playbackSeekBar.valueSafe = position.toFloat()
+ binding.playbackSeekBar.value = position.toFloat()
binding.playbackPosition.textSafe = position.formatDuration(true)
}
}
@@ -219,26 +218,4 @@ class PlaybackPanelFragment :
private fun updateShuffled(isShuffled: Boolean) {
requireBinding().playbackShuffle.isActivated = isShuffled
}
-
- private var Slider.valueSafe: Float
- get() = value
- set(v) {
- value =
- if (v > valueTo) {
- valueTo
- } else {
- v
- }
- }
-
- private var Slider.valueToSafe: Float
- get() = valueTo
- set(v) {
- valueTo =
- if (value > v) {
- value
- } else {
- v
- }
- }
}
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt
index 3f22551fb..3f1d8738d 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt
@@ -28,7 +28,6 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.shape.MaterialShapeDrawable
import org.oxycblt.auxio.IntegerTable
-import org.oxycblt.auxio.coil.bindAlbumCover
import org.oxycblt.auxio.databinding.ItemQueueSongBinding
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.ui.BackingData
@@ -71,7 +70,7 @@ private constructor(
@SuppressLint("ClickableViewAccessibility")
override fun bind(item: Song, listener: QueueItemListener) {
- binding.songAlbumCover.bindAlbumCover(item)
+ binding.songAlbumCover.bind(item)
binding.songName.textSafe = item.resolveName(binding.context)
binding.songInfo.textSafe = item.resolveIndividualArtistName(binding.context)
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt
index b261391c9..a3a6098d6 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt
@@ -25,7 +25,7 @@ import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import com.google.android.exoplayer2.Player
-import org.oxycblt.auxio.coil.BitmapProvider
+import org.oxycblt.auxio.image.BitmapProvider
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.PlaybackStateManager
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/NotificationComponent.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/NotificationComponent.kt
index d75f8a8ac..15b9d16a4 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/system/NotificationComponent.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/system/NotificationComponent.kt
@@ -30,7 +30,7 @@ import androidx.media.app.NotificationCompat.MediaStyle
import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.coil.BitmapProvider
+import org.oxycblt.auxio.image.BitmapProvider
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.RepeatMode
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt
index 7e13e07fe..5237729ef 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt
@@ -19,7 +19,7 @@ package org.oxycblt.auxio.settings
import android.content.SharedPreferences
import androidx.core.content.edit
-import org.oxycblt.auxio.accent.Accent
+import org.oxycblt.auxio.ui.accent.Accent
// A couple of utils for migrating from old settings values to the new formats
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
index cde1cd4f8..3dc82fe04 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
@@ -30,12 +30,12 @@ import androidx.preference.children
import androidx.recyclerview.widget.RecyclerView
import coil.Coil
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.accent.AccentCustomizeDialog
import org.oxycblt.auxio.home.tabs.TabCustomizeDialog
import org.oxycblt.auxio.music.excluded.ExcludedDialog
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.settings.pref.IntListPreference
import org.oxycblt.auxio.settings.pref.IntListPreferenceDialog
+import org.oxycblt.auxio.ui.accent.AccentCustomizeDialog
import org.oxycblt.auxio.util.hardRestart
import org.oxycblt.auxio.util.isNight
import org.oxycblt.auxio.util.logD
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt
index cab931176..99815520d 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt
@@ -22,12 +22,12 @@ import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit
import androidx.preference.PreferenceManager
-import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.home.tabs.Tab
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.playback.system.ReplayGainMode
import org.oxycblt.auxio.ui.DisplayMode
import org.oxycblt.auxio.ui.Sort
+import org.oxycblt.auxio.ui.accent.Accent
import org.oxycblt.auxio.util.unlikelyToBeNull
/**
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/pref/IntListPreference.kt b/app/src/main/java/org/oxycblt/auxio/settings/pref/IntListPreference.kt
index 8c1bc7b9e..778c5689a 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/pref/IntListPreference.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/pref/IntListPreference.kt
@@ -32,10 +32,11 @@ constructor(
defStyleAttr: Int = androidx.preference.R.attr.dialogPreferenceStyle,
defStyleRes: Int = 0
) : DialogPreference(context, attrs, defStyleAttr, defStyleRes) {
- // Reflect into Preference to get the (normally inaccessible) default value.
val entries: Array
val values: IntArray
private var currentValue: Int? = null
+
+ // Reflect into Preference to get the (normally inaccessible) default value.
private val defValue: Int
get() = defValueField.get(this) as Int
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/pref/M3SwitchPreference.kt b/app/src/main/java/org/oxycblt/auxio/settings/pref/M3SwitchPreference.kt
index d8170d753..49544b217 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/pref/M3SwitchPreference.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/pref/M3SwitchPreference.kt
@@ -29,7 +29,7 @@ import org.oxycblt.auxio.util.getDrawableSafe
/**
* A [SwitchPreferenceCompat] that emulates the M3 switches until the design team actually bothers
- * to add them to MDC.
+ * to add them to MDC TODO: Remove this once MaterialSwitch is stabilized.
*/
class M3SwitchPreference
@JvmOverloads
@@ -45,7 +45,6 @@ constructor(
// Lollipop cannot into ColorStateList, disable this feature on that version
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val switch = holder.findViewById(androidx.preference.R.id.switchWidget)
-
if (switch is SwitchCompat) {
switch.apply {
trackDrawable = context.getDrawableSafe(R.drawable.ui_m3_switch_track)
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt b/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt
index 77cd80115..df81099f8 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt
@@ -54,11 +54,9 @@ fun Fragment.newMenu(anchor: View, data: Item, flag: Int = ActionMenu.FLAG_NONE)
* @throws IllegalStateException When there is no menu for this specific datatype/flag
* @author OxygenCobalt
*
- * TODO: Stop scrolling when a menu is open
- *
* TODO: Prevent duplicate menus from showing up
*
- * TODO: Maybe replace this with a bottom sheet?
+ * TODO: Add multi-select
*/
class ActionMenu(
activity: AppCompatActivity,
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/NavigationViewModel.kt b/app/src/main/java/org/oxycblt/auxio/ui/NavigationViewModel.kt
index 45a6ae47a..c42b62fb8 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/NavigationViewModel.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/NavigationViewModel.kt
@@ -22,7 +22,10 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.oxycblt.auxio.music.Music
-/** A ViewModel that handles complicated navigation situations. */
+/**
+ * A ViewModel that handles complicated navigation situations.
+ * @author OxygenCobalt
+ */
class NavigationViewModel : ViewModel() {
private val _mainNavigationAction = MutableLiveData()
/** Flag for main fragment navigation. Intended for MainFragment use only. */
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/RecyclerFramework.kt b/app/src/main/java/org/oxycblt/auxio/ui/RecyclerFramework.kt
index 5f1c15531..1c097ea7c 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/RecyclerFramework.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/RecyclerFramework.kt
@@ -28,6 +28,7 @@ import androidx.recyclerview.widget.RecyclerView
/**
* An adapter for one viewholder tied to one type of data. All functionality is derived from the
* overridden values.
+ * @author OxygenCobalt
*/
abstract class MonoAdapter>(private val listener: L) :
RecyclerView.Adapter() {
@@ -51,6 +52,7 @@ private typealias AnyCreator = BindingViewHolder.Creator(private val listener: L) :
RecyclerView.Adapter() {
@@ -99,6 +101,7 @@ abstract class MultiAdapter(private val listener: L) :
* A variation of [RecyclerView.ViewHolder] that enables ViewBinding. This is be used to provide a
* universal surface for binding data to a ViewHolder, and can be used with [MonoAdapter] to get an
* entire adapter implementation for free.
+ * @author OxygenCobalt
*/
abstract class BindingViewHolder(root: View) : RecyclerView.ViewHolder(root) {
abstract fun bind(item: T, listener: L)
@@ -159,6 +162,7 @@ abstract class BackingData {
/**
* A list-backed [BackingData] that is modified using adapter primitives. Useful in cases where
* [AsyncBackingData] is not preferable due to bugs involving diffing.
+ * @author OxygenCobalt
*/
class PrimitiveBackingData(private val adapter: RecyclerView.Adapter<*>) : BackingData() {
private var _currentList = mutableListOf()
@@ -184,6 +188,7 @@ class PrimitiveBackingData(private val adapter: RecyclerView.Adapter<*>) : Ba
* A list-backed [BackingData] that is modified with [AsyncListDiffer]. This is useful in cases
* where data updates are rapid-fire and unpredictable, and where the benefits of asynchronously
* diffing the adapter outweigh the shortcomings.
+ * @author OxygenCobalt
*/
class AsyncBackingData(
adapter: RecyclerView.Adapter<*>,
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackButton.kt b/app/src/main/java/org/oxycblt/auxio/ui/StyledImageButton.kt
similarity index 77%
rename from app/src/main/java/org/oxycblt/auxio/playback/PlaybackButton.kt
rename to app/src/main/java/org/oxycblt/auxio/ui/StyledImageButton.kt
index ad44e5ca3..21b43815c 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackButton.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/StyledImageButton.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.playback
+package org.oxycblt.auxio.ui
import android.content.Context
import android.graphics.Canvas
@@ -29,33 +29,33 @@ import org.oxycblt.auxio.util.getDimenSizeSafe
import org.oxycblt.auxio.util.getDrawableSafe
/**
- * An [AppCompatImageButton] designed for the buttons used in the playback display.
+ * An [AppCompatImageButton] that applies many of the stylistic choices that Auxio uses regarding
+ * buttons.
*
- * Auxio's playback buttons have never followed the typical 24dp icon size that all other UI
- * elements do, mostly because those icons just look bad at that size with all the gobs of
- * whitespace surrounding them. So, this view resizes the icons to a fixed 32dp in a way that
- * doesn't require a whole new icon set.
- *
- * This view also enables use of an "indicator", which is a dot that can denote when a button is
- * active. This is useful for the shuffle/repeat buttons, as at times highlighting them is not
- * enough to differentiate them.
+ * More specifically, this class add two features:
+ * - Specification of the icon size. This is to accommodate the playback buttons, which tend to be
+ * larger as by default the playback icons look terrible with the gobs of whitespace everywhere.
+ * - Addition of an indicator, which is a dot that can denote when a button is active. This is
+ * also useful for the playback buttons, as at times highlighting them is not enough to
+ * differentiate them.
+ * @author OxygenCobalt
*/
-class PlaybackButton
+class StyledImageButton
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
AppCompatImageButton(context, attrs, defStyleAttr) {
- private val iconSize = context.getDimenSizeSafe(R.dimen.size_playback_icon)
- private val centerMatrix = Matrix()
- private val matrixSrc = RectF()
- private val matrixDst = RectF()
-
- private val indicatorDrawable = context.getDrawableSafe(R.drawable.ui_indicator)
+ private val iconSize: Int
private var hasIndicator = false
set(value) {
field = value
invalidate()
}
+ private val centerMatrix = Matrix()
+ private val matrixSrc = RectF()
+ private val matrixDst = RectF()
+ private val indicatorDrawable = context.getDrawableSafe(R.drawable.ui_indicator)
+
init {
val size = context.getDimenSizeSafe(R.dimen.size_btn_small)
minimumWidth = size
@@ -63,14 +63,22 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
scaleType = ScaleType.MATRIX
setBackgroundResource(R.drawable.ui_large_unbounded_ripple)
- val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.PlaybackButton)
- hasIndicator = styledAttrs.getBoolean(R.styleable.PlaybackButton_hasIndicator, false)
+ val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StyledImageButton)
+ iconSize =
+ styledAttrs
+ .getDimension(
+ R.styleable.StyledImageButton_iconSize,
+ context.getDimenSizeSafe(R.dimen.size_icon_normal).toFloat())
+ .toInt()
+ hasIndicator = styledAttrs.getBoolean(R.styleable.StyledImageButton_hasIndicator, false)
styledAttrs.recycle()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+ // TODO: Scale this drawable based on available space after padding
+
imageMatrix =
centerMatrix.apply {
reset()
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt b/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt
new file mode 100644
index 000000000..e9b69c005
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2022 Auxio Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.oxycblt.auxio.ui
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.ColorFilter
+import android.graphics.PixelFormat
+import android.graphics.drawable.Drawable
+import android.util.AttributeSet
+import androidx.annotation.AttrRes
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import androidx.appcompat.widget.AppCompatImageView
+import coil.dispose
+import coil.load
+import com.google.android.material.shape.MaterialShapeDrawable
+import org.oxycblt.auxio.R
+import org.oxycblt.auxio.image.SquareFrameTransform
+import org.oxycblt.auxio.music.Album
+import org.oxycblt.auxio.music.Artist
+import org.oxycblt.auxio.music.Genre
+import org.oxycblt.auxio.music.Music
+import org.oxycblt.auxio.music.Song
+import org.oxycblt.auxio.settings.SettingsManager
+import org.oxycblt.auxio.util.getColorStateListSafe
+import org.oxycblt.auxio.util.getDrawableSafe
+
+/**
+ * An [AppCompatImageView] that applies many of the stylistic choices that Auxio uses regarding
+ * images.
+ *
+ * Default behavior includes the addition of a tonal background, automatic sizing of icons to
+ * half of the view size, and corner radius application depending on user preference.
+ * @author OxygenCobalt
+ */
+class StyledImageView
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
+ AppCompatImageView(context, attrs, defStyleAttr) {
+ private var cornerRadius = 0f
+
+ init {
+ val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StyledImageView)
+
+ cornerRadius = styledAttrs.getDimension(R.styleable.StyledImageView_cornerRadius, 0f)
+
+ styledAttrs.recycle()
+
+ clipToOutline = true
+ background =
+ MaterialShapeDrawable().apply {
+ fillColor = context.getColorStateListSafe(R.color.sel_cover_bg)
+ }
+
+ // If we have a pre-set drawable, ensure that it's half-size.
+ val drawable = drawable
+ if (drawable != null) {
+ setImageDrawable(HalfSizeDrawable(drawable))
+ }
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+
+ // 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.
+ if (!isInEditMode) {
+ val settingsManager = SettingsManager.getInstance()
+ if (settingsManager.roundCovers) {
+ (background as MaterialShapeDrawable).setCornerSize(cornerRadius)
+ }
+ }
+ }
+
+ /** Bind the album cover for a [song]. */
+ fun bind(song: Song) = load(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)
+
+ /** Bind the image for an [artist] */
+ fun bind(artist: Artist) = load(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)
+
+ private fun load(music: T, @DrawableRes error: Int, @StringRes desc: Int) {
+ dispose()
+ load(music) {
+ error(HalfSizeDrawable(context, error))
+ transformations(SquareFrameTransform.INSTANCE)
+ }
+ contentDescription = context.getString(desc, music.resolveName(context))
+ }
+
+ private class HalfSizeDrawable(private val src: Drawable) : Drawable() {
+ constructor(context: Context, @DrawableRes res: Int) : this(context.getDrawableSafe(res))
+
+ override fun draw(canvas: Canvas) {
+ src.bounds.set(canvas.clipBounds)
+ val adjustWidth = src.bounds.width() / 4
+ val adjustHeight = src.bounds.height() / 4
+ src.bounds.set(
+ adjustWidth,
+ adjustHeight,
+ src.bounds.width() - adjustWidth,
+ src.bounds.height() - adjustHeight)
+ src.draw(canvas)
+ }
+
+ override fun setAlpha(alpha: Int) {
+ src.alpha = alpha
+ }
+
+ override fun setColorFilter(colorFilter: ColorFilter?) {
+ src.colorFilter = colorFilter
+ }
+
+ override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
+ }
+}
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ViewBindingDialogFragment.kt b/app/src/main/java/org/oxycblt/auxio/ui/ViewBindingDialogFragment.kt
index d54e3a53d..c5aff2564 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/ViewBindingDialogFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/ViewBindingDialogFragment.kt
@@ -28,6 +28,10 @@ import androidx.viewbinding.ViewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.oxycblt.auxio.util.logD
+/**
+ * A dialog fragment enabling ViewBinding inflation and usage across the dialog fragment lifecycle.
+ * @author OxygenCobalt
+ */
abstract class ViewBindingDialogFragment : DialogFragment() {
private var _binding: T? = null
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ViewBindingFragment.kt b/app/src/main/java/org/oxycblt/auxio/ui/ViewBindingFragment.kt
index d2e932c3f..4497abac4 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/ViewBindingFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/ViewBindingFragment.kt
@@ -25,7 +25,10 @@ import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import org.oxycblt.auxio.util.logD
-/** A fragment enabling ViewBinding inflation and usage across the fragment lifecycle. */
+/**
+ * A fragment enabling ViewBinding inflation and usage across the fragment lifecycle.
+ * @author OxygenCobalt
+ */
abstract class ViewBindingFragment : Fragment() {
private var _binding: T? = null
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ViewHolders.kt b/app/src/main/java/org/oxycblt/auxio/ui/ViewHolders.kt
index c93272e33..45fdbd121 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/ViewHolders.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/ViewHolders.kt
@@ -20,9 +20,6 @@ package org.oxycblt.auxio.ui
import android.content.Context
import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.coil.bindAlbumCover
-import org.oxycblt.auxio.coil.bindArtistImage
-import org.oxycblt.auxio.coil.bindGenreImage
import org.oxycblt.auxio.databinding.ItemHeaderBinding
import org.oxycblt.auxio.databinding.ItemParentBinding
import org.oxycblt.auxio.databinding.ItemSongBinding
@@ -35,11 +32,14 @@ import org.oxycblt.auxio.util.getPluralSafe
import org.oxycblt.auxio.util.inflater
import org.oxycblt.auxio.util.textSafe
-/** The shared ViewHolder for a [Song]. */
+/**
+ * The shared ViewHolder for a [Song].
+ * @author OxygenCobalt
+ */
class SongViewHolder private constructor(private val binding: ItemSongBinding) :
BindingViewHolder(binding.root) {
override fun bind(item: Song, listener: MenuItemListener) {
- binding.songAlbumCover.bindAlbumCover(item)
+ binding.songAlbumCover.bind(item)
binding.songName.textSafe = item.resolveName(binding.context)
binding.songInfo.textSafe = item.resolveIndividualArtistName(binding.context)
binding.root.apply {
@@ -70,14 +70,17 @@ class SongViewHolder private constructor(private val binding: ItemSongBinding) :
}
}
-/** The Shared ViewHolder for a [Album]. */
+/**
+ * The Shared ViewHolder for a [Album].
+ * @author OxygenCobalt
+ */
class AlbumViewHolder
private constructor(
private val binding: ItemParentBinding,
) : BindingViewHolder(binding.root) {
override fun bind(item: Album, listener: MenuItemListener) {
- binding.parentImage.bindAlbumCover(item)
+ binding.parentImage.bind(item)
binding.parentName.textSafe = item.resolveName(binding.context)
binding.parentInfo.textSafe = item.artist.resolveName(binding.context)
binding.root.apply {
@@ -108,12 +111,15 @@ private constructor(
}
}
-/** The Shared ViewHolder for a [Artist]. */
+/**
+ * The Shared ViewHolder for a [Artist].
+ * @author OxygenCobalt
+ */
class ArtistViewHolder private constructor(private val binding: ItemParentBinding) :
BindingViewHolder(binding.root) {
override fun bind(item: Artist, listener: MenuItemListener) {
- binding.parentImage.bindArtistImage(item)
+ binding.parentImage.bind(item)
binding.parentName.textSafe = item.resolveName(binding.context)
binding.parentInfo.textSafe =
binding.context.getString(
@@ -149,14 +155,17 @@ class ArtistViewHolder private constructor(private val binding: ItemParentBindin
}
}
-/** The Shared ViewHolder for a [Genre]. */
+/**
+ * The Shared ViewHolder for a [Genre].
+ * @author OxygenCobalt
+ */
class GenreViewHolder
private constructor(
private val binding: ItemParentBinding,
) : BindingViewHolder(binding.root) {
override fun bind(item: Genre, listener: MenuItemListener) {
- binding.parentImage.bindGenreImage(item)
+ binding.parentImage.bind(item)
binding.parentName.textSafe = item.resolveName(binding.context)
binding.parentInfo.textSafe =
binding.context.getPluralSafe(R.plurals.fmt_song_count, item.songs.size)
@@ -187,7 +196,10 @@ private constructor(
}
}
-/** The Shared ViewHolder for a [Header]. */
+/**
+ * The Shared ViewHolder for a [Header].
+ * @author OxygenCobalt
+ */
class NewHeaderViewHolder private constructor(private val binding: ItemHeaderBinding) :
BindingViewHolder(binding.root) {
diff --git a/app/src/main/java/org/oxycblt/auxio/accent/Accent.kt b/app/src/main/java/org/oxycblt/auxio/ui/accent/Accent.kt
similarity index 99%
rename from app/src/main/java/org/oxycblt/auxio/accent/Accent.kt
rename to app/src/main/java/org/oxycblt/auxio/ui/accent/Accent.kt
index 20ecf8149..3938b8745 100644
--- a/app/src/main/java/org/oxycblt/auxio/accent/Accent.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/accent/Accent.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.accent
+package org.oxycblt.auxio.ui.accent
import org.oxycblt.auxio.R
diff --git a/app/src/main/java/org/oxycblt/auxio/accent/AccentAdapter.kt b/app/src/main/java/org/oxycblt/auxio/ui/accent/AccentAdapter.kt
similarity index 99%
rename from app/src/main/java/org/oxycblt/auxio/accent/AccentAdapter.kt
rename to app/src/main/java/org/oxycblt/auxio/ui/accent/AccentAdapter.kt
index 0ae1b8ef3..0243fd0c9 100644
--- a/app/src/main/java/org/oxycblt/auxio/accent/AccentAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/accent/AccentAdapter.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.accent
+package org.oxycblt.auxio.ui.accent
import android.content.Context
import androidx.appcompat.widget.TooltipCompat
diff --git a/app/src/main/java/org/oxycblt/auxio/accent/AccentCustomizeDialog.kt b/app/src/main/java/org/oxycblt/auxio/ui/accent/AccentCustomizeDialog.kt
similarity index 98%
rename from app/src/main/java/org/oxycblt/auxio/accent/AccentCustomizeDialog.kt
rename to app/src/main/java/org/oxycblt/auxio/ui/accent/AccentCustomizeDialog.kt
index a384b580c..db945a60b 100644
--- a/app/src/main/java/org/oxycblt/auxio/accent/AccentCustomizeDialog.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/accent/AccentCustomizeDialog.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.accent
+package org.oxycblt.auxio.ui.accent
import android.os.Bundle
import android.view.LayoutInflater
diff --git a/app/src/main/java/org/oxycblt/auxio/accent/AccentGridLayoutManager.kt b/app/src/main/java/org/oxycblt/auxio/ui/accent/AccentGridLayoutManager.kt
similarity index 98%
rename from app/src/main/java/org/oxycblt/auxio/accent/AccentGridLayoutManager.kt
rename to app/src/main/java/org/oxycblt/auxio/ui/accent/AccentGridLayoutManager.kt
index ad9c91db0..2cb7b8cab 100644
--- a/app/src/main/java/org/oxycblt/auxio/accent/AccentGridLayoutManager.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/accent/AccentGridLayoutManager.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.accent
+package org.oxycblt.auxio.ui.accent
import android.content.Context
import android.util.AttributeSet
diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt
index fc4b916a7..bf18449fc 100644
--- a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt
+++ b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt
@@ -26,8 +26,6 @@ import org.oxycblt.auxio.playback.system.PlaybackService
import org.oxycblt.auxio.util.newBroadcastIntent
import org.oxycblt.auxio.util.newMainIntent
-// TODO: Still need to change the default cover here
-
/**
* The default widget is displayed whenever there is no music playing. It just shows the message "No
* music playing".
@@ -109,7 +107,7 @@ private fun RemoteViews.applyCover(
R.id.widget_cover,
context.getString(R.string.desc_album_cover, state.song.album.resolveName(context)))
} else {
- setImageViewResource(R.id.widget_cover, R.drawable.ic_widget_album)
+ setImageViewResource(R.id.widget_cover, R.drawable.ic_remote_default_cover)
setContentDescription(R.id.widget_cover, context.getString(R.string.desc_no_cover))
}
diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt
index 5fd73c216..81be297fa 100644
--- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt
+++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt
@@ -24,8 +24,8 @@ import coil.request.ImageRequest
import coil.size.Size
import coil.transform.RoundedCornersTransformation
import kotlin.math.min
-import org.oxycblt.auxio.coil.BitmapProvider
-import org.oxycblt.auxio.coil.SquareFrameTransform
+import org.oxycblt.auxio.image.BitmapProvider
+import org.oxycblt.auxio.image.SquareFrameTransform
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.PlaybackStateManager
@@ -87,7 +87,7 @@ class WidgetComponent(private val context: Context) :
val metrics = context.resources.displayMetrics
// Use RoundedCornersTransformation. This is because our hack to get a 1:1
- // aspect ratio on widget ImageViews doesn't actually result in a square
+ // aspect ratio on widget ImageViews doesn't actually result in a square
// ImageView, so clipToOutline won't work.
builder
.transformations(
diff --git a/app/src/main/res/drawable/ic_widget_album.xml b/app/src/main/res/drawable/ic_remote_default_cover.xml
similarity index 83%
rename from app/src/main/res/drawable/ic_widget_album.xml
rename to app/src/main/res/drawable/ic_remote_default_cover.xml
index 41ae54295..e29fbfca0 100644
--- a/app/src/main/res/drawable/ic_widget_album.xml
+++ b/app/src/main/res/drawable/ic_remote_default_cover.xml
@@ -6,11 +6,11 @@
android:viewportHeight="24">
-
-
-
-
-
-
-
-
-
-
@@ -152,18 +154,19 @@
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
tools:src="@drawable/ic_pause" />
-
-
-
-
-
@@ -141,18 +143,19 @@
app:layout_constraintStart_toStartOf="@+id/playback_seek_bar"
tools:src="@drawable/ic_pause" />
-
-
-
-
+ tools:icon="@drawable/ic_song" />
-
-
-
-
-
-
-
-
-
-
+ tools:icon="@drawable/ic_song" />
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_playback_panel.xml b/app/src/main/res/layout/fragment_playback_panel.xml
index 389574ac6..1d5f3ccf6 100644
--- a/app/src/main/res/layout/fragment_playback_panel.xml
+++ b/app/src/main/res/layout/fragment_playback_panel.xml
@@ -14,7 +14,7 @@
app:title="@string/lbl_playback"
tools:subtitle="@string/lbl_all_songs" />
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:src="@drawable/ic_remote_default_cover" />
-
+
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 28e7dd65b..baa70df53 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -21,7 +21,8 @@
8dp
16dp
- 32dp
+ 24dp
+ 32dp
16sp
18sp
diff --git a/app/src/main/res/values/styles_ui.xml b/app/src/main/res/values/styles_ui.xml
index b5d836d1f..b1f588657 100644
--- a/app/src/main/res/values/styles_ui.xml
+++ b/app/src/main/res/values/styles_ui.xml
@@ -174,7 +174,7 @@
-->
- normal
- @dimen/size_btn_large
- - @dimen/size_playback_icon
+ - @dimen/size_icon_large
- 0dp
- 0dp