converted to Glide 4

This commit is contained in:
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);
}
override fun onLowMemory() {
super.onLowMemory()
Glide.with(this).onLowMemory()
}
override fun onTerminate() {
super.onTerminate()
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.R
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.ui.activities.MainActivity
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.transition.Transition
class AppWidgetBig : BaseAppWidget() {
private var target: Target<Bitmap>? = null // for cancellation
@ -91,19 +92,19 @@ class AppWidgetBig : BaseAppWidget() {
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
GlideApp.with(appContext).clear(target)
}
target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.checkIgnoreMediaStore(appContext)
.asBitmap().build()
.into(object : SimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
override fun onResourceReady(resource: Bitmap,
glideAnimation: GlideAnimation<in Bitmap>) {
target = GlideApp.with(appContext)
.asBitmap()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
update(resource)
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
override fun onLoadFailed(errorDrawable: Drawable?) {
update(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.R
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.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
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.transition.Transition
class AppWidgetCard : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -36,15 +36,9 @@ class AppWidgetCard : BaseAppWidget() {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_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))
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_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)
pushUpdate(context, appWidgetIds, appWidgetView)
@ -92,26 +86,26 @@ class AppWidgetCard : BaseAppWidget() {
if (cardRadius == 0f) {
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
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
GlideApp.with(appContext).clear(target)
}
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
GlideApp.with(appContext)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
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.R
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.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
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.transition.Transition
class AppWidgetClassic : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -77,21 +78,21 @@ class AppWidgetClassic : BaseAppWidget() {
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
GlideApp.with(appContext).clear(target)
}
target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.checkIgnoreMediaStore(appContext)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
GlideApp.with(appContext)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))))
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed( errorDrawable)
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.R
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.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
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.transition.Transition
class AppWidgetSmall : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -82,22 +82,22 @@ class AppWidgetSmall : BaseAppWidget() {
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
GlideApp.with(appContext).clear(target);
}
target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.checkIgnoreMediaStore(appContext)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
target = GlideApp.with(appContext)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))))
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true))
}

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
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.os.Build
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RSRuntimeException
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import android.renderscript.*
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.resource.bitmap.BitmapTransformation
import code.name.monkey.retromusic.helper.StackBlur
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.util.ImageUtil
import java.security.MessageDigest
class BlurTransformation : BitmapTransformation {
private var context: Context? = null
private var blurRadius: Float = 0.toFloat()
private var sampling: Int = 0
private constructor(builder: Builder) : super(builder.context) {
private constructor(builder: Builder) : super() {
init(builder)
}
private constructor(builder: Builder, bitmapPool: BitmapPool) : super(bitmapPool) {
private constructor(builder: Builder, bitmapPool: BitmapPool) : super() {
init(builder)
}
@ -41,7 +34,6 @@ class BlurTransformation : BitmapTransformation {
this.sampling = builder.sampling
}
override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? {
val sampling: Int
if (this.sampling == 0) {
@ -93,14 +85,22 @@ class BlurTransformation : BitmapTransformation {
return StackBlur.blur(out, blurRadius)
}
override fun getId(): String {
return "BlurTransformation(radius=$blurRadius, sampling=$sampling)"
override fun equals(o: Any?): Boolean {
return o is BlurTransformation
}
class Builder(internal val context: Context) {
private var bitmapPool: BitmapPool? = null
internal var blurRadius = DEFAULT_BLUR_RADIUS
internal var sampling: Int = 0
override fun hashCode(): Int {
return ID.hashCode()
}
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.
@ -137,6 +137,8 @@ class BlurTransformation : BitmapTransformation {
}
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.widget.ImageView
import com.bumptech.glide.request.animation.GlideAnimation
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil.getColor
import code.name.monkey.retromusic.util.RetroColorUtil.getDominantColor
import com.bumptech.glide.request.transition.Transition
abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) {
@ -23,13 +20,13 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
protected val albumArtistFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor)
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
onColorReady(defaultFooterColor)
}
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
glideAnimation: Transition<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation)
val defaultColor = defaultFooterColor

View file

@ -1,25 +1,29 @@
package code.name.monkey.retromusic.glide
import android.content.Context
import com.bumptech.glide.Glide
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.module.GlideModule
import android.graphics.Bitmap
import code.name.monkey.retromusic.glide.artistimage.ArtistImage
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
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
class RetroMusicGlideModule : GlideModule {
override fun applyOptions(context: Context, builder: GlideBuilder) {
@GlideModule
class RetroMusicGlideModule : AppGlideModule() {
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) {
glide.register(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory())
glide.register(ArtistImage::class.java, InputStream::class.java, ArtistImageLoader.Factory(context))
override fun isManifestParsingEnabled(): Boolean {
return false
}
}

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
import android.content.Context
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 android.text.TextUtils
import code.name.monkey.retromusic.rest.LastFMRestClient
import code.name.monkey.retromusic.rest.model.LastFmArtist
import code.name.monkey.retromusic.util.LastFMUtil
import code.name.monkey.retromusic.util.MusicUtil
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 retrofit2.Response
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> {
class ArtistImageFetcher(private val context: Context, private val lastFMRestClient: LastFMRestClient, private val okHttp: OkHttpClient, private val model: ArtistImage, width: Int, height: Int) : DataFetcher<InputStream> {
@Volatile
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
return model.artistName
override fun getDataClass(): Class<InputStream> {
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) {
throw IOException("Request failed with code: " + response.code())
override fun getDataSource(): DataSource {
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 (isCancelled) return null
val url = GlideUrl(LastFMUtil.getLargestArtistImageUrl(lastFmArtist!!.artist.image))
urlFetcher = urlLoader.getResourceFetcher(url, width, height)
return urlFetcher!!.loadData(priority)
if (lastFmArtist == null || lastFmArtist.artist == null || lastFmArtist.artist.image == null) {
callback.onLoadFailed(Exception("No artist image url found"))
return
}
return null
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) {
callback.onLoadFailed(e)
}
}
override fun cleanup() {
if (urlFetcher != null) {
urlFetcher!!.cleanup()
if (streamFetcher != null) {
streamFetcher!!.cleanup()
}
}
override fun cancel() {
isCancelled = true
if (urlFetcher != null) {
urlFetcher!!.cancel()
if (call != null) {
call!!.cancel()
}
if (streamFetcher != null) {
streamFetcher!!.cancel()
}
}
companion object {
val TAG = ArtistImageFetcher::class.java.simpleName
val TAG: String = ArtistImageFetcher::class.java.simpleName
}
}

View file

@ -1,47 +1,45 @@
package code.name.monkey.retromusic.glide.artistimage
import android.content.Context
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.GenericLoaderFactory
import com.bumptech.glide.load.model.GlideUrl
import code.name.monkey.retromusic.rest.LastFMRestClient
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.stream.StreamModelLoader
import code.name.monkey.retromusic.rest.LastFMRestClient
import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.bumptech.glide.signature.ObjectKey
import okhttp3.OkHttpClient
import java.io.InputStream
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 getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
return ArtistImageFetcher(context, lastFMClient, model, urlLoader, width, height)
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))
}
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)
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.build())
private val okHttpFactory: OkHttpUrlLoader.Factory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
private val okHttp: OkHttpClient = OkHttpClient.Builder()
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(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() {
okHttpFactory.teardown()
}
override fun teardown() {}
}
companion object {
@ -49,4 +47,3 @@ class ArtistImageLoader(private val context: Context, private val lastFMClient:
private const val TIMEOUT = 500
}
}

View file

@ -2,41 +2,48 @@ package code.name.monkey.retromusic.glide.audiocover
import android.media.MediaMetadataRetriever
import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
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.tag.TagException
import java.io.*
/**
* @author Karim Abou Zeid (kabouzeid)
*/
class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<InputStream> {
private var stream: FileInputStream? = null
override fun getId(): String {
// makes sure we never ever return null here
return model.filePath
}
@Throws(Exception::class)
override fun loadData(priority: Priority): InputStream? {
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
val retriever = MediaMetadataRetriever()
val data: InputStream?
try {
retriever.setDataSource(model.filePath)
val picture = retriever.embeddedPicture
return if (picture != null) {
ByteArrayInputStream(picture)
if (picture != null) {
data = ByteArrayInputStream(picture)
} else {
fallback(model.filePath)
data = fallback(model.filePath)
}
callback.onDataReady(data)
} catch (e: FileNotFoundException) {
callback.onLoadFailed(e)
} finally {
retriever.release()
}
}
override fun getDataClass(): Class<InputStream> {
return InputStream::class.java
}
override fun getDataSource(): DataSource {
return DataSource.LOCAL
}
@Throws(FileNotFoundException::class)
private fun fallback(path: String): InputStream? {
// Method 1: use embedded high resolution album art if there is any
try {
val mp3File = MP3File(path)
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
} catch (ignored: ReadOnlyFileException) {
} catch (ignored: InvalidAudioFrameException) {
} catch (ignored: TagException) {
} catch (ignored: IOException) {
} catch (ignored: Exception) {
}
// Method 2: look for album art in external files
@ -82,6 +86,7 @@ class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<Inp
}
companion object {
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
import android.content.Context
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.GenericLoaderFactory
import com.bumptech.glide.load.Options
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.stream.StreamModelLoader
import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.bumptech.glide.signature.ObjectKey
import java.io.InputStream
class AudioFileCoverLoader : StreamModelLoader<AudioFileCover> {
override fun getResourceFetcher(model: AudioFileCover, width: Int, height: Int): DataFetcher<InputStream> {
return AudioFileCoverFetcher(model)
class AudioFileCoverLoader : ModelLoader<AudioFileCover, InputStream> {
override fun buildLoadData(model: AudioFileCover, width: Int, height: Int,
options: Options): LoadData<InputStream>? {
return LoadData(ObjectKey(model.filePath), AudioFileCoverFetcher(model))
}
override fun handles(model: AudioFileCover): Boolean {
return true
}
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()
}

View file

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

View file

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

View file

@ -1,25 +1,16 @@
package code.name.monkey.retromusic.glide.palette
import android.content.Context
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 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> {
constructor(context: Context) : this(Glide.get(context).bitmapPool) {}
override fun transcode(bitmapResource: Resource<Bitmap>): Resource<BitmapPaletteWrapper> {
class BitmapPaletteTranscoder : ResourceTranscoder<Bitmap, BitmapPaletteWrapper> {
override fun transcode(bitmapResource: Resource<Bitmap>, options: Options): Resource<BitmapPaletteWrapper>? {
val bitmap = bitmapResource.get()
val bitmapPaletteWrapper = BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap)!!)
return BitmapPaletteResource(bitmapPaletteWrapper, bitmapPool)
}
override fun getId(): String {
return "BitmapPaletteTranscoder.code.name.monkey.retromusic.glide.palette"
return BitmapPaletteResource(bitmapPaletteWrapper)
}
}

View file

@ -35,10 +35,8 @@ import android.telephony.TelephonyManager;
import android.util.Log;
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.transition.Transition;
import java.lang.ref.WeakReference;
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.AppWidgetText;
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.StopWatch;
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
@ -686,24 +687,26 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
if (PreferenceUtil.getInstance().albumArtOnLockscreen()) {
final Point screenSize = RetroUtil.getScreenSize(MusicService.this);
final BitmapRequestBuilder<?, Bitmap> request = SongGlideRequest.Builder.Companion.from(Glide.with(MusicService.this), song)
.checkIgnoreMediaStore(MusicService.this)
.asBitmap().build();
GlideRequest request = GlideApp.with(MusicService.this)
.asBitmap()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song);
if (PreferenceUtil.getInstance().blurredAlbumArt()) {
request.transform(new BlurTransformation.Builder(MusicService.this).build());
}
runOnUiThread(new Runnable() {
@Override
public void run() {
request.into(new SimpleTarget<Bitmap>(screenSize.x, screenSize.y) {
request.into(new RetroSimpleTarget<Bitmap>(screenSize.x, screenSize.y) {
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
mediaSession.setMetadata(metaData.build());
}
@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));
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_TOGGLE_PAUSE
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.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil
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.transition.Transition
class PlayingNotificationImpl : PlayingNotification() {
@ -92,15 +92,16 @@ class PlayingNotificationImpl : PlayingNotification() {
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
GlideApp.with(service).clear(target);
}
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize,
target = GlideApp.with(service)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize,
bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
update(resource.bitmap,
if (PreferenceUtil.getInstance().isDominantColor)
RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT)
@ -108,8 +109,8 @@ class PlayingNotificationImpl : PlayingNotification() {
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT))
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
update(null, Color.WHITE)
}

View file

@ -10,24 +10,24 @@ import android.graphics.drawable.Drawable
import android.os.Build
import android.text.Html
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_REWIND
import code.name.monkey.retromusic.Constants.ACTION_SKIP
import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE
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.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil
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.transition.Transition
class PlayingNotificationImpl24 : PlayingNotification() {
private var target: Target<BitmapPaletteWrapper>? = null
@Synchronized
override fun update() {
stopped = false
@ -54,18 +54,23 @@ class PlayingNotificationImpl24 : PlayingNotification() {
val bigNotificationImageSize = service.resources
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread {
SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
if (target != null) {
GlideApp.with(service).clear(target);
}
target = GlideApp.with(service)
.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 {
PreferenceUtil.getInstance().isDominantColor -> RetroColorUtil.getDominantColor(resource.bitmap, 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)
}
@ -111,7 +116,7 @@ class PlayingNotificationImpl24 : PlayingNotification() {
.addAction(closeAction)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setStyle(MediaStyle()
builder.setStyle(androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(service.mediaSession.sessionToken)
.setShowActionsInCompactView(0, 1, 2, 3, 4))
.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_TOGGLE_PAUSE
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.model.Song
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.createBitmap
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.transition.Transition
/**
* @author Hemanth S (h4h13).
@ -89,24 +89,21 @@ class PlayingNotificationOreo : PlayingNotification() {
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
GlideApp.with(service).clear(target);
}
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize,
bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
val mediaNotificationProcessor = MediaNotificationProcessor(
service, service) { i, _ -> update(resource.bitmap, i) }
target = GlideApp.with(service)
.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>?) {
val mediaNotificationProcessor = MediaNotificationProcessor(service, service) { i, _ -> update(resource.bitmap, i) }
mediaNotificationProcessor.processNotification(resource.bitmap)
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
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.dialogs.AddToPlaylistDialog
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
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.PreferenceUtil
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 kotlinx.android.synthetic.main.activity_album.*
import kotlinx.android.synthetic.main.activity_album_content.*
@ -192,7 +190,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
private fun loadMoreFrom(album: Album) {
if (artistImage != null) {
ArtistGlideRequest.Builder.from(Glide.with(this),
/*ArtistGlideRequest.Builder.from(Glide.with(this),
ArtistLoader.getArtist(this, album.artistId).blockingFirst())
.forceDownload(false)
.generatePalette(this).build()
@ -201,7 +199,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
override fun onColorReady(color: Int) {
//setColors(color);
}
})
})*/
}
val albums = ArtistLoader.getArtist(this, album.artistId).blockingFirst().albums
@ -220,14 +218,17 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
}
private fun loadAlbumCover() {
SongGlideRequest.Builder.from(Glide.with(this), album!!.safeGetFirstSong())
.checkIgnoreMediaStore(this)
.generatePalette(this).build()
GlideApp.with(this)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(album!!.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album!!.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) {
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.retromusic.R
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.helper.MusicPlayerRemote
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.song.SimpleSongAdapter
import code.name.monkey.retromusic.util.*
import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.activity_artist_content.*
import kotlinx.android.synthetic.main.activity_artist_details.*
@ -181,7 +181,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
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) {
reload()
@ -272,16 +272,18 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
private fun loadArtistImage() {
ArtistGlideRequest.Builder.from(Glide.with(this), artist!!)
.forceDownload(forceDownload)
.generatePalette(this).build()
GlideApp.with(this)
.asBitmapPalette()
.load(RetroGlideExtension.getArtistModel(artist!!, forceDownload))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) {
setColors(color)
}
})
forceDownload = false
forceDownload = false;
}
private fun setColors(color: Int) {
@ -331,7 +333,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
R.id.action_reset_artist_image -> {
Toast.makeText(this@ArtistDetailActivity, resources.getString(R.string.updating),
Toast.LENGTH_SHORT).show()
CustomArtistImageUtil.getInstance(this@ArtistDetailActivity).resetCustomArtistImage(artist)
CustomArtistImageUtil.getInstance(this@ArtistDetailActivity).resetCustomArtistImage(artist!!)
forceDownload = true
return true
}

View file

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

View file

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.content.*
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.Handler
import android.preference.PreferenceManager
import android.provider.MediaStore
import android.util.Log
@ -12,13 +11,7 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
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 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.R
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.service.MusicService
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.folders.FoldersFragment
import code.name.monkey.retromusic.ui.fragments.mainactivity.home.BannerHomeFragment
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.MaterialDialog
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_main_drawer_layout.*
import java.util.*
@ -73,16 +63,16 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
getBottomNavigationView()!!.setOnNavigationItemSelectedListener {
getBottomNavigationView().setOnNavigationItemSelectedListener {
PreferenceUtil.getInstance().lastPage = it.itemId
selectedFragment(it.itemId)
true
}
setUpDrawerLayout()
//setUpDrawerLayout()
if (savedInstanceState == null) {
setMusicChooser(PreferenceUtil.getInstance().lastMusicChooser)
selectedFragment(PreferenceUtil.getInstance().lastPage);
} else {
restoreCurrentFragment();
}
@ -130,8 +120,13 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this)
}
private fun setCurrentFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, null).commit()
fun setCurrentFragment(fragment: Fragment, b: Boolean) {
val trans = supportFragmentManager.beginTransaction()
trans.replace(R.id.fragment_container, fragment, null)
if (b) {
trans.addToBackStack(null)
}
trans.commit()
currentFragment = fragment as MainActivityFragmentCallbacks
}
@ -213,12 +208,11 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
if (!hasPermissions()) {
requestPermissions()
}
checkSetUpPro(); // good chance that pro version check was delayed on first start
}
REQUEST_CODE_THEME, APP_USER_INFO_REQUEST -> postRecreate()
PURCHASE_REQUEST -> {
if (resultCode == RESULT_OK) {
checkSetUpPro();
//checkSetUpPro();
}
}
}
@ -226,10 +220,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
}
override fun handleBackPress(): Boolean {
if (drawerLayout.isDrawerOpen(navigationView)) {
drawerLayout.closeDrawers()
return true
}
return super.handleBackPress() || currentFragment.handleBackPress()
}
@ -291,104 +281,20 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
R.id.action_album,
R.id.action_artist,
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 {
if (item.itemId == android.R.id.home) {
if (drawerLayout.isDrawerOpen(navigationView)) {
drawerLayout.closeDrawer(navigationView)
} else {
drawerLayout.openDrawer(navigationView)
}
NavigationUtil.goToSearch(this);
return true
}
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 {
const val APP_INTRO_REQUEST = 2323
const val LIBRARY = 1

View file

@ -5,7 +5,6 @@ import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
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.ToolbarContentTintHelper
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.loaders.AlbumLoader
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.LastFMUtil
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.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.transition.Transition
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
@ -43,20 +45,14 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
get() = R.layout.activity_album_tag_editor
override fun loadImageFromFile(selectedFile: Uri?) {
Glide.with(this@AlbumTagEditorActivity)
GlideApp.with(this).`as`(BitmapPaletteWrapper::class.java)
.load(selectedFile)
.asBitmap()
.transcode(BitmapPaletteTranscoder(this@AlbumTagEditorActivity), BitmapPaletteWrapper::class.java)
.transition(GenericTransitionOptions<BitmapPaletteWrapper>().transition(android.R.anim.fade_in))
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(object : SimpleTarget<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>) {
.skipMemoryCache(true))
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>() {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048)
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
@ -108,7 +104,7 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
override fun loadCurrentImage() {
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
}
@ -138,23 +134,16 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image)
if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) {
Glide.with(this)
GlideApp.with(this)
.`as`(BitmapPaletteWrapper::class.java)
.load(url)
.asBitmap()
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.error(R.drawable.default_album_art)
.into(object : SimpleTarget<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>) {
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.error(R.drawable.default_album_art))
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>() {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
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)))
deleteAlbumArt = false
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.MaterialValueHelper
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.model.Song
import code.name.monkey.retromusic.ui.adapter.CollageSongAdapter.CollageSongViewHolder
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
import com.bumptech.glide.Glide
import java.util.*
/**
@ -28,10 +29,16 @@ class CollageSongAdapter(private val activity: Activity, private val dataSet: Ar
holder.bindSongs()
if (dataSet.size > 8) {
for (i in 0 until dataSet.subList(0, 8).size) {
SongGlideRequest.Builder.from(Glide.with(activity), dataSet[i])
.checkIgnoreMediaStore(activity)
.build()
.into(holder.itemView.findViewById(holder.ids[i]) as ImageView)
GlideApp.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(dataSet[i]))
.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 code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.ArtistGlideRequest
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.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
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.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide
import java.util.*
@ -45,16 +44,23 @@ class SearchAdapter(private val activity: AppCompatActivity, private var dataSet
val album = dataSet!![position] as Album
holder.title!!.text = album.title
holder.text!!.text = album.artistName
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity).build()
GlideApp.with(activity)
.asDrawable()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.into(holder.image!!)
}
ARTIST -> {
val artist = dataSet!![position] as Artist
holder.title!!.text = artist.name
holder.text!!.text = MusicUtil.getArtistInfoString(activity, artist)
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
.build().into(holder.image!!)
GlideApp.with(activity)
.asBitmap()
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.into(holder.image!!)
}
SONG -> {
val song = dataSet!![position] as Song

View file

@ -1,6 +1,7 @@
package code.name.monkey.retromusic.ui.adapter
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
@ -9,19 +10,22 @@ import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.appthemehelper.util.ATHUtil
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.interfaces.CabHolder
import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
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.request.RequestOptions
import com.bumptech.glide.signature.MediaStoreSignature
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.io.File
import java.text.DecimalFormat
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 {
init {
@ -91,13 +95,14 @@ class SongFileAdapter(private val activity: AppCompatActivity, private var dataS
holder.image!!.setImageResource(R.drawable.ic_folder_white_24dp)
} else {
val error = RetroUtil.getTintedVectorDrawable(activity, R.drawable.ic_file_music_white_24dp, iconColor)
Glide.with(activity)
GlideApp.with(activity)
.load(AudioFileCover(file.path))
.transition(GenericTransitionOptions.with<Drawable>(android.R.anim.fade_in))
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.error(error)
.placeholder(error)
.animate(android.R.anim.fade_in)
.signature(MediaStoreSignature("", file.lastModified(), 0))
.signature(MediaStoreSignature("", file.lastModified(), 0)))
.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.MaterialValueHelper
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
@ -127,18 +128,21 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
return
}
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity)
.generatePalette(activity).build()
GlideApp.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
}
override fun onColorReady(color: Int) {
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
import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -9,14 +10,14 @@ import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
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.SongGlideRequest
import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.activities.LyricsActivity
import code.name.monkey.retromusic.ui.fragments.AlbumCoverStyle
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import java.util.*
@ -118,13 +119,21 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
}
private fun loadAlbumCover() {
SongGlideRequest.Builder.from(Glide.with(context), song!!)
.checkIgnoreMediaStore(activity!!)
.generatePalette(activity!!).build()
GlideApp.with(context!!)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.dontAnimate()
.into(object : RetroMusicColoredTarget(albumCover) {
override fun onColorReady(color: Int) {
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
import android.app.Activity
import android.graphics.Bitmap
import android.graphics.Canvas
import android.util.DisplayMetrics
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.core.util.Pair
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.views.MetalRecyclerViewPager
import com.bumptech.glide.Glide
import java.util.*
class AlbumFullWithAdapter(private val activity: Activity,
@ -80,10 +77,12 @@ class AlbumFullWithAdapter(private val activity: Activity,
if (holder.image == null) {
return
}
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity)
.generatePalette(activity).build()
GlideApp.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) {

View file

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

View file

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

View file

@ -1,8 +1,6 @@
package code.name.monkey.retromusic.ui.adapter.playlist
import android.graphics.Bitmap
import android.graphics.PorterDuff
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
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.util.MusicUtil
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.concurrent.ExecutionException
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) {
@ -175,34 +169,6 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL
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) {
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.MaterialValueHelper
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
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.PreferenceUtil
import com.afollestad.materialcab.MaterialCab
import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.util.*
@ -115,19 +115,19 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
if (holder.image == null) {
return
}
SongGlideRequest.Builder.from(Glide.with(activity), song)
.checkIgnoreMediaStore(activity)
.generatePalette(activity).build()
GlideApp.with(activity).asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
}
override fun onColorReady(color: Int) {
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.fragments.player.blur
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.preference.PreferenceManager
import android.view.LayoutInflater
@ -10,13 +11,13 @@ import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_blur.*
class BlurPlayerFragment : AbsPlayerFragment() {
@ -94,23 +95,26 @@ class BlurPlayerFragment : AbsPlayerFragment() {
private fun updateBlur() {
val activity = activity ?: return
val blurAmount = PreferenceManager.getDefaultSharedPreferences(context).getInt("new_blur_amount", 25)
colorBackground!!.clearColorFilter()
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(activity)
.generatePalette(activity)
.build()
GlideApp.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.transition(RetroGlideExtension.getDefaultTransition())
.transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build())
.songOptions(MusicPlayerRemote.currentSong)
.override(320, 480)
.transform(BlurTransformation.Builder(getActivity()!!).blurRadius(blurAmount.toFloat()).build())
.into(object : RetroMusicColoredTarget(colorBackground!!) {
.into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) {
if (color == defaultFooterColor) {
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
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.preference.PreferenceManager
import android.view.LayoutInflater
@ -10,14 +11,14 @@ import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
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.normal.PlayerFragment
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_card_blur_player.*
class CardBlurFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
@ -128,18 +129,27 @@ class CardBlurFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
.getInt("new_blur_amount", 25)
colorBackground!!.clearColorFilter()
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(activity)
.generatePalette(activity)
.build()
.transform(BlurTransformation.Builder(getActivity()!!).blurRadius(blurAmount.toFloat()).build())
.into(object : RetroMusicColoredTarget(colorBackground!!) {
GlideApp.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.transition(RetroGlideExtension.getDefaultTransition())
.transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build())
.songOptions(MusicPlayerRemote.currentSong)
.override(320, 480)
.into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) {
if (color == defaultFooterColor) {
colorBackground!!.setColorFilter(color)
}
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
})
}
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.ToolbarContentTintHelper
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.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.helper.MusicPlayerRemote
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.RetroColorUtil
import code.name.monkey.retromusic.util.ViewUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.transition.Transition
import kotlinx.android.synthetic.main.fragment_color_player.*
class ColorFragment : AbsPlayerFragment() {
@ -130,9 +130,40 @@ class ColorFragment : AbsPlayerFragment() {
}
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!!)
.generatePalette(activity).build().dontAnimate()
.into(object : RetroMusicColoredTarget(playerImage) {
@ -155,13 +186,13 @@ class ColorFragment : AbsPlayerFragment() {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation)
/* MediaNotificationProcessor processor = new MediaNotificationProcessor(getContext(),
*//* MediaNotificationProcessor processor = new MediaNotificationProcessor(getContext(),
getContext());
Palette.Builder builder = MediaNotificationProcessor
.generatePalette(resource.getBitmap());
int backgroundColor = processor.getBackgroundColor(builder);
int textColor = processor.getTextColor(builder);*/
int textColor = processor.getTextColor(builder);*//*
val palette = resource.palette
val swatch = RetroColorUtil.getSwatch(palette)
@ -171,7 +202,7 @@ class ColorFragment : AbsPlayerFragment() {
setColors(backgroundColor, textColor)
}
})
})*/
}
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.content.Context;
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 {
@ -19,9 +21,9 @@ public class ArtistSignatureUtil {
mPreferences = context.getSharedPreferences(ARTIST_SIGNATURE_PREFS, Context.MODE_PRIVATE);
}
public static ArtistSignatureUtil getInstance(@NonNull final Context context) {
public static ArtistSignatureUtil getInstance() {
if (sInstance == null) {
sInstance = new ArtistSignatureUtil(context.getApplicationContext());
sInstance = new ArtistSignatureUtil(App.Companion.getContext());
}
return sInstance;
}
@ -35,7 +37,7 @@ public class ArtistSignatureUtil {
return mPreferences.getLong(artistName, 0);
}
public StringSignature getArtistSignature(String artistName) {
return new StringSignature(String.valueOf(getArtistSignatureRaw(artistName)));
public ObjectKey getArtistSignature(String 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) {
Glide.with(context).load(imageUrl).asBitmap()
/*Glide.with(context).load(imageUrl).asBitmap()
.error(R.drawable.ic_person_flat)
.placeholder(R.drawable.ic_person_flat)
.into(this);
.into(this);*/
}
private void init(Context context, AttributeSet attributeSet) {