converted to Glide 4

main
h4h13 2018-12-13 02:29:07 +05:30
parent 96aa205405
commit f4c56c8484
45 changed files with 853 additions and 945 deletions

View File

@ -59,11 +59,6 @@ class App : MultiDexApplication() {
//startActivity(intent); //startActivity(intent);
} }
override fun onLowMemory() {
super.onLowMemory()
Glide.with(this).onLowMemory()
}
override fun onTerminate() { override fun onTerminate() {
super.onTerminate() super.onTerminate()
billingProcessor.release() billingProcessor.release()

View File

@ -13,14 +13,15 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class AppWidgetBig : BaseAppWidget() { class AppWidgetBig : BaseAppWidget() {
private var target: Target<Bitmap>? = null // for cancellation private var target: Target<Bitmap>? = null // for cancellation
@ -91,19 +92,19 @@ class AppWidgetBig : BaseAppWidget() {
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target!!) GlideApp.with(appContext).clear(target)
} }
target = SongGlideRequest.Builder.from(Glide.with(appContext), song) target = GlideApp.with(appContext)
.checkIgnoreMediaStore(appContext) .asBitmap()
.asBitmap().build() .load(RetroGlideExtension.getSongModel(song))
.into(object : SimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) { .transition(RetroGlideExtension.getDefaultTransition())
override fun onResourceReady(resource: Bitmap, .songOptions(song)
glideAnimation: GlideAnimation<in Bitmap>) { .into(object : RetroSimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
update(resource) update(resource)
} }
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null) update(null)
} }
@ -151,7 +152,7 @@ class AppWidgetBig : BaseAppWidget() {
companion object { companion object {
const val NAME: String = "app_widget_big" const val NAME: String = "app_widget_big"
private var mInstance: AppWidgetBig? = null private var mInstance: AppWidgetBig? = null

View File

@ -13,15 +13,15 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class AppWidgetCard : BaseAppWidget() { class AppWidgetCard : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -36,15 +36,9 @@ class AppWidgetCard : BaseAppWidget() {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp,
MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
linkButtons(context, appWidgetView) linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView) pushUpdate(context, appWidgetIds, appWidgetView)
@ -92,26 +86,26 @@ class AppWidgetCard : BaseAppWidget() {
if (cardRadius == 0f) { if (cardRadius == 0f) {
cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius) cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius)
} }
val appContext = service.applicationContext
// Load the album cover async and push the update on completion // Load the album cover async and push the update on completion
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target!!) GlideApp.with(appContext).clear(target)
} }
target = SongGlideRequest.Builder.from(Glide.with(service), song) GlideApp.with(appContext)
.checkIgnoreMediaStore(service) .asBitmapPalette()
.generatePalette(service).build() .load(RetroGlideExtension.getSongModel(song))
.centerCrop() .transition(RetroGlideExtension.getDefaultTransition())
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { .songOptions(song)
override fun onResourceReady(resource: BitmapPaletteWrapper, .into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) { override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette update(resource.bitmap, palette.getVibrantColor(palette
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true)))) .getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
} }
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true)) update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
} }

View File

@ -13,15 +13,16 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class AppWidgetClassic : BaseAppWidget() { class AppWidgetClassic : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -77,21 +78,21 @@ class AppWidgetClassic : BaseAppWidget() {
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target!!) GlideApp.with(appContext).clear(target)
} }
target = SongGlideRequest.Builder.from(Glide.with(appContext), song) GlideApp.with(appContext)
.checkIgnoreMediaStore(appContext) .asBitmapPalette()
.generatePalette(service).build() .load(RetroGlideExtension.getSongModel(song))
.centerCrop() .transition(RetroGlideExtension.getDefaultTransition())
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { .songOptions(song)
override fun onResourceReady(resource: BitmapPaletteWrapper, .into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) { override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true)))) update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))))
} }
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed( errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true)) update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true))
} }

View File

@ -13,15 +13,15 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class AppWidgetSmall : BaseAppWidget() { class AppWidgetSmall : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -82,22 +82,22 @@ class AppWidgetSmall : BaseAppWidget() {
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target!!) GlideApp.with(appContext).clear(target);
} }
target = SongGlideRequest.Builder.from(Glide.with(appContext), song) target = GlideApp.with(appContext)
.checkIgnoreMediaStore(appContext) .asBitmapPalette()
.generatePalette(service).build() .load(RetroGlideExtension.getSongModel(song))
.centerCrop() .transition(RetroGlideExtension.getDefaultTransition())
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { .songOptions(song)
override fun onResourceReady(resource: BitmapPaletteWrapper, .into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) { override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette update(resource.bitmap, palette.getVibrantColor(palette
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true)))) .getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))))
} }
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true)) update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true))
} }
@ -153,7 +153,7 @@ class AppWidgetSmall : BaseAppWidget() {
companion object { companion object {
const val NAME:String = "app_widget_small" const val NAME: String = "app_widget_small"
private var mInstance: AppWidgetSmall? = null private var mInstance: AppWidgetSmall? = null
private var imageSize = 0 private var imageSize = 0

View File

@ -1,112 +0,0 @@
package code.name.monkey.retromusic.glide
import android.content.Context
import android.graphics.Bitmap
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.artistimage.ArtistImage
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.util.ArtistSignatureUtil
import code.name.monkey.retromusic.util.CustomArtistImageUtil
import com.bumptech.glide.*
import com.bumptech.glide.load.Key
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.target.Target
object ArtistGlideRequest {
private const val DEFAULT_ANIMATION = android.R.anim.fade_in
private val DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.ALL
private const val DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art
private fun createBaseRequest(requestManager: RequestManager, artist: Artist, noCustomImage: Boolean, forceDownload: Boolean): DrawableTypeRequest<*> {
val hasCustomImage = CustomArtistImageUtil.getInstance(App.instance)
.hasCustomArtistImage(artist)
return if (noCustomImage || !hasCustomImage) {
requestManager.load(ArtistImage(artist.name, forceDownload))
} else {
requestManager.load(CustomArtistImageUtil.getFile(artist))
}
}
private fun createSignature(artist: Artist): Key {
return ArtistSignatureUtil.getInstance(App.instance)
.getArtistSignature(artist.name)
}
class Builder private constructor(internal val requestManager: RequestManager, internal val artist: Artist) {
internal var noCustomImage: Boolean = false
internal var forceDownload: Boolean = false
fun generatePalette(context: Context): PaletteBuilder {
return PaletteBuilder(this, context)
}
fun asBitmap(): BitmapBuilder {
return BitmapBuilder(this)
}
fun noCustomImage(noCustomImage: Boolean): Builder {
this.noCustomImage = noCustomImage
return this
}
fun forceDownload(forceDownload: Boolean): Builder {
this.forceDownload = forceDownload
return this
}
fun build(): DrawableRequestBuilder<out Any> {
return createBaseRequest(requestManager, artist, noCustomImage, forceDownload)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(artist))
}
companion object {
fun from(requestManager: RequestManager, artist: Artist): Builder {
return Builder(requestManager, artist)
}
}
}
class BitmapBuilder internal constructor(private val builder: Builder) {
fun build(): BitmapRequestBuilder<*, Bitmap> {
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage,
builder.forceDownload)
.asBitmap()
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(builder.artist))
}
}
class PaletteBuilder internal constructor(private val builder: Builder, internal val context: Context) {
fun build(): BitmapRequestBuilder<*, BitmapPaletteWrapper> {
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage,
builder.forceDownload)
.asBitmap()
.transcode(BitmapPaletteTranscoder(context), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(builder.artist))
}
}
}

View File

