From 09373fde8b870afa3bc91da1480319071734ffbb Mon Sep 17 00:00:00 2001 From: Konstantinos Paparas Date: Thu, 2 Jan 2025 18:46:28 +0100 Subject: [PATCH] refactor: migrate from picasso to coil v3 --- app/build.gradle.kts | 3 +- app/proguard-rules.pro | 3 +- app/src/main/AndroidManifest.xml | 2 +- app/src/main/java/com/kelsos/mbrc/App.kt | 2 - .../main/java/com/kelsos/mbrc/BaseActivity.kt | 34 ++++---- .../features/library/AlbumEntryAdapter.kt | 30 +++---- .../features/library/AlbumTracksActivity.kt | 26 ++++--- .../features/library/TrackEntryAdapter.kt | 78 ++++--------------- .../minicontrol/MiniControlFragment.kt | 22 +++--- .../mbrc/features/player/PlayerActivity.kt | 31 +++++--- .../features/widgets/RemoteViewsTarget.kt | 37 +++++++++ .../mbrc/features/widgets/WidgetNormal.kt | 23 ++++-- .../mbrc/features/widgets/WidgetSmall.kt | 23 ++++-- .../networking/protocol/ProtocolActions.kt | 30 +------ .../mediasession/MediaButtonReceiver.kt | 2 + gradle/libs.versions.toml | 9 ++- 16 files changed, 180 insertions(+), 175 deletions(-) create mode 100644 app/src/main/java/com/kelsos/mbrc/features/widgets/RemoteViewsTarget.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a7678b666..e71f2f497 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,6 +12,7 @@ plugins { alias(libs.plugins.kotlinAndroid) alias(libs.plugins.kotlinParcelize) alias(libs.plugins.kapt) + alias(libs.plugins.ksp) alias(libs.plugins.protobuf) alias(libs.plugins.googleServices) apply false alias(libs.plugins.crashlytics) apply false @@ -232,6 +233,7 @@ dependencies { implementation(libs.androidx.legacy.support.v4) implementation(libs.androidx.legacy.support.v13) implementation(libs.bundles.coroutines) + implementation(libs.bundles.coil) implementation(libs.bundles.koin) implementation(libs.google.material) implementation(libs.google.protobuf.javalite) @@ -242,7 +244,6 @@ dependencies { implementation(libs.bundles.jackson) implementation(libs.kotlin.stdlib) implementation(libs.kotlin.reflect) - implementation(libs.squareup.picasso) implementation(libs.rxandroid) implementation(libs.rxjava) implementation(libs.rxkotlin) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 9c54076f3..5f51d87f2 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -90,8 +90,7 @@ -keep class com.raizlabs.android.dbflow.config.GeneratedDatabaseHolder -keep class * extends com.raizlabs.android.dbflow.config.BaseDatabaseDefinition { *; } -## Square Picasso specific rules ## -## https://square.github.io/picasso/ ## +## OKHttp ## -dontwarn com.squareup.okhttp.** diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 621be5304..8e7ec56eb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -146,7 +146,7 @@ + android:exported="true"> diff --git a/app/src/main/java/com/kelsos/mbrc/App.kt b/app/src/main/java/com/kelsos/mbrc/App.kt index 7634e0e33..ddebf3270 100644 --- a/app/src/main/java/com/kelsos/mbrc/App.kt +++ b/app/src/main/java/com/kelsos/mbrc/App.kt @@ -68,6 +68,4 @@ open class App : Application() { ) } } - - internal open fun testMode(): Boolean = false } diff --git a/app/src/main/java/com/kelsos/mbrc/BaseActivity.kt b/app/src/main/java/com/kelsos/mbrc/BaseActivity.kt index bf1ec1344..ebe5de43f 100644 --- a/app/src/main/java/com/kelsos/mbrc/BaseActivity.kt +++ b/app/src/main/java/com/kelsos/mbrc/BaseActivity.kt @@ -42,6 +42,8 @@ import org.koin.android.ext.android.inject import org.koin.androidx.scope.ScopeActivity import timber.log.Timber +private const val NAVIGATION_DELAY = 250L + abstract class BaseActivity : ScopeActivity(), NavigationView.OnNavigationItemSelectedListener { @@ -135,25 +137,27 @@ abstract class BaseActivity : keyCode: Int, event: KeyEvent, ): Boolean { - when (keyCode) { - KeyEvent.KEYCODE_VOLUME_UP -> { - bus.post(MessageEvent(UserInputEventType.KEY_VOLUME_UP)) - return true - } + val result = + when (keyCode) { + KeyEvent.KEYCODE_VOLUME_UP -> { + bus.post(MessageEvent(UserInputEventType.KEY_VOLUME_UP)) + true + } - KeyEvent.KEYCODE_VOLUME_DOWN -> { - bus.post(MessageEvent(UserInputEventType.KEY_VOLUME_DOWN)) - return true - } + KeyEvent.KEYCODE_VOLUME_DOWN -> { + bus.post(MessageEvent(UserInputEventType.KEY_VOLUME_DOWN)) + true + } - else -> return super.onKeyDown(keyCode, event) - } + else -> super.onKeyDown(keyCode, event) + } + return result } override fun onNavigationItemSelected(item: MenuItem): Boolean { val itemId = item.itemId drawer.closeDrawer(GravityCompat.START) - drawer.postDelayed({ navigate(itemId) }, 250) + drawer.postDelayed({ navigate(itemId) }, NAVIGATION_DELAY) return true } @@ -229,7 +233,11 @@ abstract class BaseActivity : if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START) } else { - onBackPressedDispatcher.onBackPressed() + if (this@BaseActivity is PlayerActivity) { + finish() + } else { + onBackPressedDispatcher.onBackPressed() + } } } }, diff --git a/app/src/main/java/com/kelsos/mbrc/features/library/AlbumEntryAdapter.kt b/app/src/main/java/com/kelsos/mbrc/features/library/AlbumEntryAdapter.kt index 457db96f3..9aeb66b13 100644 --- a/app/src/main/java/com/kelsos/mbrc/features/library/AlbumEntryAdapter.kt +++ b/app/src/main/java/com/kelsos/mbrc/features/library/AlbumEntryAdapter.kt @@ -1,7 +1,6 @@ package com.kelsos.mbrc.features.library import android.app.Activity -import android.graphics.Bitmap import android.view.LayoutInflater import android.view.MenuItem import android.view.View @@ -11,10 +10,14 @@ import android.widget.TextView import androidx.appcompat.widget.PopupMenu import androidx.core.view.isGone import androidx.recyclerview.widget.RecyclerView +import coil3.load +import coil3.request.crossfade +import coil3.request.error +import coil3.request.placeholder +import coil3.size.Scale import com.kelsos.mbrc.R import com.kelsos.mbrc.common.ui.SquareImageView import com.raizlabs.android.dbflow.list.FlowCursorList -import com.squareup.picasso.Picasso import java.io.File class AlbumEntryAdapter( @@ -59,19 +62,20 @@ class AlbumEntryAdapter( ) { val data = this.data ?: return val item = data.getItem(position.toLong()) ?: return - val (artist, album, _, _) = item + val (artist, album) = item holder.album.text = if (album.isNullOrBlank()) holder.emptyAlbum else album holder.artist.text = if (artist.isNullOrBlank()) holder.unknownArtist else artist - Picasso - .get() - .load(File(cache, item.key())) - .noFade() - .config(Bitmap.Config.RGB_565) - .error(R.drawable.ic_image_no_cover) - .placeholder(R.drawable.ic_image_no_cover) - .resizeDimen(R.dimen.list_album_size, R.dimen.list_album_size) - .centerCrop() - .into(holder.image) + + holder.image.load(File(cache, item.key())) { + crossfade(false) + placeholder(R.drawable.ic_image_no_cover) + error(R.drawable.ic_image_no_cover) + size( + holder.itemView.context.resources + .getDimensionPixelSize(R.dimen.list_album_size), + ) + scale(Scale.FILL) + } } fun refresh() { diff --git a/app/src/main/java/com/kelsos/mbrc/features/library/AlbumTracksActivity.kt b/app/src/main/java/com/kelsos/mbrc/features/library/AlbumTracksActivity.kt index 59c2d64f1..694ba474f 100644 --- a/app/src/main/java/com/kelsos/mbrc/features/library/AlbumTracksActivity.kt +++ b/app/src/main/java/com/kelsos/mbrc/features/library/AlbumTracksActivity.kt @@ -1,6 +1,5 @@ package com.kelsos.mbrc.features.library -import android.graphics.Bitmap import android.os.Bundle import android.view.MenuItem import android.widget.Button @@ -10,13 +9,17 @@ import androidx.activity.OnBackPressedCallback import androidx.core.os.BundleCompat import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager +import coil3.load +import coil3.request.crossfade +import coil3.request.error +import coil3.request.placeholder +import coil3.size.Scale import com.google.android.material.snackbar.Snackbar import com.kelsos.mbrc.R import com.kelsos.mbrc.common.ui.EmptyRecyclerView import com.kelsos.mbrc.common.utilities.RemoteUtils.sha1 import com.kelsos.mbrc.features.queue.PopupActionHandler import com.raizlabs.android.dbflow.list.FlowCursorList -import com.squareup.picasso.Picasso import org.koin.android.ext.android.inject import org.koin.androidx.scope.ScopeActivity import java.io.File @@ -91,16 +94,15 @@ class AlbumTracksActivity : ) { val image = findViewById(R.id.album_tracks__cover) val cache = File(cacheDir, "covers") - Picasso - .get() - .load(File(cache, sha1("${artist}_$album"))) - .noFade() - .config(Bitmap.Config.RGB_565) - .error(R.drawable.ic_image_no_cover) - .placeholder(R.drawable.ic_image_no_cover) - .resizeDimen(R.dimen.cover_size, R.dimen.cover_size) - .centerCrop() - .into(image) + val coverFile = File(cache, sha1("${artist}_$album")) + + image.load(coverFile) { + crossfade(false) + placeholder(R.drawable.ic_image_no_cover) + error(R.drawable.ic_image_no_cover) + size(resources.getDimensionPixelSize(R.dimen.list_album_size)) + scale(Scale.FILL) + } } override fun onOptionsItemSelected(item: MenuItem): Boolean { diff --git a/app/src/main/java/com/kelsos/mbrc/features/library/TrackEntryAdapter.kt b/app/src/main/java/com/kelsos/mbrc/features/library/TrackEntryAdapter.kt index 6621073ba..fb11f8fdf 100644 --- a/app/src/main/java/com/kelsos/mbrc/features/library/TrackEntryAdapter.kt +++ b/app/src/main/java/com/kelsos/mbrc/features/library/TrackEntryAdapter.kt @@ -1,7 +1,6 @@ package com.kelsos.mbrc.features.library import android.app.Activity -import android.graphics.Bitmap import android.view.LayoutInflater import android.view.MenuItem import android.view.View @@ -12,10 +11,13 @@ import android.widget.TextView import androidx.appcompat.widget.PopupMenu import androidx.core.view.isGone import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.RecyclerView.ViewHolder +import coil3.load +import coil3.request.crossfade +import coil3.request.error +import coil3.request.placeholder +import coil3.size.Scale import com.kelsos.mbrc.R import com.raizlabs.android.dbflow.list.FlowCursorList -import com.squareup.picasso.Picasso import java.io.File class TrackEntryAdapter( @@ -35,31 +37,6 @@ class TrackEntryAdapter( this.listener = listener } - /** - * Called when RecyclerView needs a new [ViewHolder] of the given type to represent - * an item. - * - * - * This new ViewHolder should be constructed with a new View that can represent the items - * of the given type. You can either create a new View manually or inflate it from an XML - * layout file. - * - * - * The new ViewHolder will be used to display items of the adapter using - * [.onBindViewHolder]. Since it will be re-used to display different - * items in the data set, it is a good idea to cache references to sub views of the View to - * avoid unnecessary [View.findViewById] calls. - - * @param parent The ViewGroup into which the new View will be added after it is bound to - * * an adapter position. - * * - * @param viewType The view type of the new View. - * * - * @return A new ViewHolder that holds a View of the given view type. - * * - * @see .getItemViewType - * @see .onBindViewHolder - */ override fun onCreateViewHolder( parent: ViewGroup, viewType: Int, @@ -91,25 +68,6 @@ class TrackEntryAdapter( popupMenu.show() } - /** - * Called by RecyclerView to display the data at the specified position. This method - * should update the contents of the [ViewHolder.itemView] to reflect the item at - * the given position. - * - * - * Note that unlike [android.widget.ListView], RecyclerView will not call this - * method again if the position of the item changes in the data set unless the item itself - * is invalidated or the new position cannot be determined. For this reason, you should only - * use the `position` parameter while acquiring the related data item inside this - * method and should not keep a copy of it. If you need the position of an item later on - * (e.g. in a click listener), use [ViewHolder.getPosition] which will have the - * updated position. - - * @param holder The ViewHolder which should be updated to represent the contents of the - * * item at the given position in the data set. - * * - * @param position The position of the item within the adapter's data set. - */ override fun onBindViewHolder( holder: ViewHolder, position: Int, @@ -119,24 +77,18 @@ class TrackEntryAdapter( val artist = entry.artist holder.artist.text = if (artist.isNullOrBlank()) holder.unknownArtist else artist holder.image.isGone = !coverMode - - Picasso - .get() - .load(File(cache, entry.key())) - .noFade() - .config(Bitmap.Config.RGB_565) - .error(R.drawable.ic_image_no_cover) - .placeholder(R.drawable.ic_image_no_cover) - .resizeDimen(R.dimen.list_album_size, R.dimen.list_album_size) - .centerCrop() - .into(holder.image) + holder.image.load(File(cache, entry.key())) { + crossfade(false) + placeholder(R.drawable.ic_image_no_cover) + error(R.drawable.ic_image_no_cover) + size( + holder.itemView.context.resources + .getDimensionPixelSize(R.dimen.list_album_size), + ) + scale(Scale.FILL) + } } - /** - * Returns the total number of items in the data set hold by the adapter. - - * @return The total number of items in this adapter. - */ override fun getItemCount(): Int { val count = data?.count?.toInt() return count ?: 0 diff --git a/app/src/main/java/com/kelsos/mbrc/features/minicontrol/MiniControlFragment.kt b/app/src/main/java/com/kelsos/mbrc/features/minicontrol/MiniControlFragment.kt index 78a3f70a5..ba6ac7599 100644 --- a/app/src/main/java/com/kelsos/mbrc/features/minicontrol/MiniControlFragment.kt +++ b/app/src/main/java/com/kelsos/mbrc/features/minicontrol/MiniControlFragment.kt @@ -1,7 +1,6 @@ package com.kelsos.mbrc.features.minicontrol import android.content.Intent -import android.graphics.Bitmap import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -11,13 +10,17 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.app.TaskStackBuilder import androidx.fragment.app.Fragment +import coil3.load +import coil3.request.crossfade +import coil3.request.error +import coil3.request.placeholder +import coil3.size.Scale import com.kelsos.mbrc.R import com.kelsos.mbrc.annotations.PlayerState import com.kelsos.mbrc.annotations.PlayerState.State import com.kelsos.mbrc.extensions.getDimens import com.kelsos.mbrc.features.player.PlayerActivity import com.kelsos.mbrc.features.player.TrackInfo -import com.squareup.picasso.Picasso import org.koin.android.ext.android.inject import org.koin.android.scope.AndroidScopeComponent import org.koin.androidx.scope.fragmentScope @@ -81,14 +84,13 @@ class MiniControlFragment : if (file.exists()) { val dimens = requireContext().getDimens() - Picasso - .get() - .load(file) - .noFade() - .config(Bitmap.Config.RGB_565) - .resize(dimens, dimens) - .centerCrop() - .into(trackCover) + trackCover.load(file) { + crossfade(false) + placeholder(R.drawable.ic_image_no_cover) + error(R.drawable.ic_image_no_cover) + size(dimens) + scale(Scale.FILL) + } } else { trackCover.setImageResource(R.drawable.ic_image_no_cover) } diff --git a/app/src/main/java/com/kelsos/mbrc/features/player/PlayerActivity.kt b/app/src/main/java/com/kelsos/mbrc/features/player/PlayerActivity.kt index b911baba5..9511bb57b 100644 --- a/app/src/main/java/com/kelsos/mbrc/features/player/PlayerActivity.kt +++ b/app/src/main/java/com/kelsos/mbrc/features/player/PlayerActivity.kt @@ -1,7 +1,6 @@ package com.kelsos.mbrc.features.player import android.content.Intent -import android.graphics.Bitmap import android.os.Bundle import android.text.TextUtils import android.view.Menu @@ -20,6 +19,11 @@ import androidx.appcompat.widget.ShareActionProvider import androidx.core.content.ContextCompat import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.MenuItemCompat +import coil3.load +import coil3.request.crossfade +import coil3.request.error +import coil3.request.placeholder +import coil3.size.Scale import com.google.android.material.snackbar.Snackbar import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback import com.kelsos.mbrc.BaseActivity @@ -36,7 +40,6 @@ import com.kelsos.mbrc.events.ui.ShuffleChange.ShuffleState import com.kelsos.mbrc.events.ui.UpdateDuration import com.kelsos.mbrc.extensions.getDimens import com.kelsos.mbrc.features.player.ProgressSeekerHelper.ProgressUpdate -import com.squareup.picasso.Picasso import org.koin.android.ext.android.inject import java.io.File @@ -174,14 +177,17 @@ class PlayerActivity : presenter.toggleScrobbling() true } + R.id.menu_rating_dialog -> { val ratingDialog = RatingDialogFragment() ratingDialog.show(supportFragmentManager, "RatingDialog") true } + R.id.menu_lastfm_love -> { presenter.lfmLove() } + else -> false } @@ -224,15 +230,13 @@ class PlayerActivity : } val dimens = getDimens() - Picasso - .get() - .load(file) - .noFade() - .error(R.drawable.ic_image_no_cover) - .config(Bitmap.Config.RGB_565) - .resize(dimens, dimens) - .centerCrop() - .into(albumCover) + albumCover.load(file) { + crossfade(false) + placeholder(R.drawable.ic_image_no_cover) + error(R.drawable.ic_image_no_cover) + size(dimens) + scale(Scale.FILL) + } } override fun updateShuffleState( @@ -259,9 +263,11 @@ class PlayerActivity : Repeat.ALL.equals(mode, ignoreCase = true) -> { // Do nothing already set above } + Repeat.ONE.equals(mode, ignoreCase = true) -> { resId = R.drawable.ic_repeat_one_black_24dp } + else -> { colorId = R.color.button_dark } @@ -299,17 +305,20 @@ class PlayerActivity : trackProgressAnimation(progressBar.progress, progressBar.max) R.drawable.ic_pause_circle_filled_black_24dp } + PlayerState.PAUSED -> { // Stop the animation if the track is paused progressHelper.stop() R.drawable.ic_play_circle_filled_black_24dp } + PlayerState.STOPPED -> { // Stop the animation if the track is paused progressHelper.stop() activateStoppedState() R.drawable.ic_play_circle_filled_black_24dp } + else -> { R.drawable.ic_play_circle_filled_black_24dp } diff --git a/app/src/main/java/com/kelsos/mbrc/features/widgets/RemoteViewsTarget.kt b/app/src/main/java/com/kelsos/mbrc/features/widgets/RemoteViewsTarget.kt new file mode 100644 index 000000000..5a2b4902b --- /dev/null +++ b/app/src/main/java/com/kelsos/mbrc/features/widgets/RemoteViewsTarget.kt @@ -0,0 +1,37 @@ +package com.kelsos.mbrc.features.widgets + +import android.appwidget.AppWidgetManager +import android.widget.RemoteViews +import androidx.annotation.IdRes +import coil3.Image +import coil3.target.Target +import coil3.toBitmap +import com.kelsos.mbrc.R +import timber.log.Timber + +class RemoteViewsTarget( + private val manager: AppWidgetManager, + private val widget: RemoteViews, + private val widgetIds: IntArray, + @IdRes private val imageViewResId: Int, +) : Target { + override fun onStart(placeholder: Image?) = setDrawable(placeholder, "start") + + override fun onError(error: Image?) = setDrawable(error, "error") + + override fun onSuccess(result: Image) = setDrawable(result, "success") + + private fun setDrawable( + image: Image?, + reason: String, + ) { + if (image == null) { + Timber.v("No image found for widget setting placeholder, reason: $reason") + widget.setImageViewResource(imageViewResId, R.drawable.ic_image_no_cover) + } else { + Timber.v("Updating image for widget, reason: $reason") + widget.setImageViewBitmap(imageViewResId, image.toBitmap()) + } + manager.updateAppWidget(widgetIds, widget) + } +} diff --git a/app/src/main/java/com/kelsos/mbrc/features/widgets/WidgetNormal.kt b/app/src/main/java/com/kelsos/mbrc/features/widgets/WidgetNormal.kt index 2bef2ed5e..8a5009d85 100644 --- a/app/src/main/java/com/kelsos/mbrc/features/widgets/WidgetNormal.kt +++ b/app/src/main/java/com/kelsos/mbrc/features/widgets/WidgetNormal.kt @@ -8,12 +8,15 @@ import android.content.Context import android.content.Intent import android.widget.RemoteViews import androidx.core.os.BundleCompat +import coil3.imageLoader +import coil3.request.ImageRequest +import coil3.size.Precision +import coil3.size.Scale import com.kelsos.mbrc.R import com.kelsos.mbrc.annotations.PlayerState import com.kelsos.mbrc.features.player.PlayerActivity import com.kelsos.mbrc.features.player.TrackInfo import com.kelsos.mbrc.platform.mediasession.RemoteViewIntentBuilder -import com.squareup.picasso.Picasso import timber.log.Timber import java.io.File @@ -124,13 +127,17 @@ class WidgetNormal : AppWidgetProvider() { val coverFile = File(path) if (coverFile.exists()) { - Picasso.get().invalidate(coverFile) - Picasso - .get() - .load(coverFile) - .centerCrop() - .resizeDimen(R.dimen.widget_normal_height, R.dimen.widget_normal_height) - .into(widget, R.id.widget_normal_image, widgetsIds) + val request = + ImageRequest + .Builder(context) + .data(coverFile) + .size(R.dimen.widget_normal_height) + .scale(Scale.FILL) + .precision(Precision.INEXACT) + .target(RemoteViewsTarget(widgetManager, widget, widgetsIds, R.id.widget_normal_image)) + .build() + + context.imageLoader.enqueue(request) } else { widget.setImageViewResource(R.id.widget_normal_image, R.drawable.ic_image_no_cover) } diff --git a/app/src/main/java/com/kelsos/mbrc/features/widgets/WidgetSmall.kt b/app/src/main/java/com/kelsos/mbrc/features/widgets/WidgetSmall.kt index d5ad5e6d8..9e2ffa721 100644 --- a/app/src/main/java/com/kelsos/mbrc/features/widgets/WidgetSmall.kt +++ b/app/src/main/java/com/kelsos/mbrc/features/widgets/WidgetSmall.kt @@ -8,12 +8,15 @@ import android.content.Context import android.content.Intent import android.widget.RemoteViews import androidx.core.os.BundleCompat +import coil3.imageLoader +import coil3.request.ImageRequest +import coil3.size.Precision +import coil3.size.Scale import com.kelsos.mbrc.R import com.kelsos.mbrc.annotations.PlayerState import com.kelsos.mbrc.features.player.PlayerActivity import com.kelsos.mbrc.features.player.TrackInfo import com.kelsos.mbrc.platform.mediasession.RemoteViewIntentBuilder -import com.squareup.picasso.Picasso import java.io.File class WidgetSmall : AppWidgetProvider() { @@ -124,13 +127,17 @@ class WidgetSmall : AppWidgetProvider() { val smallWidget = RemoteViews(context.packageName, R.layout.widget_small) val coverFile = File(path) if (coverFile.exists()) { - Picasso.get().invalidate(coverFile) - Picasso - .get() - .load(coverFile) - .centerCrop() - .resizeDimen(R.dimen.widget_small_height, R.dimen.widget_small_height) - .into(smallWidget, R.id.widget_small_image, widgetsIds) + val request = + ImageRequest + .Builder(context) + .data(coverFile) + .size(R.dimen.widget_small_height) + .scale(Scale.FILL) + .precision(Precision.INEXACT) + .target(RemoteViewsTarget(widgetManager, smallWidget, widgetsIds, R.id.widget_small_image)) + .build() + + context.imageLoader.enqueue(request) } else { smallWidget.setImageViewResource(R.id.widget_small_image, R.drawable.ic_image_no_cover) widgetManager.updateAppWidget(widgetsIds, smallWidget) diff --git a/app/src/main/java/com/kelsos/mbrc/networking/protocol/ProtocolActions.kt b/app/src/main/java/com/kelsos/mbrc/networking/protocol/ProtocolActions.kt index 577996a17..ece2077ea 100644 --- a/app/src/main/java/com/kelsos/mbrc/networking/protocol/ProtocolActions.kt +++ b/app/src/main/java/com/kelsos/mbrc/networking/protocol/ProtocolActions.kt @@ -29,7 +29,6 @@ import com.kelsos.mbrc.events.ui.TrackMoved import com.kelsos.mbrc.events.ui.TrackRemoval import com.kelsos.mbrc.events.ui.UpdateDuration import com.kelsos.mbrc.events.ui.VolumeChange -import com.kelsos.mbrc.extensions.getDimens import com.kelsos.mbrc.extensions.md5 import com.kelsos.mbrc.features.lyrics.LyricsModel import com.kelsos.mbrc.features.lyrics.LyricsPayload @@ -41,19 +40,15 @@ import com.kelsos.mbrc.networking.ApiBase import com.kelsos.mbrc.networking.SocketActivityChecker import com.kelsos.mbrc.networking.client.SocketMessage import com.kelsos.mbrc.networking.client.SocketService -import com.squareup.picasso.Callback -import com.squareup.picasso.Picasso import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.async import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import kotlinx.coroutines.suspendCancellableCoroutine import timber.log.Timber import java.io.File import java.io.FileOutputStream -import kotlin.coroutines.resumeWithException class UpdateLastFm( private val model: MainDataModel, @@ -320,8 +315,7 @@ class UpdateCover( try { val bitmap = getBitmap(cover) val file = storeCover(bitmap) - val pre = prefetch(file) - val path = pre.absolutePath + val path = file.absolutePath model.coverPath = path savePath(path) bus.post(CoverChangedEvent(path)) @@ -385,28 +379,6 @@ class UpdateCover( } } - private suspend fun prefetch(newFile: File): File = - suspendCancellableCoroutine { cont -> - val dimens = context.getDimens() - Picasso - .get() - .load(newFile) - .config(Bitmap.Config.RGB_565) - .resize(dimens, dimens) - .centerCrop() - .fetch( - object : Callback { - override fun onSuccess() { - cont.resume(newFile) { cause, _, _ -> } - } - - override fun onError(e: Exception) { - cont.resumeWithException(e) - } - }, - ) - } - private fun checkIfExists() { if (!coverDir.exists()) { coverDir.mkdir() diff --git a/app/src/main/java/com/kelsos/mbrc/platform/mediasession/MediaButtonReceiver.kt b/app/src/main/java/com/kelsos/mbrc/platform/mediasession/MediaButtonReceiver.kt index 89b12103e..05cebab38 100644 --- a/app/src/main/java/com/kelsos/mbrc/platform/mediasession/MediaButtonReceiver.kt +++ b/app/src/main/java/com/kelsos/mbrc/platform/mediasession/MediaButtonReceiver.kt @@ -4,6 +4,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import org.koin.core.component.KoinComponent +import timber.log.Timber class MediaButtonReceiver : BroadcastReceiver(), @@ -12,6 +13,7 @@ class MediaButtonReceiver : context: Context, intent: Intent, ) { + Timber.v("Incoming %s", intent) if (intent.action != Intent.ACTION_MEDIA_BUTTON) { return } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 371b26b77..13c61e0e9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,6 +19,7 @@ androidx-test-truth = "1.6.0" androidx-viewpager2 = "1.1.0" androidx-core-splashscreen = "1.0.1" dbflow = "4.2.4" +coil = "3.0.4" desugar = "2.1.4" firebaseBom = "33.7.0" google-material = "1.12.0" @@ -40,7 +41,6 @@ kotlinCoroutines = "1.10.1" kotlinReflect = "2.1.0" legacySupportV4 = "1.0.0" mockk = "1.13.14" -picasso = "2.8" protobuf = "4.26.1" robolectric = "4.14.1" rxandroid = "1.2.1" @@ -80,6 +80,8 @@ androidx-test-runner = { module = "androidx.test:runner", version.ref = "android androidx-test-truth = { module = "androidx.test.ext:truth", version.ref = "androidx-test-truth" } androidx-viewpager2 = { module = "androidx.viewpager2:viewpager2", version.ref = "androidx-viewpager2" } com-android-tools-desugar = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar" } +coilKt-coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } +coilKt-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" } dbflow = { module = "com.github.Raizlabs.DBFlow:dbflow", version.ref = "dbflow" } dbflow-core = { module = "com.github.Raizlabs.DBFlow:dbflow-core", version.ref = "dbflow" } dbflow-kotlinextensions = { module = "com.github.Raizlabs.DBFlow:dbflow-kotlinextensions", version.ref = "dbflow" } @@ -106,7 +108,6 @@ rxjava = { module = "io.reactivex:rxjava", version.ref = "rxjava" } rxandroid = { module = "io.reactivex:rxandroid", version.ref = "rxandroid" } rxrelay = { module = "com.jakewharton.rxrelay:rxrelay", version.ref = "rxrelay" } rxkotlin = { module = "io.reactivex:rxkotlin", version.ref = "rxkotlin" } -squareup-picasso = { module = "com.squareup.picasso:picasso", version.ref = "picasso" } robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" } squareup-leakcanary = { module = "com.squareup.leakcanary:leakcanary-android", version.ref = "squareup-leakcanary" } squareup-okio = { module = "com.squareup.okio:okio", version.ref = "squareup-okio" } @@ -125,6 +126,10 @@ androidx-test-espresso = [ "androidx-test-espresso-core", "androidx-test-espresso-intents", ] +coil = [ + "coilKt-coil", + "coilKt-network-okhttp" +] coroutines = [ "kotlin-coroutines-android",