Further streamline coil usage

Simplify how coil is used even further.
This commit is contained in:
OxygenCobalt 2021-02-16 09:27:41 -07:00
parent c41c3be4c5
commit 1d8aeb16c2
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
6 changed files with 73 additions and 91 deletions

View file

@ -77,6 +77,7 @@ dependencies {
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
// Media
// TODO: Migrate to media2 once NewPipe implements it so I can figure out how it works
implementation 'androidx.media:media:1.2.1'
// Preferences

View file

@ -3,9 +3,11 @@ package org.oxycblt.auxio.coil
import android.content.Context
import android.graphics.Bitmap
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.core.graphics.drawable.toBitmap
import androidx.databinding.BindingAdapter
import coil.Coil
import coil.fetch.Fetcher
import coil.request.ImageRequest
import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.Album
@ -14,17 +16,77 @@ import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.settings.SettingsManager
private val ignoreCovers: Boolean get() = !SettingsManager.getInstance().showCovers
// --- BINDING ADAPTERS ---
/**
* Get a bitmap for a song. onDone will be called when the bitmap is loaded.
* Bind the album art for a [Song].
*/
@BindingAdapter("albumArt")
fun ImageView.bindAlbumArt(song: Song) {
load(song.album, R.drawable.ic_song, AlbumArtFetcher(context))
}
/**
* Bind the album art for an [Album].
*/
@BindingAdapter("albumArt")
fun ImageView.bindAlbumArt(album: Album) {
load(album, R.drawable.ic_album, AlbumArtFetcher(context))
}
/**
* Bind the image for an [Artist]
*/
@BindingAdapter("artistImage")
fun ImageView.bindArtistImage(artist: Artist) {
load(artist, R.drawable.ic_artist, MosaicFetcher(context))
}
/**
* Bind the image for a [Genre]
*/
@BindingAdapter("genreImage")
fun ImageView.bindGenreImage(genre: Genre) {
load(genre, R.drawable.ic_genre, MosaicFetcher(context))
}
/**
* Custom extension function similar to the stock coil load extensions, but allows for any type.
*/
inline fun <reified T : Any> ImageView.load(
data: T,
@DrawableRes error: Int,
fetcher: Fetcher<T>,
) {
val settingsManager = SettingsManager.getInstance()
if (!settingsManager.showCovers) {
setImageResource(error)
return
}
Coil.imageLoader(context).enqueue(
ImageRequest.Builder(context)
.target(this)
.data(data)
.fetcher(fetcher)
.error(error)
.build()
)
}
// --- OTHER FUNCTIONS ---
/**
* Get a bitmap for a [song]. [onDone] will be called when the bitmap is loaded.
* **This not meant for UIs, instead use the Binding Adapters.**
* @param context [Context] required
* @param song Song to load the cover for
* @param onDone What to do with the bitmap when the loading is finished. Bitmap will be null if loading failed/shouldn't occur.
*/
fun loadBitmap(context: Context, song: Song, onDone: (Bitmap?) -> Unit) {
if (ignoreCovers) {
val settingsManager = SettingsManager.getInstance()
if (!settingsManager.showCovers) {
onDone(null)
return
}
@ -39,86 +101,4 @@ fun loadBitmap(context: Context, song: Song, onDone: (Bitmap?) -> Unit) {
)
.build()
)
}
// --- BINDING ADAPTERS ---
/**
* Bind the album art for a [Song].
*/
@BindingAdapter("albumArt")
fun ImageView.bindAlbumArt(song: Song) {
if (ignoreCovers) {
setImageResource(R.drawable.ic_song)
return
}
Coil.imageLoader(context).enqueue(
ImageRequest.Builder(context)
.target(this)
.data(song.album)
.fetcher(AlbumArtFetcher(context))
.error(R.drawable.ic_song)
.build()
)
}
/**
* Bind the album art for an [Album].
*/
@BindingAdapter("albumArt")
fun ImageView.bindAlbumArt(album: Album) {
if (ignoreCovers) {
setImageResource(R.drawable.ic_album)
return
}
Coil.imageLoader(context).enqueue(
ImageRequest.Builder(context)
.target(this)
.data(album)
.fetcher(AlbumArtFetcher(context))
.error(R.drawable.ic_album)
.build()
)
}
/**
* Bind the image for an [Artist]
*/
@BindingAdapter("artistImage")
fun ImageView.bindArtistImage(artist: Artist) {
if (ignoreCovers) {
setImageResource(R.drawable.ic_artist)
return
}
Coil.imageLoader(context).enqueue(
ImageRequest.Builder(context)
.target(this)
.data(artist)
.fetcher(MosaicFetcher(context))
.error(R.drawable.ic_artist)
.build()
)
}
/**
* Bind the image for a [Genre]
*/
@BindingAdapter("genreImage")
fun ImageView.bindGenreImage(genre: Genre) {
if (ignoreCovers) {
setImageResource(R.drawable.ic_genre)
return
}
Coil.imageLoader(context).enqueue(
ImageRequest.Builder(context)
.target(this)
.data(genre)
.fetcher(MosaicFetcher(context))
.error(R.drawable.ic_genre)
.build()
)
}
}

View file

@ -73,7 +73,7 @@ class SettingsManager private constructor(context: Context) :
/**
* Whether to even loading embedded covers
* TODO: Make the UI result of this better
* TODO: Make the UI result of this better?
*/
val showCovers: Boolean
get() = sharedPrefs.getBoolean(Keys.KEY_SHOW_COVERS, true)

View file

@ -73,7 +73,7 @@
<string name="setting_audio">Audio</string>
<string name="setting_audio_focus">Audiofokus</string>
<string name="setting_audio_focus_desc">Pausieren wenn anderes Audio abspielt [Bsp. Alarme]</string>
<string name="setting_audio_focus_desc">Pausieren wenn anderes Audio abspielt [Bsp. Anrufe]</string>
<string name="setting_audio_plug_mgt">Kopfhöreranschluss</string>
<string name="setting_audio_plug_mgt_desc">Abspielen/Pausieren wenn der Kopfhöreranschluss ändern</string>

View file

@ -10,6 +10,7 @@
<string name="format_accent_summary" translatable="false">&lt;b>%1$s&lt;/b>:&#160;%2$s</string>
<!-- Debug Namespace | Debug labels -->
<!-- These are never shown to the user in normal use and therefore shouldnt be translated -->
<string name="debug_title" translatable="false">Debug</string>
<string name="debug_state_save" translatable="false">Save playback state</string>
<string name="debug_state_save_desc" translatable="false">Force save the current playback state</string>

View file

@ -73,7 +73,7 @@
<string name="setting_audio">Audio</string>
<string name="setting_audio_focus">Audio Focus</string>
<string name="setting_audio_focus_desc">Pause when other audio plays [ex. Alarms]</string>
<string name="setting_audio_focus_desc">Pause when other audio plays [ex. Calls]</string>
<string name="setting_audio_plug_mgt">Headset plug management</string>
<string name="setting_audio_plug_mgt_desc">Play/Pause when the headset connection changes</string>