@ -1,37 +1,30 @@
package code.name.monkey.retromusic.glide package code.name.monkey.retromusic.glide
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint import android.graphics.Paint
import android.os.Build import android.os.Build
import android.renderscript.Allocation import android.renderscript.*
import android.renderscript.Element
import android.renderscript.RSRuntimeException
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import androidx.annotation.FloatRange import androidx.annotation.FloatRange
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.helper.StackBlur
import code.name.monkey.retromusic.util.ImageUtil
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import code.name.monkey.retromusic.helper.StackBlur import java.security.MessageDigest
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.util.ImageUtil
class BlurTransformation : BitmapTransformation { class BlurTransformation : BitmapTransformation {
private var context: Context? = null private var context: Context? = null
private var blurRadius: Float = 0.toFloat() private var blurRadius: Float = 0.toFloat()
private var sampling: Int = 0 private var sampling: Int = 0
private constructor(builder: Builder) : super(builder.context) { private constructor(builder: Builder) : super() {
init(builder) init(builder)
} }
private constructor(builder: Builder, bitmapPool: BitmapPool) : super(bitmapPool) { private constructor(builder: Builder, bitmapPool: BitmapPool) : super() {
init(builder) init(builder)
} }
@ -41,7 +34,6 @@ class BlurTransformation : BitmapTransformation {
this.sampling = builder.sampling this.sampling = builder.sampling
} }
override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? { override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? {
val sampling: Int val sampling: Int
if (this.sampling == 0) { if (this.sampling == 0) {
@ -93,14 +85,22 @@ class BlurTransformation : BitmapTransformation {
return StackBlur.blur(out, blurRadius) return StackBlur.blur(out, blurRadius)
} }
override fun getId(): String { override fun equals(o: Any?): Boolean {
return "BlurTransformation(radius=$blurRadius, sampling=$sampling)" return o is BlurTransformation
} }
class Builder(internal val context: Context) { override fun hashCode(): Int {
private var bitmapPool: BitmapPool? = null return ID.hashCode()
internal var blurRadius = DEFAULT_BLUR_RADIUS }
internal var sampling: Int = 0
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update("BlurTransformation(radius=$blurRadius, sampling=$sampling)".toByteArray(CHARSET))
}
class Builder(val context: Context) {
var bitmapPool: BitmapPool? = null
var blurRadius = DEFAULT_BLUR_RADIUS
var sampling: Int = 0
/** /**
* @param blurRadius The radius to use. Must be between 0 and 25. Default is 5. * @param blurRadius The radius to use. Must be between 0 and 25. Default is 5.
@ -137,6 +137,8 @@ class BlurTransformation : BitmapTransformation {
} }
companion object { companion object {
internal const val DEFAULT_BLUR_RADIUS = 5f
val DEFAULT_BLUR_RADIUS = 5f
private val ID = "com.poupa.vinylmusicplayer.glide.BlurTransformation"
} }
} }

View File

@ -0,0 +1,96 @@
package code.name.monkey.retromusic.glide;
import com.bumptech.glide.GenericTransitionOptions;
import com.bumptech.glide.Priority;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.annotation.GlideExtension;
import com.bumptech.glide.annotation.GlideOption;
import com.bumptech.glide.annotation.GlideType;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.signature.MediaStoreSignature;
import androidx.annotation.NonNull;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.ArtistSignatureUtil;
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
import code.name.monkey.retromusic.util.MusicUtil;
import code.name.monkey.retromusic.util.PreferenceUtil;
@GlideExtension
public final class RetroGlideExtension {
private RetroGlideExtension() {
}
@GlideType(BitmapPaletteWrapper.class)
public static void asBitmapPalette(RequestBuilder<BitmapPaletteWrapper> requestBuilder) {
}
@GlideOption
public static RequestOptions artistOptions(@NonNull RequestOptions requestOptions, Artist artist) {
return requestOptions
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.error(R.drawable.default_artist_art)
.placeholder(R.drawable.default_artist_art)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(artist));
}
@GlideOption
public static RequestOptions songOptions(@NonNull RequestOptions requestOptions, Song song) {
return requestOptions
.diskCacheStrategy(DiskCacheStrategy.NONE)
.error(R.drawable.default_album_art)
.placeholder(R.drawable.default_album_art)
.signature(createSignature(song));
}
public static Key createSignature(Artist artist) {
return ArtistSignatureUtil.getInstance().getArtistSignature(artist.getName());
}
public static Key createSignature(Song song) {
return new MediaStoreSignature("", song.getDateModified(), 0);
}
public static Object getArtistModel(Artist artist) {
return getArtistModel(artist, CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist), false);
}
public static Object getArtistModel(Artist artist, boolean forceDownload) {
return getArtistModel(artist, CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist), forceDownload);
}
public static Object getArtistModel(Artist artist, boolean hasCustomImage, boolean forceDownload) {
if (!hasCustomImage) {
return new ArtistImage(artist.getName(), forceDownload);
} else {
return CustomArtistImageUtil.getFile(artist);
}
}
public static Object getSongModel(Song song) {
return getSongModel(song, PreferenceUtil.getInstance().ignoreMediaStoreArtwork());
}
public static Object getSongModel(Song song, boolean ignoreMediaStore) {
if (ignoreMediaStore) {
return new AudioFileCover(song.getData());
} else {
return MusicUtil.getMediaStoreAlbumCoverUri(song.getAlbumId());
}
}
public static <TranscodeType> GenericTransitionOptions<TranscodeType> getDefaultTransition() {
return new GenericTransitionOptions<TranscodeType>().transition(android.R.anim.fade_in);
}
}

View File

@ -2,17 +2,14 @@ package code.name.monkey.retromusic.glide
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.widget.ImageView import android.widget.ImageView
import com.bumptech.glide.request.animation.GlideAnimation
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil.getColor import code.name.monkey.retromusic.util.RetroColorUtil.getColor
import code.name.monkey.retromusic.util.RetroColorUtil.getDominantColor import code.name.monkey.retromusic.util.RetroColorUtil.getDominantColor
import com.bumptech.glide.request.transition.Transition
abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) { abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) {
@ -23,13 +20,13 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
protected val albumArtistFooterColor: Int protected val albumArtistFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor) get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor)
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(errorDrawable)
onColorReady(defaultFooterColor) onColorReady(defaultFooterColor)
} }
override fun onResourceReady(resource: BitmapPaletteWrapper, override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) { glideAnimation: Transition<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation) super.onResourceReady(resource, glideAnimation)
val defaultColor = defaultFooterColor val defaultColor = defaultFooterColor

View File

@ -1,25 +1,29 @@
package code.name.monkey.retromusic.glide package code.name.monkey.retromusic.glide
import android.content.Context import android.content.Context
import android.graphics.Bitmap
import com.bumptech.glide.Glide
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.module.GlideModule
import code.name.monkey.retromusic.glide.artistimage.ArtistImage import code.name.monkey.retromusic.glide.artistimage.ArtistImage
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import com.bumptech.glide.Glide
import com.bumptech.glide.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule
import java.io.InputStream import java.io.InputStream
@GlideModule
class RetroMusicGlideModule : GlideModule { class RetroMusicGlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) { override fun registerComponents(context: Context, glide: Glide,
registry: Registry) {
registry.append(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory())
registry.append(ArtistImage::class.java, InputStream::class.java, ArtistImageLoader.Factory(context))
registry.register(Bitmap::class.java, BitmapPaletteWrapper::class.java, BitmapPaletteTranscoder())
} }
override fun registerComponents(context: Context, glide: Glide) { override fun isManifestParsingEnabled(): Boolean {
glide.register(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory()) return false
glide.register(ArtistImage::class.java, InputStream::class.java, ArtistImageLoader.Factory(context))
} }
} }

View File

@ -0,0 +1,64 @@
package code.name.monkey.retromusic.glide
import android.graphics.drawable.Drawable
import com.bumptech.glide.request.Request
import com.bumptech.glide.request.target.SizeReadyCallback
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
import com.bumptech.glide.util.Util
open class RetroSimpleTarget<T> @JvmOverloads constructor(private val width: Int = Target.SIZE_ORIGINAL, private val height: Int = Target.SIZE_ORIGINAL) : Target<T> {
private var request: Request? = null
override fun getRequest(): Request? {
return request
}
override fun setRequest(request: Request?) {
this.request = request
}
override fun onLoadStarted(placeholder: Drawable?) {
}
override fun onLoadFailed(errorDrawable: Drawable?) {
}
override fun onResourceReady(resource: T, transition: Transition<in T>?) {
}
override fun onLoadCleared(placeholder: Drawable?) {
}
override fun getSize(cb: SizeReadyCallback) {
if (!Util.isValidDimensions(width, height)) {
throw IllegalArgumentException(
"Width and height must both be > 0 or Target#SIZE_ORIGINAL, but given" + " width: "
+ width + " and height: " + height + ", either provide dimensions in the constructor"
+ " or call override()")
}
cb.onSizeReady(width, height)
}
override fun removeCallback(cb: SizeReadyCallback) {
}
override fun onStart() {
}
override fun onStop() {
}
override fun onDestroy() {
}
}

View File

@ -1,102 +0,0 @@
package code.name.monkey.retromusic.glide
import android.content.Context
import android.graphics.Bitmap
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.BitmapRequestBuilder
import com.bumptech.glide.DrawableRequestBuilder
import com.bumptech.glide.DrawableTypeRequest
import com.bumptech.glide.RequestManager
import com.bumptech.glide.load.Key
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.signature.MediaStoreSignature
object SongGlideRequest {
internal val DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.NONE
internal const val DEFAULT_ANIMATION = android.R.anim.fade_in
internal const val DEFAULT_ERROR_IMAGE = R.drawable.default_album_art
internal fun createBaseRequest(requestManager: RequestManager, song: Song,
ignoreMediaStore: Boolean): DrawableTypeRequest<*> {
return if (ignoreMediaStore) {
requestManager.load(AudioFileCover(song.data!!))
} else {
requestManager.loadFromMediaStore(MusicUtil.getMediaStoreAlbumCoverUri(song.albumId))
}
}
internal fun createSignature(song: Song): Key {
return MediaStoreSignature("", song.dateModified, 0)
}
class Builder private constructor(internal val requestManager: RequestManager, internal val song: Song) {
internal var ignoreMediaStore: Boolean = false
fun generatePalette(context: Context): PaletteBuilder {
return PaletteBuilder(this, context)
}
fun asBitmap(): BitmapBuilder {
return BitmapBuilder(this)
}
fun checkIgnoreMediaStore(context: Context): Builder {
return ignoreMediaStore(PreferenceUtil.getInstance().ignoreMediaStoreArtwork())
}
fun ignoreMediaStore(ignoreMediaStore: Boolean): Builder {
this.ignoreMediaStore = ignoreMediaStore
return this
}
fun build(): DrawableRequestBuilder<out Any> {
return createBaseRequest(requestManager, song, ignoreMediaStore)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.signature(createSignature(song))
}
companion object {
fun from(requestManager: RequestManager, song: Song): Builder {
return Builder(requestManager, song)
}
}
}
class BitmapBuilder internal constructor(private val builder: Builder) {
fun build(): BitmapRequestBuilder<*, Bitmap> {
return createBaseRequest(builder.requestManager, builder.song, builder.ignoreMediaStore)
.asBitmap()
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.signature(createSignature(builder.song))
}
}
class PaletteBuilder internal constructor(private val builder: Builder, internal val context: Context) {
fun build(): BitmapRequestBuilder<*, BitmapPaletteWrapper> {
return createBaseRequest(builder.requestManager, builder.song, builder.ignoreMediaStore)
.asBitmap()
.transcode(BitmapPaletteTranscoder(context), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.signature(createSignature(builder.song))
}
}
}

View File

@ -1,69 +1,98 @@
package code.name.monkey.retromusic.glide.artistimage package code.name.monkey.retromusic.glide.artistimage
import android.content.Context import android.content.Context
import android.text.TextUtils
import com.bumptech.glide.Priority
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.load.model.ModelLoader
import code.name.monkey.retromusic.rest.LastFMRestClient import code.name.monkey.retromusic.rest.LastFMRestClient
import code.name.monkey.retromusic.rest.model.LastFmArtist import code.name.monkey.retromusic.rest.model.LastFmArtist
import code.name.monkey.retromusic.util.LastFMUtil import code.name.monkey.retromusic.util.LastFMUtil
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Priority
import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.GlideUrl
import java.io.IOException import okhttp3.OkHttpClient
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import java.io.InputStream import java.io.InputStream
import retrofit2.Response
class ArtistImageFetcher(private val context: Context, private val lastFMRestClient: LastFMRestClient, private val okHttp: OkHttpClient, private val model: ArtistImage, width: Int, height: Int) : DataFetcher<InputStream> {
class ArtistImageFetcher(private val context: Context, private val lastFMRestClient: LastFMRestClient, private val model: ArtistImage, private val urlLoader: ModelLoader<GlideUrl, InputStream>, private val width: Int, private val height: Int) : DataFetcher<InputStream> {
@Volatile @Volatile
private var isCancelled: Boolean = false private var isCancelled: Boolean = false
private var urlFetcher: DataFetcher<InputStream>? = null private var call: Call<LastFmArtist>? = null
private var streamFetcher: OkHttpStreamFetcher? = null
override fun getId(): String {
// makes sure we never ever return null here override fun getDataClass(): Class<InputStream> {
return model.artistName return InputStream::class.java
} }
@Throws(Exception::class)
override fun loadData(priority: Priority): InputStream? {
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
val response = lastFMRestClient.apiService.getArtistInfo(model.artistName, null, if (model.skipOkHttpCache) "no-cache" else null).execute()
if (!response.isSuccessful) { override fun getDataSource(): DataSource {
throw IOException("Request failed with code: " + response.code()) return DataSource.REMOTE
}
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
try {
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
call = lastFMRestClient.apiService.getArtistInfo(model.artistName, null, if (model.skipOkHttpCache) "no-cache" else null)
call!!.enqueue(object : Callback<LastFmArtist> {
override fun onResponse(call: Call<LastFmArtist>, response: Response<LastFmArtist>) {
if (isCancelled) {
callback.onDataReady(null)
return
}
val lastFmArtist = response.body()
if (lastFmArtist == null || lastFmArtist.artist == null || lastFmArtist.artist.image == null) {
callback.onLoadFailed(Exception("No artist image url found"))
return
}
val url = LastFMUtil.getLargestArtistImageUrl(lastFmArtist.artist.image)
if (TextUtils.isEmpty(url) || TextUtils.isEmpty(url.trim { it <= ' ' })) {
callback.onLoadFailed(Exception("No artist image url found"))
return
}
streamFetcher = OkHttpStreamFetcher(okHttp, GlideUrl(url))
streamFetcher!!.loadData(priority, callback)
}
override fun onFailure(call: Call<LastFmArtist>, throwable: Throwable) {
callback.onLoadFailed(Exception(throwable))
}
})
} }
} catch (e: Exception) {
val lastFmArtist = response.body() callback.onLoadFailed(e)
if (isCancelled) return null
val url = GlideUrl(LastFMUtil.getLargestArtistImageUrl(lastFmArtist!!.artist.image))
urlFetcher = urlLoader.getResourceFetcher(url, width, height)
return urlFetcher!!.loadData(priority)
} }
return null
} }
override fun cleanup() { override fun cleanup() {
if (urlFetcher != null) { if (streamFetcher != null) {
urlFetcher!!.cleanup() streamFetcher!!.cleanup()
} }
} }
override fun cancel() { override fun cancel() {
isCancelled = true isCancelled = true
if (urlFetcher != null) { if (call != null) {
urlFetcher!!.cancel() call!!.cancel()
}
if (streamFetcher != null) {
streamFetcher!!.cancel()
} }
} }
companion object { companion object {
val TAG = ArtistImageFetcher::class.java.simpleName val TAG: String = ArtistImageFetcher::class.java.simpleName
} }
} }

View File

@ -1,52 +1,49 @@
package code.name.monkey.retromusic.glide.artistimage package code.name.monkey.retromusic.glide.artistimage
import android.content.Context import android.content.Context
import code.name.monkey.retromusic.rest.LastFMRestClient
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader import com.bumptech.glide.load.Options
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.GenericLoaderFactory
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.load.model.ModelLoader import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.stream.StreamModelLoader import com.bumptech.glide.load.model.MultiModelLoaderFactory
import code.name.monkey.retromusic.rest.LastFMRestClient import com.bumptech.glide.signature.ObjectKey
import okhttp3.OkHttpClient
import java.io.InputStream import java.io.InputStream
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import okhttp3.OkHttpClient
class ArtistImageLoader(private val context: Context, private val lastFMClient: LastFMRestClient, private val okhttp: OkHttpClient) : ModelLoader<ArtistImage, InputStream> {
class ArtistImageLoader(private val context: Context, private val lastFMClient: LastFMRestClient, private val urlLoader: ModelLoader<GlideUrl, InputStream>) : StreamModelLoader<ArtistImage> { override fun buildLoadData(model: ArtistImage, width: Int, height: Int, options: Options): ModelLoader.LoadData<InputStream>? {
return ModelLoader.LoadData(ObjectKey(model.artistName), ArtistImageFetcher(context, lastFMClient, okhttp, model, width, height))
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
return ArtistImageFetcher(context, lastFMClient, model, urlLoader, width, height)
} }
class Factory(context: Context) : ModelLoaderFactory<ArtistImage, InputStream> { override fun handles(model: ArtistImage): Boolean {
return true
}
class Factory(private val context: Context) : ModelLoaderFactory<ArtistImage, InputStream> {
private val lastFMClient: LastFMRestClient = LastFMRestClient(LastFMRestClient.createDefaultOkHttpClientBuilder(context) private val lastFMClient: LastFMRestClient = LastFMRestClient(LastFMRestClient.createDefaultOkHttpClientBuilder(context)
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS) .connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS) .readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS) .writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.build()) .build())
private val okHttpFactory: OkHttpUrlLoader.Factory = OkHttpUrlLoader.Factory(OkHttpClient.Builder() private val okHttp: OkHttpClient = OkHttpClient.Builder()
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS) .connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS) .readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS) .writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.build()) .build()
override fun build(context: Context, factories: GenericLoaderFactory): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(context, lastFMClient, okHttpFactory.build(context, factories)) override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(context, lastFMClient, okHttp)
} }
override fun teardown() { override fun teardown() {}
okHttpFactory.teardown()
}
} }
companion object { companion object {
// we need these very low values to make sure our artist image loading calls doesn't block the image loading queue // we need these very low values to make sure our artist image loading calls doesn't block the image loading queue
private const val TIMEOUT = 500 private const val TIMEOUT = 500
} }
} }

View File

@ -2,41 +2,48 @@ package code.name.monkey.retromusic.glide.audiocover
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import com.bumptech.glide.Priority import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.data.DataFetcher import com.bumptech.glide.load.data.DataFetcher
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException
import org.jaudiotagger.audio.mp3.MP3File import org.jaudiotagger.audio.mp3.MP3File
import org.jaudiotagger.tag.TagException
import java.io.* import java.io.*
/**
* @author Karim Abou Zeid (kabouzeid)
*/
class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<InputStream> { class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<InputStream> {
private var stream: FileInputStream? = null private var stream: FileInputStream? = null
override fun getId(): String { override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
// makes sure we never ever return null here
return model.filePath
}
@Throws(Exception::class)
override fun loadData(priority: Priority): InputStream? {
val retriever = MediaMetadataRetriever() val retriever = MediaMetadataRetriever()
val data: InputStream?
try { try {
retriever.setDataSource(model.filePath) retriever.setDataSource(model.filePath)
val picture = retriever.embeddedPicture val picture = retriever.embeddedPicture
return if (picture != null) { if (picture != null) {
ByteArrayInputStream(picture) data = ByteArrayInputStream(picture)
} else { } else {
fallback(model.filePath) data = fallback(model.filePath)
} }
callback.onDataReady(data)
} catch (e: FileNotFoundException) {
callback.onLoadFailed(e)
} finally { } finally {
retriever.release() retriever.release()
} }
} }
override fun getDataClass(): Class<InputStream> {
return InputStream::class.java
}
override fun getDataSource(): DataSource {
return DataSource.LOCAL
}
@Throws(FileNotFoundException::class) @Throws(FileNotFoundException::class)
private fun fallback(path: String): InputStream? { private fun fallback(path: String): InputStream? {
// Method 1: use embedded high resolution album art if there is any
try { try {
val mp3File = MP3File(path) val mp3File = MP3File(path)
if (mp3File.hasID3v2Tag()) { if (mp3File.hasID3v2Tag()) {
@ -47,10 +54,7 @@ class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<Inp
} }
} }
// If there are any exceptions, we ignore them and continue to the other fallback method // If there are any exceptions, we ignore them and continue to the other fallback method
} catch (ignored: ReadOnlyFileException) { } catch (ignored: Exception) {
} catch (ignored: InvalidAudioFrameException) {
} catch (ignored: TagException) {
} catch (ignored: IOException) {
} }
// Method 2: look for album art in external files // Method 2: look for album art in external files
@ -82,6 +86,7 @@ class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<Inp
} }
companion object { companion object {
private val FALLBACKS = arrayOf("cover.jpg", "album.jpg", "folder.jpg", "cover.png", "album.png", "folder.png") private val FALLBACKS = arrayOf("cover.jpg", "album.jpg", "folder.jpg", "cover.png", "album.png", "folder.png")
} }
} }

View File

@ -1,24 +1,27 @@
package code.name.monkey.retromusic.glide.audiocover package code.name.monkey.retromusic.glide.audiocover
import android.content.Context import com.bumptech.glide.load.Options
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.GenericLoaderFactory
import com.bumptech.glide.load.model.ModelLoader import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoader.LoadData
import com.bumptech.glide.load.model.ModelLoaderFactory import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.stream.StreamModelLoader import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.bumptech.glide.signature.ObjectKey
import java.io.InputStream import java.io.InputStream
class AudioFileCoverLoader : StreamModelLoader<AudioFileCover> { class AudioFileCoverLoader : ModelLoader<AudioFileCover, InputStream> {
override fun buildLoadData(model: AudioFileCover, width: Int, height: Int,
override fun getResourceFetcher(model: AudioFileCover, width: Int, height: Int): DataFetcher<InputStream> { options: Options): LoadData<InputStream>? {
return AudioFileCoverFetcher(model) return LoadData(ObjectKey(model.filePath), AudioFileCoverFetcher(model))
} }
override fun handles(model: AudioFileCover): Boolean {
return true
}
class Factory : ModelLoaderFactory<AudioFileCover, InputStream> { class Factory : ModelLoaderFactory<AudioFileCover, InputStream> {
override fun build(context: Context, factories: GenericLoaderFactory): ModelLoader<AudioFileCover, InputStream> { override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<AudioFileCover, InputStream> {
return AudioFileCoverLoader() return AudioFileCoverLoader()
} }

View File

@ -1,23 +1,24 @@
package code.name.monkey.retromusic.glide.palette package code.name.monkey.retromusic.glide.palette
import com.bumptech.glide.load.engine.Resource import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.util.Util import com.bumptech.glide.util.Util
class BitmapPaletteResource(private val bitmapPaletteWrapper: BitmapPaletteWrapper, private val bitmapPool: BitmapPool) : Resource<BitmapPaletteWrapper> { class BitmapPaletteResource(private val bitmapPaletteWrapper: BitmapPaletteWrapper) : Resource<BitmapPaletteWrapper> {
override fun get(): BitmapPaletteWrapper { override fun get(): BitmapPaletteWrapper {
return bitmapPaletteWrapper return bitmapPaletteWrapper
} }
override fun getResourceClass(): Class<BitmapPaletteWrapper> {
return BitmapPaletteWrapper::class.java
}
override fun getSize(): Int { override fun getSize(): Int {
return Util.getBitmapByteSize(bitmapPaletteWrapper.bitmap) return Util.getBitmapByteSize(bitmapPaletteWrapper.bitmap)
} }
override fun recycle() { override fun recycle() {
if (!bitmapPool.put(bitmapPaletteWrapper.bitmap)) { bitmapPaletteWrapper.bitmap.recycle()
bitmapPaletteWrapper.bitmap.recycle()
}
} }
} }

View File

@ -1,12 +1,14 @@
package code.name.monkey.retromusic.glide.palette package code.name.monkey.retromusic.glide.palette
import android.widget.ImageView import android.widget.ImageView
import com.bumptech.glide.request.target.ImageViewTarget import com.bumptech.glide.request.target.ImageViewTarget
open class BitmapPaletteTarget(view: ImageView) : ImageViewTarget<BitmapPaletteWrapper>(view) { open class BitmapPaletteTarget(view: ImageView) : ImageViewTarget<BitmapPaletteWrapper>(view) {
override fun setResource(bitmapPaletteWrapper: BitmapPaletteWrapper) { override fun setResource(bitmapPaletteWrapper: BitmapPaletteWrapper?) {
view.setImageBitmap(bitmapPaletteWrapper.bitmap) if (bitmapPaletteWrapper != null) {
view.setImageBitmap(bitmapPaletteWrapper.bitmap)
}
} }
}
}

View File

@ -1,25 +1,16 @@
package code.name.monkey.retromusic.glide.palette package code.name.monkey.retromusic.glide.palette
import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder
class BitmapPaletteTranscoder(private val bitmapPool: BitmapPool) : ResourceTranscoder<Bitmap, BitmapPaletteWrapper> { class BitmapPaletteTranscoder : ResourceTranscoder<Bitmap, BitmapPaletteWrapper> {
override fun transcode(bitmapResource: Resource<Bitmap>, options: Options): Resource<BitmapPaletteWrapper>? {
constructor(context: Context) : this(Glide.get(context).bitmapPool) {}
override fun transcode(bitmapResource: Resource<Bitmap>): Resource<BitmapPaletteWrapper> {
val bitmap = bitmapResource.get() val bitmap = bitmapResource.get()
val bitmapPaletteWrapper = BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap)!!) val bitmapPaletteWrapper = BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap)!!)
return BitmapPaletteResource(bitmapPaletteWrapper, bitmapPool) return BitmapPaletteResource(bitmapPaletteWrapper)
}
override fun getId(): String {
return "BitmapPaletteTranscoder.code.name.monkey.retromusic.glide.palette"
} }
} }

View File

@ -35,10 +35,8 @@ import android.telephony.TelephonyManager;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import com.bumptech.glide.BitmapRequestBuilder;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget; import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
@ -54,7 +52,10 @@ import code.name.monkey.retromusic.appwidgets.AppWidgetClassic;
import code.name.monkey.retromusic.appwidgets.AppWidgetSmall; import code.name.monkey.retromusic.appwidgets.AppWidgetSmall;
import code.name.monkey.retromusic.appwidgets.AppWidgetText; import code.name.monkey.retromusic.appwidgets.AppWidgetText;
import code.name.monkey.retromusic.glide.BlurTransformation; import code.name.monkey.retromusic.glide.BlurTransformation;
import code.name.monkey.retromusic.glide.SongGlideRequest; import code.name.monkey.retromusic.glide.GlideApp;
import code.name.monkey.retromusic.glide.GlideRequest;
import code.name.monkey.retromusic.glide.RetroGlideExtension;
import code.name.monkey.retromusic.glide.RetroSimpleTarget;
import code.name.monkey.retromusic.helper.ShuffleHelper; import code.name.monkey.retromusic.helper.ShuffleHelper;
import code.name.monkey.retromusic.helper.StopWatch; import code.name.monkey.retromusic.helper.StopWatch;
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader; import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
@ -686,24 +687,26 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
if (PreferenceUtil.getInstance().albumArtOnLockscreen()) { if (PreferenceUtil.getInstance().albumArtOnLockscreen()) {
final Point screenSize = RetroUtil.getScreenSize(MusicService.this); final Point screenSize = RetroUtil.getScreenSize(MusicService.this);
final BitmapRequestBuilder<?, Bitmap> request = SongGlideRequest.Builder.Companion.from(Glide.with(MusicService.this), song) GlideRequest request = GlideApp.with(MusicService.this)
.checkIgnoreMediaStore(MusicService.this) .asBitmap()
.asBitmap().build(); .load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song);
if (PreferenceUtil.getInstance().blurredAlbumArt()) { if (PreferenceUtil.getInstance().blurredAlbumArt()) {
request.transform(new BlurTransformation.Builder(MusicService.this).build()); request.transform(new BlurTransformation.Builder(MusicService.this).build());
} }
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
request.into(new SimpleTarget<Bitmap>(screenSize.x, screenSize.y) { request.into(new RetroSimpleTarget<Bitmap>(screenSize.x, screenSize.y) {
@Override @Override
public void onLoadFailed(Exception e, Drawable errorDrawable) { public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable); super.onLoadFailed(errorDrawable);
mediaSession.setMetadata(metaData.build()); mediaSession.setMetadata(metaData.build());
} }
@Override @Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> glideAnimation) {
metaData.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, copy(resource)); metaData.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, copy(resource));
mediaSession.setMetadata(metaData.build()); mediaSession.setMetadata(metaData.build());
} }

View File

@ -19,18 +19,18 @@ import code.name.monkey.retromusic.Constants.ACTION_REWIND
import code.name.monkey.retromusic.Constants.ACTION_SKIP import code.name.monkey.retromusic.Constants.ACTION_SKIP
import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget.Companion.createBitmap
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.RetroUtil.createBitmap
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class PlayingNotificationImpl : PlayingNotification() { class PlayingNotificationImpl : PlayingNotification() {
@ -92,15 +92,16 @@ class PlayingNotificationImpl : PlayingNotification() {
.getDimensionPixelSize(R.dimen.notification_big_image_size) .getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target!!) GlideApp.with(service).clear(target);
} }
target = SongGlideRequest.Builder.from(Glide.with(service), song) target = GlideApp.with(service)
.checkIgnoreMediaStore(service) .asBitmapPalette()
.generatePalette(service).build() .load(RetroGlideExtension.getSongModel(song))
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, .transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize,
bigNotificationImageSize) { bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
update(resource.bitmap, update(resource.bitmap,
if (PreferenceUtil.getInstance().isDominantColor) if (PreferenceUtil.getInstance().isDominantColor)
RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT) RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT)
@ -108,8 +109,8 @@ class PlayingNotificationImpl : PlayingNotification() {
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)) RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT))
} }
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(errorDrawable)
update(null, Color.WHITE) update(null, Color.WHITE)
} }

