diff --git a/app/src/main/java/code/name/monkey/retromusic/deezer/DeezerApiService.kt b/app/src/main/java/code/name/monkey/retromusic/deezer/DeezerApiService.kt index ff9b9a8d..d8f46796 100644 --- a/app/src/main/java/code/name/monkey/retromusic/deezer/DeezerApiService.kt +++ b/app/src/main/java/code/name/monkey/retromusic/deezer/DeezerApiService.kt @@ -11,7 +11,7 @@ import retrofit2.create import retrofit2.http.GET import retrofit2.http.Query import java.io.File -import java.util.* +import java.util.Locale private const val BASE_QUERY_ARTIST = "search/artist" private const val BASE_URL = "https://api.deezer.com/" @@ -20,30 +20,30 @@ interface DeezerApiService { @GET("$BASE_QUERY_ARTIST&limit=1") fun getArtistImage( - @Query("q") artistName: String + @Query("q") artistName: String ): Call companion object { operator fun invoke( - client: okhttp3.Call.Factory + client: okhttp3.Call.Factory ): DeezerApiService { return Retrofit.Builder() - .baseUrl(BASE_URL) - .callFactory(client) - .addConverterFactory(GsonConverterFactory.create()) - .build() - .create() + .baseUrl(BASE_URL) + .callFactory(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create() } fun createDefaultOkHttpClient( - context: Context + context: Context ): OkHttpClient.Builder = - OkHttpClient.Builder() - .cache(createDefaultCache(context)) - .addInterceptor(createCacheControlInterceptor()) + OkHttpClient.Builder() + .cache(createDefaultCache(context)) + .addInterceptor(createCacheControlInterceptor()) private fun createDefaultCache( - context: Context + context: Context ): Cache? { val cacheDir = File(context.applicationContext.cacheDir.absolutePath, "/okhttp-deezer/") if (cacheDir.mkdir() or cacheDir.isDirectory) { @@ -55,12 +55,13 @@ interface DeezerApiService { private fun createCacheControlInterceptor(): Interceptor { return Interceptor { chain -> val modifiedRequest = chain.request().newBuilder() - .addHeader("Cache-Control", - String.format( - Locale.getDefault(), - "max-age=31536000, max-stale=31536000" - ) - ).build() + .addHeader( + "Cache-Control", + String.format( + Locale.getDefault(), + "max-age=31536000, max-stale=31536000" + ) + ).build() chain.proceed(modifiedRequest) } } diff --git a/app/src/main/java/code/name/monkey/retromusic/deezer/DeezerResponse.kt b/app/src/main/java/code/name/monkey/retromusic/deezer/DeezerResponse.kt index 4a076112..b029ab53 100644 --- a/app/src/main/java/code/name/monkey/retromusic/deezer/DeezerResponse.kt +++ b/app/src/main/java/code/name/monkey/retromusic/deezer/DeezerResponse.kt @@ -3,29 +3,29 @@ package code.name.monkey.retromusic.deezer import com.google.gson.annotations.SerializedName data class Data( - val id: String, - val link: String, - val name: String, - @SerializedName("nb_album") - val nbAlbum: Int, - @SerializedName("nb_fan") - val nbFan: Int, - val picture: String, - @SerializedName("picture_big") - val pictureBig: String, - @SerializedName("picture_medium") - val pictureMedium: String, - @SerializedName("picture_small") - val pictureSmall: String, - @SerializedName("picture_xl") - val pictureXl: String, - val radio: Boolean, - val tracklist: String, - val type: String + val id: String, + val link: String, + val name: String, + @SerializedName("nb_album") + val nbAlbum: Int, + @SerializedName("nb_fan") + val nbFan: Int, + val picture: String, + @SerializedName("picture_big") + val pictureBig: String, + @SerializedName("picture_medium") + val pictureMedium: String, + @SerializedName("picture_small") + val pictureSmall: String, + @SerializedName("picture_xl") + val pictureXl: String, + val radio: Boolean, + val tracklist: String, + val type: String ) data class DeezerResponse( - val data: List, - val next: String, - val total: Int + val data: List, + val next: String, + val total: Int ) \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/ArtistGlideRequest.java b/app/src/main/java/code/name/monkey/retromusic/glide/ArtistGlideRequest.java index e339cf1d..cc3e28fa 100644 --- a/app/src/main/java/code/name/monkey/retromusic/glide/ArtistGlideRequest.java +++ b/app/src/main/java/code/name/monkey/retromusic/glide/ArtistGlideRequest.java @@ -16,9 +16,15 @@ package code.name.monkey.retromusic.glide; import android.content.Context; import android.graphics.Bitmap; - 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.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.BitmapRequestBuilder; import com.bumptech.glide.DrawableRequestBuilder; import com.bumptech.glide.DrawableTypeRequest; @@ -29,68 +35,32 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.resource.drawable.GlideDrawable; import com.bumptech.glide.request.target.Target; -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; - public class ArtistGlideRequest { - public static final int DEFAULT_ANIMATION = android.R.anim.fade_in; - private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.SOURCE; - private static final int DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art; - - public static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist, boolean noCustomImage, boolean forceDownload) { - boolean hasCustomImage = CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist); - if (noCustomImage || !hasCustomImage) { - return requestManager.load(new ArtistImage(artist.getName(), forceDownload)); - } else { - return requestManager.load(CustomArtistImageUtil.getFile(artist)); - } - } - - public static Key createSignature(Artist artist) { - return ArtistSignatureUtil.getInstance(App.Companion.getContext()).getArtistSignature(artist.getName()); - } - public static class Builder { - final RequestManager requestManager; + final Artist artist; - boolean noCustomImage; + boolean forceDownload; + boolean noCustomImage; + + final RequestManager requestManager; + + public static Builder from(@NonNull RequestManager requestManager, Artist artist) { + return new Builder(requestManager, artist); + } + private Builder(@NonNull RequestManager requestManager, Artist artist) { this.requestManager = requestManager; this.artist = artist; } - public static Builder from(@NonNull RequestManager requestManager, Artist artist) { - return new Builder(requestManager, artist); - } - - public PaletteBuilder generatePalette(Context context) { - return new PaletteBuilder(this, context); - } - public BitmapBuilder asBitmap() { return new BitmapBuilder(this); } - public Builder noCustomImage(boolean noCustomImage) { - this.noCustomImage = noCustomImage; - return this; - } - - public Builder forceDownload(boolean forceDownload) { - this.forceDownload = forceDownload; - return this; - } - public DrawableRequestBuilder build() { //noinspection unchecked return createBaseRequest(requestManager, artist, noCustomImage, forceDownload) @@ -101,9 +71,24 @@ public class ArtistGlideRequest { .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .signature(createSignature(artist)); } + + public Builder forceDownload(boolean forceDownload) { + this.forceDownload = forceDownload; + return this; + } + + public PaletteBuilder generatePalette(Context context) { + return new PaletteBuilder(this, context); + } + + public Builder noCustomImage(boolean noCustomImage) { + this.noCustomImage = noCustomImage; + return this; + } } public static class BitmapBuilder { + private final Builder builder; public BitmapBuilder(Builder builder) { @@ -112,7 +97,8 @@ public class ArtistGlideRequest { public BitmapRequestBuilder build() { //noinspection unchecked - return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload) + return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, + builder.forceDownload) .asBitmap() .diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY) .error(DEFAULT_ERROR_IMAGE) @@ -124,7 +110,9 @@ public class ArtistGlideRequest { } public static class PaletteBuilder { + final Context context; + private final Builder builder; public PaletteBuilder(Builder builder, Context context) { @@ -134,7 +122,8 @@ public class ArtistGlideRequest { public BitmapRequestBuilder build() { //noinspection unchecked - return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload) + return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, + builder.forceDownload) .asBitmap() .transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class) .diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY) @@ -145,6 +134,30 @@ public class ArtistGlideRequest { .signature(createSignature(builder.artist)); } } + + private static final int DEFAULT_ANIMATION = android.R.anim.fade_in; + + private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.SOURCE; + + private static final int DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art; + + @NonNull + public static Key createSignature(@NonNull Artist artist) { + return ArtistSignatureUtil.getInstance(App.Companion.getContext()).getArtistSignature(artist.getName()); + } + + @NonNull + private static DrawableTypeRequest createBaseRequest(@NonNull RequestManager requestManager, + @NonNull Artist artist, + boolean noCustomImage, boolean forceDownload) { + boolean hasCustomImage = CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()) + .hasCustomArtistImage(artist); + if (noCustomImage || !hasCustomImage) { + return requestManager.load(new ArtistImage(artist.getName())); + } else { + return requestManager.load(CustomArtistImageUtil.getFile(artist)); + } + } } /** diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt b/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt index af811112..6bf62d7e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt @@ -32,16 +32,15 @@ import java.io.IOException import java.io.InputStream import java.util.concurrent.TimeUnit - -class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean) +class ArtistImage(val artistName: String) class ArtistImageFetcher( - private val context: Context, - private val deezerApiService: DeezerApiService, - val model: ArtistImage, - val urlLoader: ModelLoader, - val width: Int, - val height: Int + private val context: Context, + private val deezerApiService: DeezerApiService, + val model: ArtistImage, + val urlLoader: ModelLoader, + val width: Int, + val height: Int ) : DataFetcher { private var urlFetcher: DataFetcher? = null @@ -96,9 +95,9 @@ class ArtistImageFetcher( } class ArtistImageLoader( - val context: Context, - private val deezerApiService: DeezerApiService, - private val urlLoader: ModelLoader + val context: Context, + private val deezerApiService: DeezerApiService, + private val urlLoader: ModelLoader ) : StreamModelLoader { override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher { @@ -107,22 +106,27 @@ class ArtistImageLoader( } class Factory( - val context: Context + val context: Context ) : ModelLoaderFactory { + private var deezerApiService: DeezerApiService private var okHttpFactory: OkHttpUrlLoader.Factory init { - okHttpFactory = OkHttpUrlLoader.Factory(OkHttpClient.Builder() + okHttpFactory = OkHttpUrlLoader.Factory( + OkHttpClient.Builder() .connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS) .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS) .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS) - .build()) - deezerApiService = DeezerApiService.invoke(DeezerApiService.createDefaultOkHttpClient(context) + .build() + ) + deezerApiService = DeezerApiService.invoke( + DeezerApiService.createDefaultOkHttpClient(context) .connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS) .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS) .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS) - .build()) + .build() + ) } override fun build(context: Context?, factories: GenericLoaderFactory?): ModelLoader { @@ -137,5 +141,4 @@ class Factory( // we need these very low values to make sure our artist image loading calls doesn't block the image loading queue private const val TIMEOUT: Long = 700 } - }