coil: update image behavior

Update the image behavior for the following:
1. Use ic_album as the default image for songs and albums this just
looks beter in general.
2. Use a special default drawable for the widget so that it doesn't
look as strange.
3. Generally update the loading process throughout the app
This commit is contained in:
OxygenCobalt 2021-11-14 16:23:25 -07:00
parent d4fa52ee13
commit 1ea3ddb2e0
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
31 changed files with 158 additions and 112 deletions

View file

@ -57,6 +57,10 @@ class AlbumArtFetcher(private val context: Context) : Fetcher<Album> {
): FetchResult { ): FetchResult {
val settingsManager = SettingsManager.getInstance() val settingsManager = SettingsManager.getInstance()
if (!settingsManager.showCovers) {
error("Covers are disabled")
}
val result = if (settingsManager.useQualityCovers) { val result = if (settingsManager.useQualityCovers) {
fetchQualityCovers(data.songs[0]) fetchQualityCovers(data.songs[0])
} else { } else {

View file

@ -28,7 +28,6 @@ import coil.Coil
import coil.fetch.Fetcher import coil.fetch.Fetcher
import coil.request.ImageRequest import coil.request.ImageRequest
import coil.size.OriginalSize import coil.size.OriginalSize
import coil.transform.RoundedCornersTransformation
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Artist
@ -44,7 +43,7 @@ import org.oxycblt.auxio.settings.SettingsManager
*/ */
@BindingAdapter("albumArt") @BindingAdapter("albumArt")
fun ImageView.bindAlbumArt(song: Song?) { fun ImageView.bindAlbumArt(song: Song?) {
load(song?.album, R.drawable.ic_song, AlbumArtFetcher(context)) load(song?.album, R.drawable.ic_album, AlbumArtFetcher(context))
} }
/** /**
@ -69,13 +68,6 @@ fun ImageView.bindArtistImage(artist: Artist?) {
@BindingAdapter("genreImage") @BindingAdapter("genreImage")
fun ImageView.bindGenreImage(genre: Genre?) { fun ImageView.bindGenreImage(genre: Genre?) {
load(genre, R.drawable.ic_genre, MosaicFetcher(context)) load(genre, R.drawable.ic_genre, MosaicFetcher(context))
if (genre != null) {
contentDescription = context.getString(
R.string.desc_genre_image,
genre.resolvedName
)
}
} }
/** /**
@ -91,14 +83,7 @@ inline fun <reified T : BaseModel> ImageView.load(
@DrawableRes error: Int, @DrawableRes error: Int,
fetcher: Fetcher<T>, fetcher: Fetcher<T>,
) { ) {
val settingsManager = SettingsManager.getInstance() val disposable = Coil.imageLoader(context).enqueue(
if (!settingsManager.showCovers) {
setImageResource(error)
return
}
Coil.imageLoader(context).enqueue(
ImageRequest.Builder(context) ImageRequest.Builder(context)
.target(this) .target(this)
.data(data) .data(data)
@ -118,7 +103,6 @@ inline fun <reified T : BaseModel> ImageView.load(
fun loadBitmap( fun loadBitmap(
context: Context, context: Context,
song: Song, song: Song,
cornerRadius: Float = 0f,
onDone: (Bitmap?) -> Unit onDone: (Bitmap?) -> Unit
) { ) {
val settingsManager = SettingsManager.getInstance() val settingsManager = SettingsManager.getInstance()
@ -132,7 +116,6 @@ fun loadBitmap(
ImageRequest.Builder(context) ImageRequest.Builder(context)
.data(song.album) .data(song.album)
.fetcher(AlbumArtFetcher(context)) .fetcher(AlbumArtFetcher(context))
.transformations(RoundedCornersTransformation(cornerRadius))
.size(OriginalSize) .size(OriginalSize)
.target( .target(
onError = { onDone(null) }, onError = { onDone(null) },

View file

@ -31,7 +31,7 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentDetailBinding import org.oxycblt.auxio.databinding.FragmentDetailBinding
import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.SortMode import org.oxycblt.auxio.ui.SortMode
import org.oxycblt.auxio.ui.memberBinding import org.oxycblt.auxio.ui.memberBinding
@ -71,17 +71,17 @@ abstract class DetailFragment : Fragment() {
/** /**
* Shortcut method for doing setup of the detail toolbar. * Shortcut method for doing setup of the detail toolbar.
* @param music Music data to use as the toolbar title * @param data Parent data to use as the toolbar title
* @param menu Menu resource to use * @param menu Menu resource to use
* @param onMenuClick (Optional) a click listener for that menu * @param onMenuClick (Optional) a click listener for that menu
*/ */
protected fun setupToolbar( protected fun setupToolbar(
music: Music, data: MusicParent,
@MenuRes menu: Int = -1, @MenuRes menu: Int = -1,
onMenuClick: ((itemId: Int) -> Boolean)? = null onMenuClick: ((itemId: Int) -> Boolean)? = null
) { ) {
binding.detailToolbar.apply { binding.detailToolbar.apply {
title = music.name title = data.resolvedName
if (menu != -1) { if (menu != -1) {
inflateMenu(menu) inflateMenu(menu)

View file

@ -52,7 +52,7 @@ import kotlin.math.sqrt
class FastScrollPopupDrawable(context: Context) : Drawable() { class FastScrollPopupDrawable(context: Context) : Drawable() {
private val paint: Paint = Paint().apply { private val paint: Paint = Paint().apply {
isAntiAlias = true isAntiAlias = true
color = R.attr.colorControlActivated.resolveAttr(context) color = R.attr.colorSecondary.resolveAttr(context)
style = Paint.Style.FILL style = Paint.Style.FILL
} }
@ -86,7 +86,7 @@ class FastScrollPopupDrawable(context: Context) : Drawable() {
else -> if (!path.isConvex) { else -> if (!path.isConvex) {
// The outline path must be convex before Q, but we may run into floating point // The outline path must be convex before Q, but we may run into floating point
// error caused by calculations involving sqrt(2) or OEM implementation differences, // errors caused by calculations involving sqrt(2) or OEM implementation differences,
// so in this case we just omit the shadow instead of crashing. // so in this case we just omit the shadow instead of crashing.
super.getOutline(outline) super.getOutline(outline)
} }

View file

@ -46,7 +46,7 @@ class PlaybackNotification private constructor(
mediaToken: MediaSessionCompat.Token mediaToken: MediaSessionCompat.Token
) : NotificationCompat.Builder(context, CHANNEL_ID) { ) : NotificationCompat.Builder(context, CHANNEL_ID) {
init { init {
setSmallIcon(R.drawable.ic_notif) setSmallIcon(R.drawable.ic_auxio)
setCategory(NotificationCompat.CATEGORY_SERVICE) setCategory(NotificationCompat.CATEGORY_SERVICE)
setShowWhen(false) setShowWhen(false)
setSilent(true) setSilent(true)

View file

@ -36,7 +36,6 @@ import java.text.Normalizer
/** /**
* The [ViewModel] for the search functionality * The [ViewModel] for the search functionality
* TODO: Implement fuzzy search?
* @author OxygenCobalt * @author OxygenCobalt
*/ */
class SearchViewModel : ViewModel(), MusicStore.MusicCallback { class SearchViewModel : ViewModel(), MusicStore.MusicCallback {

View file

@ -24,6 +24,7 @@ import androidx.annotation.LayoutRes
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.playback.state.LoopMode import org.oxycblt.auxio.playback.state.LoopMode
import org.oxycblt.auxio.playback.system.PlaybackService import org.oxycblt.auxio.playback.system.PlaybackService
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.newBroadcastIntent import org.oxycblt.auxio.util.newBroadcastIntent
import org.oxycblt.auxio.util.newMainIntent import org.oxycblt.auxio.util.newMainIntent
@ -41,7 +42,9 @@ private fun createViews(
return views return views
} }
private fun RemoteViews.applyMeta(state: WidgetState): RemoteViews { private fun RemoteViews.applyMeta(context: Context, state: WidgetState): RemoteViews {
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.album.artist.resolvedName)
@ -55,20 +58,15 @@ private fun RemoteViews.applyCover(context: Context, state: WidgetState): Remote
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.album.name)
) )
} else { } else {
setImageViewResource(R.id.widget_cover, R.drawable.ic_song) logD("WHY ARE YOU NOT WORKING")
setImageViewResource(R.id.widget_cover, R.drawable.ic_widget_album)
setContentDescription(R.id.widget_cover, context.getString(R.string.desc_no_cover)) setContentDescription(R.id.widget_cover, context.getString(R.string.desc_no_cover))
} }
return this return this
} }
private fun RemoteViews.applyControls(context: Context, state: WidgetState): RemoteViews {
setOnClickPendingIntent(
R.id.widget_skip_prev,
context.newBroadcastIntent(
PlaybackService.ACTION_SKIP_PREV
)
)
private fun RemoteViews.applyPlayControls(context: Context, state: WidgetState): RemoteViews {
setOnClickPendingIntent( setOnClickPendingIntent(
R.id.widget_play_pause, R.id.widget_play_pause,
context.newBroadcastIntent( context.newBroadcastIntent(
@ -76,13 +74,6 @@ private fun RemoteViews.applyControls(context: Context, state: WidgetState): Rem
) )
) )
setOnClickPendingIntent(
R.id.widget_skip_next,
context.newBroadcastIntent(
PlaybackService.ACTION_SKIP_NEXT
)
)
setImageViewResource( setImageViewResource(
R.id.widget_play_pause, R.id.widget_play_pause,
if (state.isPlaying) { if (state.isPlaying) {
@ -95,6 +86,26 @@ private fun RemoteViews.applyControls(context: Context, state: WidgetState): Rem
return this return this
} }
private fun RemoteViews.applyControls(context: Context, state: WidgetState): RemoteViews {
applyPlayControls(context, state)
setOnClickPendingIntent(
R.id.widget_skip_prev,
context.newBroadcastIntent(
PlaybackService.ACTION_SKIP_PREV
)
)
setOnClickPendingIntent(
R.id.widget_skip_next,
context.newBroadcastIntent(
PlaybackService.ACTION_SKIP_NEXT
)
)
return this
}
private fun RemoteViews.applyFullControls(context: Context, state: WidgetState): RemoteViews { private fun RemoteViews.applyFullControls(context: Context, state: WidgetState): RemoteViews {
applyControls(context, state) applyControls(context, state)
@ -133,41 +144,59 @@ private fun RemoteViews.applyFullControls(context: Context, state: WidgetState):
return this return this
} }
/**
* The default widget is displayed whenever there is no music playing. It just shows the
* message "No music playing".
*/
fun createDefaultWidget(context: Context): RemoteViews { fun createDefaultWidget(context: Context): RemoteViews {
return createViews(context, R.layout.widget_default) return createViews(context, R.layout.widget_default)
} }
/**
* The tiny widget is for an edge-case situation where a 2xN widget happens to be smaller than
* 100dp. It just shows the cover, titles, and a button.
*/
fun createTinyWidget(context: Context, state: WidgetState): RemoteViews { fun createTinyWidget(context: Context, state: WidgetState): RemoteViews {
return createViews(context, R.layout.widget_tiny) return createViews(context, R.layout.widget_tiny)
.applyMeta(state) .applyMeta(context, state)
.applyCover(context, state) .applyPlayControls(context, state)
.applyControls(context, state)
}
fun createWideWidget(context: Context, state: WidgetState): RemoteViews {
return createViews(context, R.layout.widget_wide)
.applyMeta(state)
.applyCover(context, state)
.applyFullControls(context, state)
} }
/**
* The small widget is for 2x2 widgets and just shows the cover art and playback controls.
* This is generally because a Medium widget is too large for this widget size and a text-only
* widget is too small for this widget size.
*/
fun createSmallWidget(context: Context, state: WidgetState): RemoteViews { fun createSmallWidget(context: Context, state: WidgetState): RemoteViews {
return createViews(context, R.layout.widget_small) return createViews(context, R.layout.widget_small)
.applyMeta(state)
.applyCover(context, state) .applyCover(context, state)
.applyControls(context, state) .applyControls(context, state)
} }
/**
* The medium widget is for 2x3 widgets and shows the cover art, title/artist, and three
* controls. This is the default widget configuration.
*/
fun createMediumWidget(context: Context, state: WidgetState): RemoteViews { fun createMediumWidget(context: Context, state: WidgetState): RemoteViews {
return createViews(context, R.layout.widget_medium) return createViews(context, R.layout.widget_medium)
.applyMeta(state) .applyMeta(context, state)
.applyCover(context, state)
.applyControls(context, state) .applyControls(context, state)
} }
fun createLargeWidget(context: Context, state: WidgetState): RemoteViews { /**
return createViews(context, R.layout.widget_large) * The wide widget is for Nx2 widgets and is like the small widget but with more controls.
.applyMeta(state) */
fun createWideWidget(context: Context, state: WidgetState): RemoteViews {
return createViews(context, R.layout.widget_wide)
.applyCover(context, state) .applyCover(context, state)
.applyFullControls(context, state) .applyFullControls(context, state)
} }
/**
* The large widget is for 3x4 widgets and shows all metadata and controls.
*/
fun createLargeWidget(context: Context, state: WidgetState): RemoteViews {
return createViews(context, R.layout.widget_large)
.applyMeta(context, state)
.applyFullControls(context, state)
}

View file

@ -32,27 +32,23 @@ import android.widget.RemoteViews
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import coil.Coil import coil.Coil
import coil.request.ImageRequest import coil.request.ImageRequest
import coil.size.OriginalSize
import coil.transform.RoundedCornersTransformation import coil.transform.RoundedCornersTransformation
import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.R
import org.oxycblt.auxio.coil.AlbumArtFetcher import org.oxycblt.auxio.coil.AlbumArtFetcher
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.PlaybackStateManager import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.util.isLandscape import org.oxycblt.auxio.util.isLandscape
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import kotlin.math.min
/** /**
* Auxio's one and only appwidget. This widget follows a more unorthodox approach, effectively * Auxio's one and only appwidget. This widget follows a more unorthodox approach, effectively
* packing what could be considered multiple widgets into a single responsive widget. All types * packing what could be considered multiple widgets into a single responsive widget.
* are listed below:
* *
* - Large widgets will show cover art and all controls * This widget is also able to backport it's responsive behavior to android versions below 12,
* - Tall and thin widgets will show cover art and three controls * albeit with some issues, such as UI jittering and a layout not being picked when the orientation
* - Wide or small widgets will display a "Stylistic" view with controls and the cover art * changes. This is tolerable.
* - Tiny widgets [e.g landscape mode] will show cover art, text, and a play/pause control.
*
* There are some minor problems with this implementation [notably UI jittering when the widget
* picks a new layout below Android 12], but this is tolerable. It may be improved in the future.
* *
* For more specific details about these sub-widgets, see Forms.kt. * For more specific details about these sub-widgets, see Forms.kt.
*/ */
@ -92,28 +88,37 @@ class WidgetProvider : AppWidgetProvider() {
} }
private fun loadWidgetBitmap(context: Context, song: Song, onDone: (Bitmap?) -> Unit) { private fun loadWidgetBitmap(context: Context, song: Song, onDone: (Bitmap?) -> Unit) {
val builder = ImageRequest.Builder(context) // Load our image so that it takes up the phone screen. This allows
// us to get stable rounded corners for every single widget image. This probably
// sacrifices quality in some way, but it's really the only good option.
// Hey google, maybe allow us to use our own views in widgets next time. That would
// be nice.
val metrics = context.resources.displayMetrics
val imageSize = min(metrics.widthPixels, metrics.heightPixels)
val coverRequest = ImageRequest.Builder(context)
.data(song.album) .data(song.album)
.fetcher(AlbumArtFetcher(context)) .fetcher(AlbumArtFetcher(context))
.size(OriginalSize) .size(imageSize)
.target(
onError = { onDone(null) },
onSuccess = { onDone(it.toBitmap()) }
)
// If we are on Android 12 or higher, round out the album cover so that the widget is // If we are on Android 12 or higher, round out the album cover so that the widget is
// cohesive. I really don't like this, but whatever. // cohesive. I really don't like this, but whatever.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
builder.transformations( val transform = RoundedCornersTransformation(
RoundedCornersTransformation( context.resources.getDimensionPixelSize(
context.resources.getDimensionPixelSize( android.R.dimen.system_app_widget_inner_radius
android.R.dimen.system_app_widget_inner_radius ).toFloat()
).toFloat()
)
) )
coverRequest.transformations(transform)
} }
Coil.imageLoader(context).enqueue(builder.build()) coverRequest.target(
onError = { onDone(null) },
onSuccess = { onDone(it.toBitmap()) }
)
Coil.imageLoader(context).enqueue(coverRequest.build())
} }
/* /*
@ -127,7 +132,7 @@ class WidgetProvider : AppWidgetProvider() {
) )
} }
// / --- OVERRIDES --- // --- OVERRIDES ---
override fun onUpdate( override fun onUpdate(
context: Context, context: Context,
@ -147,7 +152,6 @@ class WidgetProvider : AppWidgetProvider() {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions) super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
// We can't resize the widget until we can generate the views, so request an update // We can't resize the widget until we can generate the views, so request an update
// from PlaybackService. // from PlaybackService.
requestUpdate(context) requestUpdate(context)

View file

@ -1,7 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal" android:tint="?attr/colorPrimary"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24"> android:viewportHeight="24">
<path <path

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!--
Special album icon where the center is filled with the surface color.
This is used for widgets specifically, as it creates a contiguous surface
that looks nicer on the small widgets while also lining up with the preview.
This does cause issues when the theme is changed on older android versions, but
this is tolerable.
-->
<path
android:fillColor="?attr/colorPrimary"
android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-0.55 0-1 0.45-1 1s0.45 1 1 1 1-0.45 1-1-0.45-1-1-1z" />
<path
android:fillColor="?attr/colorSurface"
android:pathData="M 11.999988,7.5000052 C 10.26837,7.4769007 8.5915309,8.560755 7.896993,10.146219 c -0.7453054,1.607465 -0.4180795,3.637951 0.8068934,4.921183 1.166041,1.284666 3.1054606,1.767719 4.7412966,1.196892 1.694811,-0.550604 2.957738,-2.193714 3.045894,-3.974751 0.132222,-1.713727 -0.824064,-3.4451124 -2.343934,-4.2469378 -0.655277,-0.3575862 -1.401101,-0.5431647 -2.147155,-0.5426 z m 0,3.5000448 c 0.727249,-0.03179 1.254295,0.852995 0.879019,1.475902 -0.300918,0.612861 -1.237867,0.707058 -1.649512,0.15916 -0.489216,-0.537264 -0.143543,-1.499245 0.56999,-1.614362 0.06589,-0.01409 0.133207,-0.02062 0.200503,-0.0207 z" />
</vector>

View file

@ -45,7 +45,7 @@
app:layout_constraintDimensionRatio="1" app:layout_constraintDimensionRatio="1"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar" app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<!-- TextView is wrapped in a container so that marquee doesn't break --> <!-- TextView is wrapped in a container so that marquee doesn't break -->

View file

@ -47,7 +47,7 @@
app:layout_constraintDimensionRatio="1" app:layout_constraintDimensionRatio="1"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar" app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<!-- TextView is wrapped in a container so that marquee doesn't break --> <!-- TextView is wrapped in a container so that marquee doesn't break -->

View file

@ -46,7 +46,7 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar" app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<TextView <TextView
android:id="@+id/playback_song" android:id="@+id/playback_song"

View file

@ -165,12 +165,12 @@
style="@style/Widget.Auxio.TextView.Icon" style="@style/Widget.Auxio.TextView.Icon"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Theme.Auxio.Neutral" app:drawableStartCompat="@drawable/ic_album"
app:drawableStartCompat="@drawable/ic_song"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/about_licenses" app:layout_constraintTop_toBottomOf="@+id/about_licenses"
tools:text="Songs Loaded: 1616" /> tools:text="Songs Loaded: 1616"
app:drawableTint="?attr/colorControlNormal" />
<TextView <TextView
android:id="@+id/about_author" android:id="@+id/about_author"
@ -178,7 +178,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/lbl_author" android:text="@string/lbl_author"
android:theme="@style/Theme.Auxio.Neutral" app:drawableTint="?attr/colorControlNormal"
app:drawableStartCompat="@drawable/ic_artist" app:drawableStartCompat="@drawable/ic_artist"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View file

@ -45,7 +45,7 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar" app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<TextView <TextView
android:id="@+id/playback_song" android:id="@+id/playback_song"

View file

@ -21,7 +21,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<TextView <TextView
android:id="@+id/song_name" android:id="@+id/song_name"

View file

@ -21,7 +21,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<TextView <TextView
android:id="@+id/song_name" android:id="@+id/song_name"

View file

@ -47,7 +47,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<TextView <TextView
android:id="@+id/song_name" android:id="@+id/song_name"

View file

@ -22,7 +22,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" tools:ignore="ContentDescription"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<TextView <TextView
android:id="@+id/song_name" android:id="@+id/song_name"

View file

@ -26,7 +26,7 @@
app:layout_constraintBottom_toTopOf="@+id/playback_progress_bar" app:layout_constraintBottom_toTopOf="@+id/playback_progress_bar"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_song" /> tools:src="@drawable/ic_album" />
<TextView <TextView
android:id="@+id/playback_song" android:id="@+id/playback_song"

View file

@ -14,7 +14,8 @@
android:alpha="0.275" android:alpha="0.275"
android:contentDescription="@string/desc_no_cover" android:contentDescription="@string/desc_no_cover"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@drawable/ic_song" /> android:src="@drawable/ic_auxio"
android:tint="?attr/colorPrimary" />
<android.widget.TextView <android.widget.TextView
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -43,7 +43,7 @@
android:layout_alignTop="@id/widget_aspect_ratio" android:layout_alignTop="@id/widget_aspect_ratio"
android:layout_alignEnd="@id/widget_aspect_ratio" android:layout_alignEnd="@id/widget_aspect_ratio"
android:layout_alignBottom="@id/widget_aspect_ratio" android:layout_alignBottom="@id/widget_aspect_ratio"
android:src="@drawable/ic_song" android:src="@drawable/ic_widget_album"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<android.widget.LinearLayout <android.widget.LinearLayout

View file

@ -43,7 +43,7 @@
android:layout_alignTop="@id/widget_aspect_ratio" android:layout_alignTop="@id/widget_aspect_ratio"
android:layout_alignEnd="@id/widget_aspect_ratio" android:layout_alignEnd="@id/widget_aspect_ratio"
android:layout_alignBottom="@id/widget_aspect_ratio" android:layout_alignBottom="@id/widget_aspect_ratio"
android:src="@drawable/ic_song" android:src="@drawable/ic_widget_album"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<android.widget.LinearLayout <android.widget.LinearLayout

View file

@ -45,7 +45,7 @@
android:layout_alignTop="@id/widget_aspect_ratio" android:layout_alignTop="@id/widget_aspect_ratio"
android:layout_alignEnd="@id/widget_aspect_ratio" android:layout_alignEnd="@id/widget_aspect_ratio"
android:layout_alignBottom="@id/widget_aspect_ratio" android:layout_alignBottom="@id/widget_aspect_ratio"
android:src="@drawable/ic_song" android:src="@drawable/ic_widget_album"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<android.widget.LinearLayout <android.widget.LinearLayout
@ -53,7 +53,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:padding="@dimen/spacing_small" android:paddingTop="@dimen/spacing_small"
android:paddingBottom="@dimen/spacing_small"
android:paddingStart="@dimen/spacing_medium"
android:paddingEnd="@dimen/spacing_medium"
android:elevation="@dimen/elevation_normal" android:elevation="@dimen/elevation_normal"
android:orientation="horizontal" android:orientation="horizontal"
android:background="@drawable/ui_widget_panel" android:background="@drawable/ui_widget_panel"

View file

@ -26,7 +26,7 @@
android:layout_marginEnd="@dimen/spacing_medium" android:layout_marginEnd="@dimen/spacing_medium"
android:contentDescription="@string/desc_no_cover" android:contentDescription="@string/desc_no_cover"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@drawable/ic_song" /> android:src="@drawable/ic_widget_album" />
<android.widget.LinearLayout <android.widget.LinearLayout
android:layout_width="0dp" android:layout_width="0dp"

View file

@ -45,7 +45,7 @@
android:layout_alignTop="@id/widget_aspect_ratio" android:layout_alignTop="@id/widget_aspect_ratio"
android:layout_alignEnd="@id/widget_aspect_ratio" android:layout_alignEnd="@id/widget_aspect_ratio"
android:layout_alignBottom="@id/widget_aspect_ratio" android:layout_alignBottom="@id/widget_aspect_ratio"
android:src="@drawable/ic_song" android:src="@drawable/ic_widget_album"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<android.widget.LinearLayout <android.widget.LinearLayout
@ -57,7 +57,10 @@
android:background="@drawable/ui_widget_panel" android:background="@drawable/ui_widget_panel"
android:elevation="@dimen/elevation_normal" android:elevation="@dimen/elevation_normal"
android:orientation="horizontal" android:orientation="horizontal"
android:padding="@dimen/spacing_small"> android:paddingTop="@dimen/spacing_small"
android:paddingBottom="@dimen/spacing_small"
android:paddingStart="@dimen/spacing_medium"
android:paddingEnd="@dimen/spacing_medium">
<android.widget.ImageButton <android.widget.ImageButton
android:id="@+id/widget_loop" android:id="@+id/widget_loop"

View file

@ -5,6 +5,5 @@
android:title="@string/lbl_queue_add" /> android:title="@string/lbl_queue_add" />
<item <item
android:id="@+id/action_go_album" android:id="@+id/action_go_album"
android:icon="@drawable/ic_album"
android:title="@string/lbl_go_album" /> android:title="@string/lbl_go_album" />
</menu> </menu>

View file

@ -5,10 +5,8 @@
android:title="@string/lbl_queue_add" /> android:title="@string/lbl_queue_add" />
<item <item
android:id="@+id/action_go_artist" android:id="@+id/action_go_artist"
android:icon="@drawable/ic_artist"
android:title="@string/lbl_go_artist" /> android:title="@string/lbl_go_artist" />
<item <item
android:id="@+id/action_go_album" android:id="@+id/action_go_album"
android:icon="@drawable/ic_album"
android:title="@string/lbl_go_album" /> android:title="@string/lbl_go_album" />
</menu> </menu>

View file

@ -83,5 +83,7 @@
<item name="colorSecondary">?android:attr/colorAccent</item> <item name="colorSecondary">?android:attr/colorAccent</item>
<item name="colorControlNormal">?android:attr/colorControlNormal</item> <item name="colorControlNormal">?android:attr/colorControlNormal</item>
<item name="colorControlHighlight">?android:attr/colorControlHighlight</item> <item name="colorControlHighlight">?android:attr/colorControlHighlight</item>
<item name="colorSurfaceInverse">@color/m3_sys_color_dynamic_dark_inverse_surface</item>
<item name="colorOnSurfaceInverse">@color/m3_sys_color_dynamic_dark_inverse_on_surface</item>
</style> </style>
</resources> </resources>

View file

@ -83,5 +83,7 @@
<item name="colorSecondary">?android:attr/colorAccent</item> <item name="colorSecondary">?android:attr/colorAccent</item>
<item name="colorControlNormal">?android:attr/colorControlNormal</item> <item name="colorControlNormal">?android:attr/colorControlNormal</item>
<item name="colorControlHighlight">?android:attr/colorControlHighlight</item> <item name="colorControlHighlight">?android:attr/colorControlHighlight</item>
<item name="colorSurfaceInverse">@color/m3_sys_color_dynamic_light_inverse_surface</item>
<item name="colorOnSurfaceInverse">@color/m3_sys_color_dynamic_light_inverse_on_surface</item>
</style> </style>
</resources> </resources>

View file

@ -7,9 +7,7 @@
<item name="android:statusBarColor">@android:color/black</item> <item name="android:statusBarColor">@android:color/black</item>
</style> </style>
<!-- Android 12 configuration --> <!-- Android 12 configuration -->
<style name="Theme.Auxio.V31" parent="Theme.Auxio.V27"> <style name="Theme.Auxio.V31" parent="Theme.Auxio.V27" />
</style>
<!-- Base theme --> <!-- Base theme -->
<style name="Theme.Auxio.App" parent="Theme.Auxio.V31"> <style name="Theme.Auxio.App" parent="Theme.Auxio.V31">