View File

@ -10,24 +10,24 @@ import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.text.Html import android.text.Html
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.media.app.NotificationCompat.MediaStyle
import code.name.monkey.retromusic.Constants.ACTION_QUIT import code.name.monkey.retromusic.Constants.ACTION_QUIT
import code.name.monkey.retromusic.Constants.ACTION_REWIND import code.name.monkey.retromusic.Constants.ACTION_REWIND
import code.name.monkey.retromusic.Constants.ACTION_SKIP import code.name.monkey.retromusic.Constants.ACTION_SKIP
import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.Glide import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.animation.GlideAnimation import com.bumptech.glide.request.transition.Transition
import com.bumptech.glide.request.target.SimpleTarget
class PlayingNotificationImpl24 : PlayingNotification() { class PlayingNotificationImpl24 : PlayingNotification() {
private var target: Target<BitmapPaletteWrapper>? = null
@Synchronized @Synchronized
override fun update() { override fun update() {
stopped = false stopped = false
@ -54,18 +54,23 @@ class PlayingNotificationImpl24 : PlayingNotification() {
val bigNotificationImageSize = service.resources val bigNotificationImageSize = service.resources
.getDimensionPixelSize(R.dimen.notification_big_image_size) .getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread { service.runOnUiThread {
SongGlideRequest.Builder.from(Glide.with(service), song) if (target != null) {
.checkIgnoreMediaStore(service) GlideApp.with(service).clear(target);
.generatePalette(service).build() }
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) { target = GlideApp.with(service)
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) { .asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
update(resource.bitmap, when { update(resource.bitmap, when {
PreferenceUtil.getInstance().isDominantColor -> RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT) PreferenceUtil.getInstance().isDominantColor -> RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT)
else -> RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT) else -> RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
}) })
} }
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(errorDrawable: Drawable?) {
update(null, Color.TRANSPARENT) update(null, Color.TRANSPARENT)
} }
@ -111,7 +116,7 @@ class PlayingNotificationImpl24 : PlayingNotification() {
.addAction(closeAction) .addAction(closeAction)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setStyle(MediaStyle() builder.setStyle(androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(service.mediaSession.sessionToken) .setMediaSession(service.mediaSession.sessionToken)
.setShowActionsInCompactView(0, 1, 2, 3, 4)) .setShowActionsInCompactView(0, 1, 2, 3, 4))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)

View File

@ -16,7 +16,9 @@ import code.name.monkey.retromusic.Constants.ACTION_REWIND
import code.name.monkey.retromusic.Constants.ACTION_SKIP import code.name.monkey.retromusic.Constants.ACTION_SKIP
import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
@ -25,10 +27,8 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.RetroUtil.createBitmap import code.name.monkey.retromusic.util.RetroUtil.createBitmap
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
/** /**
* @author Hemanth S (h4h13). * @author Hemanth S (h4h13).
@ -89,24 +89,21 @@ class PlayingNotificationOreo : PlayingNotification() {
.getDimensionPixelSize(R.dimen.notification_big_image_size) .getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target!!) GlideApp.with(service).clear(target);
} }
target = SongGlideRequest.Builder.from(Glide.with(service), song) target = GlideApp.with(service)
.checkIgnoreMediaStore(service) .asBitmapPalette()
.generatePalette(service).build() .load(RetroGlideExtension.getSongModel(song))
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, .transition(RetroGlideExtension.getDefaultTransition())
bigNotificationImageSize) { .songOptions(song)
override fun onResourceReady(resource: BitmapPaletteWrapper, .into(object : RetroSimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) { override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val mediaNotificationProcessor = MediaNotificationProcessor(service, service) { i, _ -> update(resource.bitmap, i) }
val mediaNotificationProcessor = MediaNotificationProcessor(
service, service) { i, _ -> update(resource.bitmap, i) }
mediaNotificationProcessor.processNotification(resource.bitmap) mediaNotificationProcessor.processNotification(resource.bitmap)
} }
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(errorDrawable)
update(null, Color.WHITE) update(null, Color.WHITE)
} }

View File

@ -19,9 +19,9 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.glide.ArtistGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
import code.name.monkey.retromusic.loaders.ArtistLoader import code.name.monkey.retromusic.loaders.ArtistLoader
@ -38,8 +38,6 @@ import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.views.CircularImageView
import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.activity_album.* import kotlinx.android.synthetic.main.activity_album.*
import kotlinx.android.synthetic.main.activity_album_content.* import kotlinx.android.synthetic.main.activity_album_content.*
@ -192,7 +190,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
private fun loadMoreFrom(album: Album) { private fun loadMoreFrom(album: Album) {
if (artistImage != null) { if (artistImage != null) {
ArtistGlideRequest.Builder.from(Glide.with(this), /*ArtistGlideRequest.Builder.from(Glide.with(this),
ArtistLoader.getArtist(this, album.artistId).blockingFirst()) ArtistLoader.getArtist(this, album.artistId).blockingFirst())
.forceDownload(false) .forceDownload(false)
.generatePalette(this).build() .generatePalette(this).build()
@ -201,7 +199,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
//setColors(color); //setColors(color);
} }
}) })*/
} }
val albums = ArtistLoader.getArtist(this, album.artistId).blockingFirst().albums val albums = ArtistLoader.getArtist(this, album.artistId).blockingFirst().albums
@ -220,14 +218,17 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
} }
private fun loadAlbumCover() { private fun loadAlbumCover() {
SongGlideRequest.Builder.from(Glide.with(this), album!!.safeGetFirstSong()) GlideApp.with(this)
.checkIgnoreMediaStore(this) .asBitmapPalette()
.generatePalette(this).build() .load(RetroGlideExtension.getSongModel(album!!.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album!!.safeGetFirstSong())
.dontAnimate() .dontAnimate()
.into(object : RetroMusicColoredTarget(image) { .into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColors(color) setColors(color)
} }
}) })
} }

View File

@ -22,7 +22,8 @@ import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.glide.ArtistGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.misc.AppBarStateChangeListener import code.name.monkey.retromusic.misc.AppBarStateChangeListener
@ -36,7 +37,6 @@ import code.name.monkey.retromusic.ui.adapter.album.AlbumAdapter
import code.name.monkey.retromusic.ui.adapter.album.HorizontalAlbumAdapter import code.name.monkey.retromusic.ui.adapter.album.HorizontalAlbumAdapter
import code.name.monkey.retromusic.ui.adapter.song.SimpleSongAdapter import code.name.monkey.retromusic.ui.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.util.* import code.name.monkey.retromusic.util.*
import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.activity_artist_content.* import kotlinx.android.synthetic.main.activity_artist_content.*
import kotlinx.android.synthetic.main.activity_artist_details.* import kotlinx.android.synthetic.main.activity_artist_details.*
@ -181,7 +181,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
when (requestCode) { when (requestCode) {
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) { REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, data!!.data) CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist!!, data!!.data!!)
} }
else -> if (resultCode == Activity.RESULT_OK) { else -> if (resultCode == Activity.RESULT_OK) {
reload() reload()
@ -272,16 +272,18 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
private fun loadArtistImage() { private fun loadArtistImage() {
ArtistGlideRequest.Builder.from(Glide.with(this), artist!!) GlideApp.with(this)
.forceDownload(forceDownload) .asBitmapPalette()
.generatePalette(this).build() .load(RetroGlideExtension.getArtistModel(artist!!, forceDownload))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.dontAnimate() .dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) { .into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColors(color) setColors(color)
} }
}) })
forceDownload = false forceDownload = false;
} }
private fun setColors(color: Int) { private fun setColors(color: Int) {
@ -331,7 +333,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
R.id.action_reset_artist_image -> { R.id.action_reset_artist_image -> {
Toast.makeText(this@ArtistDetailActivity, resources.getString(R.string.updating), Toast.makeText(this@ArtistDetailActivity, resources.getString(R.string.updating),
Toast.LENGTH_SHORT).show() Toast.LENGTH_SHORT).show()
CustomArtistImageUtil.getInstance(this@ArtistDetailActivity).resetCustomArtistImage(artist) CustomArtistImageUtil.getInstance(this@ArtistDetailActivity).resetCustomArtistImage(artist!!)
forceDownload = true forceDownload = true
return true return true
} }

View File

@ -1,23 +1,21 @@
package code.name.monkey.retromusic.ui.activities package code.name.monkey.retromusic.ui.activities
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.ui.fragments.player.lockscreen.LockScreenPlayerControlsFragment import code.name.monkey.retromusic.ui.fragments.player.lockscreen.LockScreenPlayerControlsFragment
import com.bumptech.glide.Glide
import com.r0adkll.slidr.Slidr import com.r0adkll.slidr.Slidr
import com.r0adkll.slidr.model.SlidrConfig import com.r0adkll.slidr.model.SlidrConfig
import com.r0adkll.slidr.model.SlidrListener
import com.r0adkll.slidr.model.SlidrPosition import com.r0adkll.slidr.model.SlidrPosition
import kotlinx.android.synthetic.main.activity_album.*
class LockScreenActivity : AbsMusicServiceActivity() { class LockScreenActivity : AbsMusicServiceActivity() {
private var mFragment: LockScreenPlayerControlsFragment? = null private var mFragment: LockScreenPlayerControlsFragment? = null
@ -71,10 +69,13 @@ class LockScreenActivity : AbsMusicServiceActivity() {
private fun updateSongs() { private fun updateSongs() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
SongGlideRequest.Builder.from(Glide.with(this), song) GlideApp.with(this)
.checkIgnoreMediaStore(this) .asBitmapPalette()
.generatePalette(this) .load(RetroGlideExtension.getSongModel(song))
.build().into(object : RetroMusicColoredTarget(findViewById(R.id.image)) { .transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.dontAnimate()
.into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
mFragment!!.setDark(color) mFragment!!.setDark(color)
} }

View File

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.content.* import android.content.*
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
@ -12,13 +11,7 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.app.ShareCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.drawerlayout.widget.DrawerLayout.*
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.NavigationViewUtil
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -29,15 +22,12 @@ import code.name.monkey.retromusic.loaders.ArtistLoader
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.ui.activities.bugreport.BugReportActivity
import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment
import code.name.monkey.retromusic.ui.fragments.mainactivity.folders.FoldersFragment
import code.name.monkey.retromusic.ui.fragments.mainactivity.home.BannerHomeFragment import code.name.monkey.retromusic.ui.fragments.mainactivity.home.BannerHomeFragment
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_main_drawer_layout.*
import java.util.* import java.util.*
@ -73,16 +63,16 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
setDrawUnderStatusBar() setDrawUnderStatusBar()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
getBottomNavigationView()!!.setOnNavigationItemSelectedListener { getBottomNavigationView().setOnNavigationItemSelectedListener {
PreferenceUtil.getInstance().lastPage = it.itemId PreferenceUtil.getInstance().lastPage = it.itemId
selectedFragment(it.itemId) selectedFragment(it.itemId)
true true
} }
setUpDrawerLayout() //setUpDrawerLayout()
if (savedInstanceState == null) { if (savedInstanceState == null) {
setMusicChooser(PreferenceUtil.getInstance().lastMusicChooser) selectedFragment(PreferenceUtil.getInstance().lastPage);
} else { } else {
restoreCurrentFragment(); restoreCurrentFragment();
} }
@ -130,8 +120,13 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this) PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this)
} }
private fun setCurrentFragment(fragment: Fragment) { fun setCurrentFragment(fragment: Fragment, b: Boolean) {
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, null).commit() val trans = supportFragmentManager.beginTransaction()
trans.replace(R.id.fragment_container, fragment, null)
if (b) {
trans.addToBackStack(null)
}
trans.commit()
currentFragment = fragment as MainActivityFragmentCallbacks currentFragment = fragment as MainActivityFragmentCallbacks
} }
@ -213,12 +208,11 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
if (!hasPermissions()) { if (!hasPermissions()) {
requestPermissions() requestPermissions()
} }
checkSetUpPro(); // good chance that pro version check was delayed on first start
} }
REQUEST_CODE_THEME, APP_USER_INFO_REQUEST -> postRecreate() REQUEST_CODE_THEME, APP_USER_INFO_REQUEST -> postRecreate()
PURCHASE_REQUEST -> { PURCHASE_REQUEST -> {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
checkSetUpPro(); //checkSetUpPro();
} }
} }
} }
@ -226,10 +220,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
} }
override fun handleBackPress(): Boolean { override fun handleBackPress(): Boolean {
if (drawerLayout.isDrawerOpen(navigationView)) {
drawerLayout.closeDrawers()
return true
}
return super.handleBackPress() || currentFragment.handleBackPress() return super.handleBackPress() || currentFragment.handleBackPress()
} }
@ -291,104 +281,20 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
R.id.action_album, R.id.action_album,
R.id.action_artist, R.id.action_artist,
R.id.action_playlist, R.id.action_playlist,
R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId)) R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), false)
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), false)
} }
} }
private fun setUpNavigationView() {
val accentColor = ThemeStore.accentColor(this)
NavigationViewUtil.setItemIconColors(navigationView, ATHUtil.resolveColor(this, R.attr.iconColor, ThemeStore.textColorSecondary(this)), accentColor)
NavigationViewUtil.setItemTextColors(navigationView, ThemeStore.textColorPrimary(this), accentColor)
checkSetUpPro()
navigationView.setBackgroundColor(ThemeStore.primaryColor(this))
navigationView.setNavigationItemSelectedListener { menuItem ->
drawerLayout.closeDrawers()
when (menuItem.itemId) {
R.id.nav_library -> Handler().postDelayed({ setMusicChooser(LIBRARY) }, 200)
R.id.nav_home -> Handler().postDelayed({ setMusicChooser(HOME) }, 200)
R.id.nav_folders -> Handler().postDelayed({ setMusicChooser(FOLDERS) }, 200)
R.id.buy_pro -> Handler().postDelayed({ startActivityForResult(Intent(this@MainActivity, PurchaseActivity::class.java), PURCHASE_REQUEST) }, 200)
R.id.nav_settings -> Handler().postDelayed({ NavigationUtil.goToSettings(this@MainActivity) }, 200)
R.id.nav_equalizer -> Handler().postDelayed({ NavigationUtil.openEqualizer(this@MainActivity) }, 200)
R.id.nav_share_app -> Handler().postDelayed({ shareApp() }, 200)
R.id.nav_report_bug -> Handler().postDelayed({ prepareBugReport() }, 200)
}
true
}
}
private fun prepareBugReport() {
startActivity(Intent(this, BugReportActivity::class.java))
}
private fun shareApp() {
val shareIntent = ShareCompat.IntentBuilder.from(this)
.setType("songText/plain")
.setText(String.format(getString(R.string.app_share), packageName))
.intent
if (shareIntent.resolveActivity(packageManager) != null) {
startActivity(
Intent.createChooser(shareIntent, resources.getText(R.string.action_share)))
}
}
private fun setMusicChooser(key: Int) {
PreferenceUtil.getInstance().lastMusicChooser = key
when (key) {
LIBRARY -> {
navigationView.setCheckedItem(R.id.nav_library)
setCurrentFragment(LibraryFragment.newInstance(PreferenceUtil.getInstance().lastPage))
}
FOLDERS -> {
navigationView.setCheckedItem(R.id.nav_folders)
setCurrentFragment(FoldersFragment.newInstance(this))
}
HOME -> {
navigationView.setCheckedItem(R.id.nav_home)
setCurrentFragment(BannerHomeFragment())
}
}
}
private fun checkSetUpPro() {
if (App.isProVersion) {
setUpPro()
}
}
private fun setUpPro() {
navigationView.menu.removeGroup(R.id.navigation_drawer_menu_category_buy_pro)
}
private fun setUpDrawerLayout() {
setUpNavigationView()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) { if (item.itemId == android.R.id.home) {
if (drawerLayout.isDrawerOpen(navigationView)) { NavigationUtil.goToSearch(this);
drawerLayout.closeDrawer(navigationView)
} else {
drawerLayout.openDrawer(navigationView)
}
return true return true
} }
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
override fun onPanelCollapsed() {
super.onPanelCollapsed()
drawerLayout.setDrawerLockMode(LOCK_MODE_UNLOCKED)
}
override fun onPanelExpanded() {
super.onPanelExpanded()
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
}
companion object { companion object {
const val APP_INTRO_REQUEST = 2323 const val APP_INTRO_REQUEST = 2323
const val LIBRARY = 1 const val LIBRARY = 1

View File

@ -5,7 +5,6 @@ import android.content.res.ColorStateList
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
@ -18,7 +17,8 @@ import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.loaders.AlbumLoader import code.name.monkey.retromusic.loaders.AlbumLoader
import code.name.monkey.retromusic.rest.LastFMRestClient import code.name.monkey.retromusic.rest.LastFMRestClient
@ -26,10 +26,12 @@ import code.name.monkey.retromusic.rest.model.LastFmAlbum
import code.name.monkey.retromusic.util.ImageUtil import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.LastFMUtil import code.name.monkey.retromusic.util.LastFMUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.Glide import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
import code.name.monkey.retromusic.util.RetroColorUtil.getColor
import com.bumptech.glide.GenericTransitionOptions
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.animation.GlideAnimation import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.transition.Transition
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
@ -43,20 +45,14 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
get() = R.layout.activity_album_tag_editor get() = R.layout.activity_album_tag_editor
override fun loadImageFromFile(selectedFile: Uri?) { override fun loadImageFromFile(selectedFile: Uri?) {
Glide.with(this@AlbumTagEditorActivity) GlideApp.with(this).`as`(BitmapPaletteWrapper::class.java)
.load(selectedFile) .load(selectedFile)
.asBitmap() .transition(GenericTransitionOptions<BitmapPaletteWrapper>().transition(android.R.anim.fade_in))
.transcode(BitmapPaletteTranscoder(this@AlbumTagEditorActivity), BitmapPaletteWrapper::class.java) .apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true) .skipMemoryCache(true))
.into(object : SimpleTarget<BitmapPaletteWrapper>() { .into(object : RetroSimpleTarget<BitmapPaletteWrapper>() {
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
super.onLoadFailed(e, errorDrawable)
e!!.printStackTrace()
Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG).show()
}
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT) RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048) albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048)
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor))) setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
@ -108,7 +104,7 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
override fun loadCurrentImage() { override fun loadCurrentImage() {
val bitmap = albumArt val bitmap = albumArt
setImageBitmap(bitmap, RetroColorUtil.getColor(RetroColorUtil.generatePalette(bitmap), ATHUtil.resolveColor(this, R.attr.defaultFooterColor))) setImageBitmap(bitmap, getColor(generatePalette(bitmap), ATHUtil.resolveColor(this, R.attr.defaultFooterColor)))
deleteAlbumArt = false deleteAlbumArt = false
} }
@ -138,23 +134,16 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image) val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image)
if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) { if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) {
Glide.with(this) GlideApp.with(this)
.`as`(BitmapPaletteWrapper::class.java)
.load(url) .load(url)
.asBitmap() .apply(RequestOptions()
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.diskCacheStrategy(DiskCacheStrategy.SOURCE) .error(R.drawable.default_album_art))
.error(R.drawable.default_album_art) .into(object : RetroSimpleTarget<BitmapPaletteWrapper>() {
.into(object : SimpleTarget<BitmapPaletteWrapper>() { override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
e!!.printStackTrace()
Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG).show()
}
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048) albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048)
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.palette, setImageBitmap(albumArtBitmap, getColor(resource.palette,
ContextCompat.getColor(this@AlbumTagEditorActivity, R.color.md_grey_500))) ContextCompat.getColor(this@AlbumTagEditorActivity, R.color.md_grey_500)))
deleteAlbumArt = false deleteAlbumArt = false
dataChanged() dataChanged()

View File

@ -11,12 +11,13 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.adapter.CollageSongAdapter.CollageSongViewHolder import code.name.monkey.retromusic.ui.adapter.CollageSongAdapter.CollageSongViewHolder
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
import com.bumptech.glide.Glide
import java.util.* import java.util.*
/** /**
@ -28,10 +29,16 @@ class CollageSongAdapter(private val activity: Activity, private val dataSet: Ar
holder.bindSongs() holder.bindSongs()
if (dataSet.size > 8) { if (dataSet.size > 8) {
for (i in 0 until dataSet.subList(0, 8).size) { for (i in 0 until dataSet.subList(0, 8).size) {
SongGlideRequest.Builder.from(Glide.with(activity), dataSet[i]) GlideApp.with(activity)
.checkIgnoreMediaStore(activity) .asBitmapPalette()
.build() .load(RetroGlideExtension.getSongModel(dataSet[i]))
.into(holder.itemView.findViewById(holder.ids[i]) as ImageView) .transition(RetroGlideExtension.getDefaultTransition())
.songOptions(dataSet[i])
.into(object : RetroMusicColoredTarget(holder.itemView.findViewById(holder.ids[i]) as ImageView) {
override fun onColorReady(color: Int) {
}
})
} }
} }
} }

View File

@ -8,8 +8,8 @@ import androidx.core.util.Pair
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.ArtistGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.menu.SongMenuHelper import code.name.monkey.retromusic.helper.menu.SongMenuHelper
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
@ -18,7 +18,6 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide
import java.util.* import java.util.*
@ -45,16 +44,23 @@ class SearchAdapter(private val activity: AppCompatActivity, private var dataSet
val album = dataSet!![position] as Album val album = dataSet!![position] as Album
holder.title!!.text = album.title holder.title!!.text = album.title
holder.text!!.text = album.artistName holder.text!!.text = album.artistName
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) GlideApp.with(activity)
.checkIgnoreMediaStore(activity).build() .asDrawable()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.into(holder.image!!) .into(holder.image!!)
} }
ARTIST -> { ARTIST -> {
val artist = dataSet!![position] as Artist val artist = dataSet!![position] as Artist
holder.title!!.text = artist.name holder.title!!.text = artist.name
holder.text!!.text = MusicUtil.getArtistInfoString(activity, artist) holder.text!!.text = MusicUtil.getArtistInfoString(activity, artist)
ArtistGlideRequest.Builder.from(Glide.with(activity), artist) GlideApp.with(activity)
.build().into(holder.image!!) .asBitmap()
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.into(holder.image!!)
} }
SONG -> { SONG -> {
val song = dataSet!![position] as Song val song = dataSet!![position] as Song

View File

@ -1,6 +1,7 @@
package code.name.monkey.retromusic.ui.adapter package code.name.monkey.retromusic.ui.adapter
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -9,19 +10,22 @@ import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide import com.bumptech.glide.GenericTransitionOptions
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.signature.MediaStoreSignature import com.bumptech.glide.signature.MediaStoreSignature
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.io.File import java.io.File
import java.text.DecimalFormat import java.text.DecimalFormat
import java.util.* import java.util.*
class SongFileAdapter(private val activity: AppCompatActivity, private var dataSet: List<File>?, @param:LayoutRes private val itemLayoutRes: Int, private val callbacks: Callbacks?, cabHolder: CabHolder?) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(activity, cabHolder, R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter { class SongFileAdapter(private val activity: AppCompatActivity, private var dataSet: List<File>?, @param:LayoutRes private val itemLayoutRes: Int, private val callbacks: Callbacks?, cabHolder: CabHolder?) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(activity, cabHolder, R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter {
init { init {
@ -91,13 +95,14 @@ class SongFileAdapter(private val activity: AppCompatActivity, private var dataS
holder.image!!.setImageResource(R.drawable.ic_folder_white_24dp) holder.image!!.setImageResource(R.drawable.ic_folder_white_24dp)
} else { } else {
val error = RetroUtil.getTintedVectorDrawable(activity, R.drawable.ic_file_music_white_24dp, iconColor) val error = RetroUtil.getTintedVectorDrawable(activity, R.drawable.ic_file_music_white_24dp, iconColor)
Glide.with(activity) GlideApp.with(activity)
.load(AudioFileCover(file.path)) .load(AudioFileCover(file.path))
.diskCacheStrategy(DiskCacheStrategy.NONE) .transition(GenericTransitionOptions.with<Drawable>(android.R.anim.fade_in))
.error(error) .apply(RequestOptions()
.placeholder(error) .diskCacheStrategy(DiskCacheStrategy.NONE)
.animate(android.R.anim.fade_in) .error(error)
.signature(MediaStoreSignature("", file.lastModified(), 0)) .placeholder(error)
.signature(MediaStoreSignature("", file.lastModified(), 0)))
.into(holder.image!!) .into(holder.image!!)
} }
} }

View File

@ -12,8 +12,9 @@ import androidx.core.util.Pair
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
@ -127,18 +128,21 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
return return
} }
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) GlideApp.with(activity)
.checkIgnoreMediaStore(activity) .asBitmapPalette()
.generatePalette(activity).build() .load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
}
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColors(color, holder) setColors(color, holder)
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColors(defaultFooterColor, holder)
}
}) })
} }

View File

@ -1,6 +1,7 @@
package code.name.monkey.retromusic.ui.adapter.album package code.name.monkey.retromusic.ui.adapter.album
import android.content.Intent import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -9,14 +10,14 @@ import android.widget.ImageView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.activities.LyricsActivity import code.name.monkey.retromusic.ui.activities.LyricsActivity
import code.name.monkey.retromusic.ui.fragments.AlbumCoverStyle import code.name.monkey.retromusic.ui.fragments.AlbumCoverStyle
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import java.util.* import java.util.*
@ -118,13 +119,21 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
} }
private fun loadAlbumCover() { private fun loadAlbumCover() {
SongGlideRequest.Builder.from(Glide.with(context), song!!) GlideApp.with(context!!)
.checkIgnoreMediaStore(activity!!) .asBitmapPalette()
.generatePalette(activity!!).build() .load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.dontAnimate()
.into(object : RetroMusicColoredTarget(albumCover) { .into(object : RetroMusicColoredTarget(albumCover) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColor(color) setColor(color)
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColor(defaultFooterColor)
}
}) })
} }

View File

@ -16,23 +16,20 @@
package code.name.monkey.retromusic.ui.adapter.album package code.name.monkey.retromusic.ui.adapter.album
import android.app.Activity import android.app.Activity
import android.graphics.Bitmap
import android.graphics.Canvas
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import androidx.core.util.Pair import androidx.core.util.Pair
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.views.MetalRecyclerViewPager import code.name.monkey.retromusic.views.MetalRecyclerViewPager
import com.bumptech.glide.Glide
import java.util.* import java.util.*
class AlbumFullWithAdapter(private val activity: Activity, class AlbumFullWithAdapter(private val activity: Activity,
@ -80,10 +77,12 @@ class AlbumFullWithAdapter(private val activity: Activity,
if (holder.image == null) { if (holder.image == null) {
return return
} }
GlideApp.with(activity)
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) .asBitmapPalette()
.checkIgnoreMediaStore(activity) .load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.generatePalette(activity).build() .transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {

View File

@ -6,13 +6,13 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.HorizontalAdapterHelper import code.name.monkey.retromusic.helper.HorizontalAdapterHelper
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import com.bumptech.glide.Glide
import java.util.* import java.util.*
@ -36,20 +36,20 @@ class HorizontalAlbumAdapter(activity: AppCompatActivity, dataSet: ArrayList<Alb
override fun loadAlbumCover(album: Album, holder: ViewHolder) { override fun loadAlbumCover(album: Album, holder: ViewHolder) {
if (holder.image == null) return if (holder.image == null) return
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) GlideApp.with(activity)
.checkIgnoreMediaStore(activity) .asBitmapPalette()
.generatePalette(activity).build() .load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onLoadCleared(placeholder: Drawable?) { override fun onColorReady(color: Int) {
super.onLoadCleared(placeholder) setColors(color, holder)
setColors(albumArtistFooterColor, holder)
} }
override fun onColorReady(color: Int) { override fun onLoadFailed(errorDrawable: Drawable?) {
if (usePalette) super.onLoadFailed(errorDrawable)
setColors(color, holder) setColors(defaultFooterColor, holder)
else
setColors(albumArtistFooterColor, holder)
} }
}) })
} }
@ -63,6 +63,6 @@ class HorizontalAlbumAdapter(activity: AppCompatActivity, dataSet: ArrayList<Alb
} }
companion object { companion object {
val TAG: String = AlbumAdapter::class.java.simpleName val TAG: String = AlbumAdapter::class.java.simpleName
} }
} }

View File

@ -12,7 +12,8 @@ import androidx.core.util.Pair
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.ArtistGlideRequest import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
@ -22,7 +23,6 @@ import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.util.* import java.util.*
@ -91,8 +91,12 @@ class ArtistAdapter(val activity: AppCompatActivity,
if (holder.image == null) { if (holder.image == null) {
return return
} }
ArtistGlideRequest.Builder.from(Glide.with(activity), artist) GlideApp.with(activity)
.generatePalette(activity).build() .asBitmapPalette()
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColors(color, holder) setColors(color, holder)

View File

@ -1,8 +1,6 @@
package code.name.monkey.retromusic.ui.adapter.playlist package code.name.monkey.retromusic.ui.adapter.playlist
import android.graphics.Bitmap
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -27,11 +25,7 @@ import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import io.reactivex.Observable
import java.util.* import java.util.*
import java.util.concurrent.ExecutionException
class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayList<Playlist>, class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayList<Playlist>,
@param:LayoutRes protected var itemLayoutRes: Int, cabHolder: CabHolder?) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(activity, cabHolder, R.menu.menu_playlists_selection) { @param:LayoutRes protected var itemLayoutRes: Int, cabHolder: CabHolder?) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(activity, cabHolder, R.menu.menu_playlists_selection) {
@ -175,34 +169,6 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL
return songs return songs
} }
private fun loadBitmaps(songs: ArrayList<Song>): Observable<ArrayList<Bitmap>> {
return Observable.create { e ->
val bitmaps = ArrayList<Bitmap>()
for (song in songs) {
try {
val bitmap = Glide.with(activity)
.load(RetroUtil.getAlbumArtUri(song.albumId.toLong()))
.asBitmap()
.into(500, 500)
.get()
if (bitmap != null) {
Log.i(TAG, "loadBitmaps: has")
bitmaps.add(bitmap)
}
if (bitmaps.size == 4) {
break
}
} catch (ex: InterruptedException) {
ex.printStackTrace()
} catch (ex: ExecutionException) {
ex.printStackTrace()
}
}
e.onNext(bitmaps)
e.onComplete()
}
}
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) { inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init { init {

View File

@ -11,8 +11,9 @@ import androidx.core.util.Pair
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.helper.menu.SongMenuHelper import code.name.monkey.retromusic.helper.menu.SongMenuHelper
@ -25,7 +26,6 @@ import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialcab.MaterialCab import com.afollestad.materialcab.MaterialCab
import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.util.* import java.util.*
@ -115,19 +115,19 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
if (holder.image == null) { if (holder.image == null) {
return return
} }
GlideApp.with(activity).asBitmapPalette()
SongGlideRequest.Builder.from(Glide.with(activity), song) .load(RetroGlideExtension.getSongModel(song))
.checkIgnoreMediaStore(activity) .transition(RetroGlideExtension.getDefaultTransition())
.generatePalette(activity).build() .songOptions(song)
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
}
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColors(color, holder) setColors(color, holder)
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColors(defaultFooterColor, holder)
}
}) })
} }
@ -226,6 +226,6 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
companion object { companion object {
val TAG:String = SongAdapter::class.java.simpleName val TAG: String = SongAdapter::class.java.simpleName
} }
} }

View File

@ -1,6 +1,7 @@
package code.name.monkey.retromusic.ui.fragments.player.blur package code.name.monkey.retromusic.ui.fragments.player.blur
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.view.LayoutInflater import android.view.LayoutInflater
@ -10,13 +11,13 @@ import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.BlurTransformation import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_blur.* import kotlinx.android.synthetic.main.fragment_blur.*
class BlurPlayerFragment : AbsPlayerFragment() { class BlurPlayerFragment : AbsPlayerFragment() {
@ -94,23 +95,26 @@ class BlurPlayerFragment : AbsPlayerFragment() {
private fun updateBlur() { private fun updateBlur() {
val activity = activity ?: return val activity = activity ?: return
val blurAmount = PreferenceManager.getDefaultSharedPreferences(context).getInt("new_blur_amount", 25) val blurAmount = PreferenceManager.getDefaultSharedPreferences(context).getInt("new_blur_amount", 25)
colorBackground!!.clearColorFilter() colorBackground!!.clearColorFilter()
GlideApp.with(activity)
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.currentSong) .asBitmapPalette()
.checkIgnoreMediaStore(activity) .load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.generatePalette(activity) .transition(RetroGlideExtension.getDefaultTransition())
.build() .transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build())
.songOptions(MusicPlayerRemote.currentSong)
.override(320, 480) .override(320, 480)
.transform(BlurTransformation.Builder(getActivity()!!).blurRadius(blurAmount.toFloat()).build()) .into(object : RetroMusicColoredTarget(colorBackground) {
.into(object : RetroMusicColoredTarget(colorBackground!!) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
if (color == defaultFooterColor) { if (color == defaultFooterColor) {
colorBackground!!.setColorFilter(color) colorBackground!!.setColorFilter(color)
} }
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
}) })
} }

View File

@ -1,6 +1,7 @@
package code.name.monkey.retromusic.ui.fragments.player.cardblur package code.name.monkey.retromusic.ui.fragments.player.cardblur
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.view.LayoutInflater import android.view.LayoutInflater
@ -10,14 +11,14 @@ import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.BlurTransformation import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_card_blur_player.* import kotlinx.android.synthetic.main.fragment_card_blur_player.*
class CardBlurFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { class CardBlurFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
@ -128,18 +129,27 @@ class CardBlurFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
.getInt("new_blur_amount", 25) .getInt("new_blur_amount", 25)
colorBackground!!.clearColorFilter() colorBackground!!.clearColorFilter()
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(activity) GlideApp.with(activity)
.generatePalette(activity) .asBitmapPalette()
.build() .load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.transform(BlurTransformation.Builder(getActivity()!!).blurRadius(blurAmount.toFloat()).build()) .transition(RetroGlideExtension.getDefaultTransition())
.into(object : RetroMusicColoredTarget(colorBackground!!) { .transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build())
.songOptions(MusicPlayerRemote.currentSong)
.override(320, 480)
.into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
if (color == defaultFooterColor) { if (color == defaultFooterColor) {
colorBackground!!.setColorFilter(color) colorBackground!!.setColorFilter(color)
} }
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
}) })
} }
companion object { companion object {

View File

@ -17,8 +17,9 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
@ -28,8 +29,7 @@ import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import com.bumptech.glide.Glide import com.bumptech.glide.request.transition.Transition
import com.bumptech.glide.request.animation.GlideAnimation
import kotlinx.android.synthetic.main.fragment_color_player.* import kotlinx.android.synthetic.main.fragment_color_player.*
class ColorFragment : AbsPlayerFragment() { class ColorFragment : AbsPlayerFragment() {
@ -130,9 +130,40 @@ class ColorFragment : AbsPlayerFragment() {
} }
private fun updateSong() { private fun updateSong() {
val activity = activity
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.currentSong) GlideApp.with(activity!!).asBitmapPalette()
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.songOptions(MusicPlayerRemote.currentSong)
.transition(RetroGlideExtension.getDefaultTransition())
.into(object : RetroMusicColoredTarget(playerImage) {
override fun onColorReady(color: Int) {
}
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: Transition<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation)
val palette = resource.palette
val swatch = RetroColorUtil.getSwatch(palette)
val textColor = RetroColorUtil.getTextColor(palette)
val backgroundColor = swatch.rgb
setColors(backgroundColor, textColor)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
val backgroundColor = defaultFooterColor
val textColor = if (ColorUtil.isColorLight(defaultFooterColor))
MaterialValueHelper.getPrimaryTextColor(context, true)
else
MaterialValueHelper.getPrimaryTextColor(context, false)
setColors(backgroundColor, textColor)
}
})
/*SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(activity!!) .checkIgnoreMediaStore(activity!!)
.generatePalette(activity).build().dontAnimate() .generatePalette(activity).build().dontAnimate()
.into(object : RetroMusicColoredTarget(playerImage) { .into(object : RetroMusicColoredTarget(playerImage) {
@ -155,13 +186,13 @@ class ColorFragment : AbsPlayerFragment() {
override fun onResourceReady(resource: BitmapPaletteWrapper, override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) { glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation) super.onResourceReady(resource, glideAnimation)
/* MediaNotificationProcessor processor = new MediaNotificationProcessor(getContext(), *//* MediaNotificationProcessor processor = new MediaNotificationProcessor(getContext(),
getContext()); getContext());
Palette.Builder builder = MediaNotificationProcessor Palette.Builder builder = MediaNotificationProcessor
.generatePalette(resource.getBitmap()); .generatePalette(resource.getBitmap());
int backgroundColor = processor.getBackgroundColor(builder); int backgroundColor = processor.getBackgroundColor(builder);
int textColor = processor.getTextColor(builder);*/ int textColor = processor.getTextColor(builder);*//*
val palette = resource.palette val palette = resource.palette
val swatch = RetroColorUtil.getSwatch(palette) val swatch = RetroColorUtil.getSwatch(palette)
@ -171,7 +202,7 @@ class ColorFragment : AbsPlayerFragment() {
setColors(backgroundColor, textColor) setColors(backgroundColor, textColor)
} }
}) })*/
} }
private fun setColors(backgroundColor: Int, textColor: Int) { private fun setColors(backgroundColor: Int, textColor: Int) {

View File

@ -3,9 +3,11 @@ package code.name.monkey.retromusic.util;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import com.bumptech.glide.signature.StringSignature; import com.bumptech.glide.signature.ObjectKey;
import androidx.annotation.NonNull;
import code.name.monkey.retromusic.App;
public class ArtistSignatureUtil { public class ArtistSignatureUtil {
@ -19,9 +21,9 @@ public class ArtistSignatureUtil {
mPreferences = context.getSharedPreferences(ARTIST_SIGNATURE_PREFS, Context.MODE_PRIVATE); mPreferences = context.getSharedPreferences(ARTIST_SIGNATURE_PREFS, Context.MODE_PRIVATE);
} }
public static ArtistSignatureUtil getInstance(@NonNull final Context context) { public static ArtistSignatureUtil getInstance() {
if (sInstance == null) { if (sInstance == null) {
sInstance = new ArtistSignatureUtil(context.getApplicationContext()); sInstance = new ArtistSignatureUtil(App.Companion.getContext());
} }
return sInstance; return sInstance;
} }
@ -35,7 +37,7 @@ public class ArtistSignatureUtil {
return mPreferences.getLong(artistName, 0); return mPreferences.getLong(artistName, 0);
} }
public StringSignature getArtistSignature(String artistName) { public ObjectKey getArtistSignature(String artistName) {
return new StringSignature(String.valueOf(getArtistSignatureRaw(artistName))); return new ObjectKey(String.valueOf(getArtistSignatureRaw(artistName)));
} }
} }

View File

@ -1,137 +0,0 @@
package code.name.monkey.retromusic.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Locale;
import androidx.annotation.NonNull;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.model.Artist;
public class CustomArtistImageUtil {
private static final String CUSTOM_ARTIST_IMAGE_PREFS = "custom_artist_image";
private static final String FOLDER_NAME = "/custom_artist_images/";
private static CustomArtistImageUtil sInstance;
private final SharedPreferences mPreferences;
private CustomArtistImageUtil(@NonNull final Context context) {
mPreferences = context.getApplicationContext().getSharedPreferences(CUSTOM_ARTIST_IMAGE_PREFS, Context.MODE_PRIVATE);
}
public static CustomArtistImageUtil getInstance(@NonNull final Context context) {
if (sInstance == null) {
sInstance = new CustomArtistImageUtil(context.getApplicationContext());
}
return sInstance;
}
private static String getFileName(Artist artist) {
String artistName = artist.getName();
if (artistName == null)
artistName = "";
// replace everything that is not a letter or a number with _
artistName = artistName.replaceAll("[^a-zA-Z0-9]", "_");
return String.format(Locale.US, "#%d#%s.jpeg", artist.getId(), artistName);
}
public static File getFile(Artist artist) {
File dir = new File(App.Companion.getInstance().getFilesDir(), FOLDER_NAME);
return new File(dir, getFileName(artist));
}
public void setCustomArtistImage(final Artist artist, Uri uri) {
Glide.with(App.Companion.getInstance())
.load(uri)
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
e.printStackTrace();
Toast.makeText(App.Companion.getInstance(), e.toString(), Toast.LENGTH_LONG).show();
}
@SuppressLint("StaticFieldLeak")
@Override
public void onResourceReady(final Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
new AsyncTask<Void, Void, Void>() {
@SuppressLint("ApplySharedPref")
@Override
protected Void doInBackground(Void... params) {
File dir = new File(App.Companion.getInstance().getFilesDir(), FOLDER_NAME);
if (!dir.exists()) {
if (!dir.mkdirs()) { // create the folder
return null;
}
}
File file = new File(dir, getFileName(artist));
boolean succesful = false;
try {
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
succesful = ImageUtil.resizeBitmap(resource, 2048).compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();
} catch (IOException e) {
Toast.makeText(App.Companion.getInstance(), e.toString(), Toast.LENGTH_LONG).show();
}
if (succesful) {
mPreferences.edit().putBoolean(getFileName(artist), true).commit();
ArtistSignatureUtil.getInstance(App.Companion.getInstance()).updateArtistSignature(artist.getName());
App.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload
}
return null;
}
}.execute();
}
});
}
@SuppressLint("StaticFieldLeak")
public void resetCustomArtistImage(final Artist artist) {
new AsyncTask<Void, Void, Void>() {
@SuppressLint("ApplySharedPref")
@Override
protected Void doInBackground(Void... params) {
mPreferences.edit().putBoolean(getFileName(artist), false).commit();
ArtistSignatureUtil.getInstance(App.Companion.getInstance()).updateArtistSignature(artist.getName());
App.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload
File file = getFile(artist);
if (!file.exists()) {
return null;
} else {
file.delete();
}
return null;
}
}.execute();
}
// shared prefs saves us many IO operations
public boolean hasCustomArtistImage(Artist artist) {
return mPreferences.getBoolean(getFileName(artist), false);
}
}

View File

@ -0,0 +1,125 @@
package code.name.monkey.retromusic.util
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.AsyncTask
import android.widget.Toast
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.model.Artist
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.transition.Transition
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.*
class CustomArtistImageUtil private constructor(context: Context) {
private val mPreferences: SharedPreferences
init {
mPreferences = context.applicationContext.getSharedPreferences(CUSTOM_ARTIST_IMAGE_PREFS, Context.MODE_PRIVATE)
}
fun setCustomArtistImage(artist: Artist, uri: Uri) {
GlideApp.with(App.context)
.asBitmap()
.load(uri)
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
)
.into(object : RetroSimpleTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
object : AsyncTask<Void, Void, Void>() {
@SuppressLint("ApplySharedPref")
override fun doInBackground(vararg params: Void): Void? {
val dir = File(App.context.getFilesDir(), FOLDER_NAME)
if (!dir.exists()) {
if (!dir.mkdirs()) { // create the folder
return null
}
}
val file = File(dir, getFileName(artist))
var succesful = false
try {
val os = BufferedOutputStream(FileOutputStream(file))
succesful = ImageUtil.resizeBitmap(resource, 2048).compress(Bitmap.CompressFormat.JPEG, 100, os)
os.close()
} catch (e: IOException) {
Toast.makeText(App.context, e.toString(), Toast.LENGTH_LONG).show()
}
if (succesful) {
mPreferences.edit().putBoolean(getFileName(artist), true).commit()
ArtistSignatureUtil.getInstance().updateArtistSignature(artist.name)
App.context.getContentResolver().notifyChange(Uri.parse("content://media"), null) // trigger media store changed to force artist image reload
}
return null
}
}.execute()
}
})
}
fun resetCustomArtistImage(artist: Artist) {
object : AsyncTask<Void, Void, Void>() {
@SuppressLint("ApplySharedPref")
override fun doInBackground(vararg params: Void): Void? {
mPreferences.edit().putBoolean(getFileName(artist), false).commit()
ArtistSignatureUtil.getInstance().updateArtistSignature(artist.name)
App.context.contentResolver.notifyChange(Uri.parse("content://media"), null) // trigger media store changed to force artist image reload
val file = getFile(artist)
if (!file.exists()) {
return null
} else {
file.delete()
}
return null
}
}.execute()
}
// shared prefs saves us many IO operations
fun hasCustomArtistImage(artist: Artist): Boolean {
return mPreferences.getBoolean(getFileName(artist), false)
}
companion object {
private const val CUSTOM_ARTIST_IMAGE_PREFS = "custom_artist_image"
private const val FOLDER_NAME = "/custom_artist_images/"
private var sInstance: CustomArtistImageUtil? = null
fun getInstance(context: Context): CustomArtistImageUtil {
if (sInstance == null) {
sInstance = CustomArtistImageUtil(context.applicationContext)
}
return sInstance!!
}
fun getFileName(artist: Artist): String {
var artistName = artist.name
// replace everything that is not a letter or a number with _
artistName = artistName.replace("[^a-zA-Z0-9]".toRegex(), "_")
return String.format(Locale.US, "#%d#%s.jpeg", artist.id, artistName)
}
@JvmStatic
fun getFile(artist: Artist): File {
val dir = File(App.context.getFilesDir(), FOLDER_NAME)
return File(dir, getFileName(artist))
}
}
}

View File

@ -33,10 +33,10 @@ public class NetworkImageView extends CircularImageView {
} }
public void setImageUrl(Context context, String imageUrl) { public void setImageUrl(Context context, String imageUrl) {
Glide.with(context).load(imageUrl).asBitmap() /*Glide.with(context).load(imageUrl).asBitmap()
.error(R.drawable.ic_person_flat) .error(R.drawable.ic_person_flat)
.placeholder(R.drawable.ic_person_flat) .placeholder(R.drawable.ic_person_flat)
.into(this); .into(this);*/
} }
private void init(Context context, AttributeSet attributeSet) { private void init(Context context, AttributeSet attributeSet) {