From c39100b7c6b6b330b4207d780ef602a2ba5af85a Mon Sep 17 00:00:00 2001 From: Isabel Martin Date: Mon, 15 Apr 2024 11:25:11 -0700 Subject: [PATCH] MBL-1318: Spiking crash PicassoDrawable.draw trying to draw too large bitmap mitigation (#2015) --- .../ui/activities/EditProfileActivity.kt | 5 +- .../ui/activities/ProfileActivity.kt | 5 +- .../ui/activities/SettingsActivity.kt | 6 +- .../kickstarter/ui/extensions/ImageViewExt.kt | 162 +++++++++++++----- .../projectpage/ProjectOverviewFragment.kt | 13 +- .../ActivitySampleFriendFollowViewHolder.kt | 7 +- .../ActivitySampleProjectViewHolder.kt | 6 +- .../ui/viewholders/FriendBackingViewHolder.kt | 13 +- .../ui/viewholders/FriendFollowViewHolder.kt | 8 +- .../ui/viewholders/MessageThreadViewHolder.kt | 7 +- .../ui/viewholders/MessageViewHolder.kt | 7 +- .../ui/viewholders/ProfileCardViewHolder.kt | 6 +- .../ui/viewholders/ProjectCardViewHolder.kt | 12 +- .../ProjectStateChangedPositiveViewHolder.kt | 6 +- .../ProjectStateChangedViewHolder.kt | 6 +- .../ui/viewholders/ProjectUpdateViewHolder.kt | 6 +- .../ui/viewholders/SurveyViewHolder.kt | 8 +- .../discoverydrawer/LoggedInViewHolder.kt | 8 +- .../com/kickstarter/ui/views/MediaHeader.kt | 9 +- 19 files changed, 155 insertions(+), 145 deletions(-) diff --git a/app/src/main/java/com/kickstarter/ui/activities/EditProfileActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/EditProfileActivity.kt index 2b13d02887..e0c8eafe28 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/EditProfileActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/EditProfileActivity.kt @@ -6,16 +6,15 @@ import androidx.activity.ComponentActivity import androidx.activity.viewModels import androidx.core.view.isGone import com.kickstarter.databinding.ActivityEditProfileBinding -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.SwitchCompatUtils import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.libs.utils.extensions.isFalse import com.kickstarter.models.User +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.showSnackbar import com.kickstarter.viewmodels.EditProfileViewModel -import com.squareup.picasso.Picasso import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -40,7 +39,7 @@ class EditProfileActivity : ComponentActivity() { this.viewModel.outputs.userAvatarUrl() .observeOn(AndroidSchedulers.mainThread()) .subscribe { url -> - Picasso.get().load(url).transform(CircleTransformation()).into(binding.avatarImageView) + binding.avatarImageView.loadCircleImage(url) }.addToDisposable(disposables) this.viewModel.outputs.user() diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProfileActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProfileActivity.kt index be30576256..1b8b525656 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProfileActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProfileActivity.kt @@ -11,15 +11,14 @@ import com.kickstarter.libs.BaseActivity import com.kickstarter.libs.RecyclerViewPaginator import com.kickstarter.libs.qualifiers.RequiresActivityViewModel import com.kickstarter.libs.rx.transformers.Transformers.observeForUI -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.ApplicationUtils import com.kickstarter.libs.utils.ViewUtils import com.kickstarter.libs.utils.extensions.getProjectIntent import com.kickstarter.models.Project import com.kickstarter.ui.IntentKey import com.kickstarter.ui.adapters.ProfileAdapter +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.viewmodels.ProfileViewModel -import com.squareup.picasso.Picasso @RequiresActivityViewModel(ProfileViewModel.ViewModel::class) class ProfileActivity : BaseActivity() { @@ -46,7 +45,7 @@ class ProfileActivity : BaseActivity() { this.viewModel.outputs.avatarImageViewUrl() .compose(bindToLifecycle()) .compose(observeForUI()) - .subscribe { url -> Picasso.get().load(url).transform(CircleTransformation()).into(binding.avatarImageView) } + .subscribe { url -> binding.avatarImageView.loadCircleImage(url) } this.viewModel.outputs.backedCountTextViewHidden() .compose(bindToLifecycle()) diff --git a/app/src/main/java/com/kickstarter/ui/activities/SettingsActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/SettingsActivity.kt index 922426c5fe..4972b68302 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/SettingsActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/SettingsActivity.kt @@ -18,15 +18,14 @@ import com.kickstarter.libs.Build import com.kickstarter.libs.KSString import com.kickstarter.libs.Logout import com.kickstarter.libs.featureflag.FlagKey -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.ApplicationUtils import com.kickstarter.libs.utils.ViewUtils import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.ui.SharedPreferenceKey +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.viewmodels.SettingsViewModel -import com.squareup.picasso.Picasso import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -86,8 +85,7 @@ class SettingsActivity : AppCompatActivity() { this.viewModel.outputs.avatarImageViewUrl() .observeOn(AndroidSchedulers.mainThread()) .subscribe { url -> - Picasso.get().load(url).transform(CircleTransformation()) - .into(binding.profilePictureImageView) + binding.profilePictureImageView.loadCircleImage(url) } .addToDisposable(disposables) diff --git a/app/src/main/java/com/kickstarter/ui/extensions/ImageViewExt.kt b/app/src/main/java/com/kickstarter/ui/extensions/ImageViewExt.kt index e577111d29..be33ea9203 100644 --- a/app/src/main/java/com/kickstarter/ui/extensions/ImageViewExt.kt +++ b/app/src/main/java/com/kickstarter/ui/extensions/ImageViewExt.kt @@ -3,75 +3,145 @@ package com.kickstarter.ui.extensions import android.content.Context import android.graphics.Color import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable import android.widget.ImageView import androidx.appcompat.widget.AppCompatImageView import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.load.engine.GlideException +import com.bumptech.glide.request.RequestListener +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.Target +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.kickstarter.R -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.extensions.isKSApplication -import com.squareup.picasso.Callback -import com.squareup.picasso.Picasso +import javax.sql.DataSource fun ImageView.loadCircleImage(url: String?) { url?.let { - if (it.isBlank()) { // - load with drawable - Picasso.get() - .load(R.drawable.circle_grey_500) - .transform(CircleTransformation()) - .into(this) - } else { // - load with url string - Picasso.get() - .load(it) - .placeholder(R.drawable.circle_grey_500) - .transform(CircleTransformation()) - .into(this) + try { + if (it.isBlank()) { // - load with drawable + Glide.with(context) + .load(ColorDrawable(Color.TRANSPARENT)) + .circleCrop() + .into(this) + } else { // - load with url string + Glide.with(context) + .load(it) + .placeholder(ColorDrawable(Color.TRANSPARENT)) + .diskCacheStrategy(DiskCacheStrategy.RESOURCE) + .circleCrop() + .into(this) + } + } catch (e: Exception) { + // - Empty by default in case or error + this.setImageResource(R.drawable.image_placeholder) + FirebaseCrashlytics.getInstance().setCustomKey("ImageView.loadCircleImage", " with url: $it ${e.message ?: ""}") + FirebaseCrashlytics.getInstance().recordException(e) } } } fun ImageView.loadImage(url: String?) { url?.let { - Picasso - .get() - .load(it) - .into(this) + try { + Glide.with(context) + .load(url) + .placeholder(ColorDrawable(Color.TRANSPARENT)) + .diskCacheStrategy(DiskCacheStrategy.RESOURCE) + .into(this) + } catch (e: Exception) { + this.setImageResource(R.drawable.image_placeholder) + FirebaseCrashlytics.getInstance().setCustomKey("ImageView.loadImage", " with url: $it ${e.message ?: ""}") + FirebaseCrashlytics.getInstance().recordException(e) + } } } +fun ImageView.loadImageWithResize( + url: String?, + targetImageWidth: Int, + targetImageHeight: Int, + placeholder: Drawable +) { + url?.let { + try { + Glide.with(context) + .load(url) + .diskCacheStrategy(DiskCacheStrategy.RESOURCE) + .apply(RequestOptions().override(targetImageWidth, targetImageHeight)) + .centerCrop() + .placeholder(placeholder) + .into(this) + } catch (e: Exception) { + this.setImageResource(R.drawable.image_placeholder) + FirebaseCrashlytics.getInstance().setCustomKey("ImageView.loadImageWithResize", " with url: $it ${e.message ?: ""}") + FirebaseCrashlytics.getInstance().recordException(e) + } + } +} fun ImageView.loadImage(url: String?, context: Context, imageViewPlaceholder: AppCompatImageView? = null) { - val target = this - if (context.applicationContext.isKSApplication()) { - Picasso - .get() - .load(url) - .into( - this, - object : Callback { - override fun onSuccess() { - imageViewPlaceholder?.setImageDrawable(target.drawable) - } + url?.let { + val targetView = this + if (context.applicationContext.isKSApplication()) { + try { + Glide.with(context) + .load(url) + .listener(object : RequestListener { + override fun onResourceReady( + resource: Drawable?, + model: Any?, + target: Target?, + dataSource: com.bumptech.glide.load.DataSource?, + isFirstResource: Boolean + ): Boolean { + imageViewPlaceholder?.setImageDrawable(resource) + return isFirstResource + } - override fun onError(e: Exception?) { - target.setImageDrawable(null) - imageViewPlaceholder?.setImageDrawable(null) - } - } - ) - } else { - this.setImageResource(R.drawable.image_placeholder) + override fun onLoadFailed( + e: GlideException?, + model: Any?, + target: Target?, + isFirstResource: Boolean + ): Boolean { + targetView.setImageDrawable(null) + imageViewPlaceholder?.setImageDrawable(null) + return isFirstResource + } + }) + .placeholder(ColorDrawable(Color.TRANSPARENT)) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .load(url) + .into(this) + } catch (e: Exception) { + this.setImageResource(R.drawable.image_placeholder) + FirebaseCrashlytics.getInstance().setCustomKey("ImageView.loadImageWithResize", " with url: $it ${e.message ?: ""}") + FirebaseCrashlytics.getInstance().recordException(e) + } + } else { + this.setImageResource(R.drawable.image_placeholder) + } } } fun ImageView.loadGifImage(url: String?, context: Context) { - if (context.applicationContext.isKSApplication()) { - Glide.with(context) - .asGif() - .placeholder(ColorDrawable(Color.TRANSPARENT)) - .diskCacheStrategy(DiskCacheStrategy.ALL) - .load(url) - .into(this) - } else { - this.setImageResource(R.drawable.image_placeholder) + url?.let { + if (context.applicationContext.isKSApplication()) { + try { + Glide.with(context) + .asGif() + .placeholder(ColorDrawable(Color.TRANSPARENT)) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .load(url) + .into(this) + } catch (e: Exception) { + this.setImageResource(R.drawable.image_placeholder) + FirebaseCrashlytics.getInstance().setCustomKey("ImageView.loadImageWithResize", " with url: $url ${e.message ?: ""}") + FirebaseCrashlytics.getInstance().recordException(e) + } + } else { + this.setImageResource(R.drawable.image_placeholder) + } } } diff --git a/app/src/main/java/com/kickstarter/ui/fragments/projectpage/ProjectOverviewFragment.kt b/app/src/main/java/com/kickstarter/ui/fragments/projectpage/ProjectOverviewFragment.kt index d33b9af5a4..84d710bb08 100644 --- a/app/src/main/java/com/kickstarter/ui/fragments/projectpage/ProjectOverviewFragment.kt +++ b/app/src/main/java/com/kickstarter/ui/fragments/projectpage/ProjectOverviewFragment.kt @@ -23,7 +23,6 @@ import com.kickstarter.R import com.kickstarter.databinding.FragmentProjectOverviewBinding import com.kickstarter.libs.Configure import com.kickstarter.libs.KSString -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.ApplicationUtils import com.kickstarter.libs.utils.DateTimeUtils import com.kickstarter.libs.utils.SocialUtils @@ -36,6 +35,7 @@ import com.kickstarter.ui.ArgumentsKey import com.kickstarter.ui.IntentKey import com.kickstarter.ui.activities.ProjectSocialActivity import com.kickstarter.ui.data.ProjectData +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.ui.extensions.setClickableHtml import com.kickstarter.ui.extensions.startCreatorBioWebViewActivity import com.kickstarter.ui.extensions.startLoginActivity @@ -43,7 +43,6 @@ import com.kickstarter.ui.extensions.startProjectUpdatesActivity import com.kickstarter.ui.extensions.startReportProjectActivity import com.kickstarter.ui.extensions.startRootCommentsActivity import com.kickstarter.viewmodels.projectpage.ProjectOverviewViewModel.ProjectOverviewViewModel -import com.squareup.picasso.Picasso import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import org.joda.time.DateTime @@ -224,10 +223,7 @@ class ProjectOverviewFragment : Fragment(), Configure { .observeOn(AndroidSchedulers.mainThread()) .subscribe { url: String? -> url?.let { - Picasso.get() - .load(it) - .transform(CircleTransformation()) - .into(binding.projectSocialImage) + binding.projectSocialImage.loadCircleImage(it) } } .addToDisposable(disposables) @@ -393,10 +389,7 @@ class ProjectOverviewFragment : Fragment(), Configure { } private fun setAvatar(url: String) { - Picasso.get() - .load(url) - .transform(CircleTransformation()) - .into(binding.avatar) + binding.avatar.loadCircleImage(url) } private fun setConvertedCurrencyView(pledgedAndGoal: Pair) { diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/ActivitySampleFriendFollowViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/ActivitySampleFriendFollowViewHolder.kt index 7859c19ff1..e4fd01ea1c 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/ActivitySampleFriendFollowViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/ActivitySampleFriendFollowViewHolder.kt @@ -4,11 +4,10 @@ import android.view.View import com.kickstarter.R import com.kickstarter.databinding.ActivitySampleFriendFollowViewBinding import com.kickstarter.libs.rx.transformers.Transformers -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.models.Activity +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.viewmodels.ActivitySampleFriendFollowViewHolderViewModel -import com.squareup.picasso.Picasso import io.reactivex.disposables.CompositeDisposable class ActivitySampleFriendFollowViewHolder( @@ -32,9 +31,7 @@ class ActivitySampleFriendFollowViewHolder( .subscribe { it.user()?.let { user -> user.avatar().small().let { url -> - Picasso.get().load(url) - .transform(CircleTransformation()) - .into(binding.activityImage) + binding.activityImage.loadCircleImage(url) } binding.activityTitle.text = ksString.format( diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/ActivitySampleProjectViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/ActivitySampleProjectViewHolder.kt index 1da2a497b3..7ca9122d8f 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/ActivitySampleProjectViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/ActivitySampleProjectViewHolder.kt @@ -5,8 +5,8 @@ import com.kickstarter.databinding.ActivitySampleProjectViewBinding import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.models.Activity import com.kickstarter.models.Project +import com.kickstarter.ui.extensions.loadImage import com.kickstarter.viewmodels.ActivitySampleProjectViewHolderViewModel -import com.squareup.picasso.Picasso import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -40,9 +40,7 @@ class ActivitySampleProjectViewHolder( activity.project()?.let { project -> val photo = project.photo() photo?.let { - Picasso.get() - .load(photo.little()) - .into(binding.activityImage) + binding.activityImage.loadImage(it.little()) } binding.activityTitle.text = project.name() val activitySubtitleText = when (activity.category()) { diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/FriendBackingViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/FriendBackingViewHolder.kt index adddbce273..e4805e539e 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/FriendBackingViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/FriendBackingViewHolder.kt @@ -2,10 +2,10 @@ package com.kickstarter.ui.viewholders import com.kickstarter.R import com.kickstarter.databinding.ActivityFriendBackingViewBinding -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.SocialUtils import com.kickstarter.models.Activity -import com.squareup.picasso.Picasso +import com.kickstarter.ui.extensions.loadCircleImage +import com.kickstarter.ui.extensions.loadImage class FriendBackingViewHolder( private val binding: ActivityFriendBackingViewBinding, @@ -25,17 +25,12 @@ class FriendBackingViewHolder( val projectCategory = activityProject.category() ?: return val projectPhoto = activityProject.photo() ?: return activityUser.avatar().small()?.let { - Picasso.get() - .load(it) - .transform(CircleTransformation()) - .into(binding.avatar) + binding.avatar.loadCircleImage(it) } binding.creatorName.text = ksString.format(context.getString(R.string.project_creator_by_creator), "creator_name", projectCreator.name()) binding.projectName.text = activityProject.name() - Picasso.get() - .load(projectPhoto.little()) - .into(binding.projectPhoto) + binding.projectPhoto.loadImage(projectPhoto.little()) binding.title.text = SocialUtils.friendBackingActivityTitle( context, activityUser.name(), diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/FriendFollowViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/FriendFollowViewHolder.kt index 71293c44cf..e712447c85 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/FriendFollowViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/FriendFollowViewHolder.kt @@ -2,8 +2,7 @@ package com.kickstarter.ui.viewholders import com.kickstarter.R import com.kickstarter.databinding.ActivityFriendFollowViewBinding -import com.kickstarter.libs.transformations.CircleTransformation -import com.squareup.picasso.Picasso +import com.kickstarter.ui.extensions.loadCircleImage class FriendFollowViewHolder(private val binding: ActivityFriendFollowViewBinding) : ActivityListViewHolder(binding.root) { @@ -12,10 +11,7 @@ class FriendFollowViewHolder(private val binding: ActivityFriendFollowViewBindin val context = context() val friend = activity().user() ?: return friend.avatar().small()?.let { - Picasso.get() - .load(it) - .transform(CircleTransformation()) - .into(binding.avatar) + binding.avatar.loadCircleImage(it) } // TODO: bold username binding.title.text = StringBuilder(friend.name()) diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/MessageThreadViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/MessageThreadViewHolder.kt index 59093f4929..8ea3c208cd 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/MessageThreadViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/MessageThreadViewHolder.kt @@ -8,15 +8,14 @@ import com.kickstarter.R import com.kickstarter.databinding.MessageThreadViewBinding import com.kickstarter.libs.MessagePreviousScreenType import com.kickstarter.libs.rx.transformers.Transformers -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.DateTimeUtils import com.kickstarter.libs.utils.ViewUtils import com.kickstarter.libs.utils.extensions.wrapInParentheses import com.kickstarter.models.MessageThread import com.kickstarter.ui.IntentKey import com.kickstarter.ui.activities.MessagesActivity +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.viewmodels.MessageThreadHolderViewModel -import com.squareup.picasso.Picasso import org.joda.time.DateTime class MessageThreadViewHolder(private val binding: MessageThreadViewBinding) : KSViewHolder(binding.root) { @@ -46,9 +45,7 @@ class MessageThreadViewHolder(private val binding: MessageThreadViewBinding) : K } private fun setParticipantAvatarImageView(avatarUrl: String) { - Picasso.get().load(avatarUrl) - .transform(CircleTransformation()) - .into(binding.participantAvatarImageView) + binding.participantAvatarImageView.loadCircleImage(avatarUrl) } private fun setUnreadCountTextView(unreadCount: String) { diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/MessageViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/MessageViewHolder.kt index 0402f1ae9e..b943222b80 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/MessageViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/MessageViewHolder.kt @@ -10,12 +10,11 @@ import android.view.View import androidx.core.content.ContextCompat.startActivity import androidx.core.view.isGone import com.kickstarter.databinding.MessageViewBinding -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.models.Message import com.kickstarter.ui.activities.DeepLinkActivity +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.viewmodels.MessageHolderViewModel -import com.squareup.picasso.Picasso import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -102,8 +101,6 @@ class MessageViewHolder(private val binding: MessageViewBinding) : KSViewHolder( } private fun setParticipantAvatarImageView(avatarUrl: String) { - Picasso.get().load(avatarUrl) - .transform(CircleTransformation()) - .into(binding.messageSenderAvatarImageView) + binding.messageSenderAvatarImageView.loadCircleImage(avatarUrl) } } diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/ProfileCardViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/ProfileCardViewHolder.kt index 6be7133735..62436c5e09 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/ProfileCardViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/ProfileCardViewHolder.kt @@ -6,7 +6,7 @@ import com.kickstarter.R import com.kickstarter.databinding.ProfileCardViewBinding import com.kickstarter.libs.utils.ProgressBarUtils import com.kickstarter.models.Project -import com.squareup.picasso.Picasso +import com.kickstarter.ui.extensions.loadImage class ProfileCardViewHolder( private val binding: ProfileCardViewBinding, @@ -32,9 +32,7 @@ class ProfileCardViewHolder( binding.profileCardImage.apply { visibility = View.VISIBLE ContextCompat.getDrawable(context, R.drawable.gray_gradient)?.let { - Picasso.get().load(photo.med()) - .placeholder(it) - .into(this) + this.loadImage(photo.med()) } } } diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/ProjectCardViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/ProjectCardViewHolder.kt index a9b3afb449..0ec4bfbbc7 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/ProjectCardViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/ProjectCardViewHolder.kt @@ -24,8 +24,8 @@ import com.kickstarter.libs.utils.extensions.photoHeightFromWidthRatio import com.kickstarter.models.Project import com.kickstarter.services.DiscoveryParams import com.kickstarter.ui.extensions.loadCircleImage +import com.kickstarter.ui.extensions.loadImageWithResize import com.kickstarter.viewmodels.ProjectCardHolderViewModel -import com.squareup.picasso.Picasso import io.reactivex.disposables.CompositeDisposable import org.joda.time.DateTime @@ -322,15 +322,7 @@ class ProjectCardViewHolder( avatarUrl?.let { ResourcesCompat.getDrawable(context().resources, R.drawable.gray_gradient, null) ?.let { placeholder -> - Picasso.get() - .load(it) - .resize( - targetImageWidth, - targetImageHeight - ) // required to fit properly into apis < 18 - .centerCrop() - .placeholder(placeholder) - .into(binding.projectCardPhoto.photo) + binding.projectCardPhoto.photo.loadImageWithResize(it, targetImageWidth, targetImageHeight, placeholder) } } } diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/ProjectStateChangedPositiveViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/ProjectStateChangedPositiveViewHolder.kt index 2c3858f0ed..bf405e946f 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/ProjectStateChangedPositiveViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/ProjectStateChangedPositiveViewHolder.kt @@ -5,7 +5,7 @@ import com.kickstarter.R import com.kickstarter.databinding.ActivityProjectStateChangedPositiveViewBinding import com.kickstarter.libs.utils.DateTimeUtils import com.kickstarter.models.Activity -import com.squareup.picasso.Picasso +import com.kickstarter.ui.extensions.loadImage import org.joda.time.DateTime class ProjectStateChangedPositiveViewHolder( @@ -72,9 +72,7 @@ class ProjectStateChangedPositiveViewHolder( } // TODO: Switch to "You launched a project" if current user launched // return context.getString(R.string.creator_launched_a_project, activity.user().name(), activity.project().name()); - Picasso.get() - .load(photo.full()) - .into(binding.projectPhoto) + binding.projectPhoto.loadImage(photo.full()) } binding.cardView.setOnClickListener { onClick() diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/ProjectStateChangedViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/ProjectStateChangedViewHolder.kt index 37b227ecd5..eca7e92be4 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/ProjectStateChangedViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/ProjectStateChangedViewHolder.kt @@ -3,7 +3,7 @@ package com.kickstarter.ui.viewholders import com.kickstarter.R import com.kickstarter.databinding.ActivityProjectStateChangedViewBinding import com.kickstarter.models.Activity -import com.squareup.picasso.Picasso +import com.kickstarter.ui.extensions.loadImage class ProjectStateChangedViewHolder( private val binding: ActivityProjectStateChangedViewBinding, @@ -21,9 +21,7 @@ class ProjectStateChangedViewHolder( val user = activity().user() val photo = project?.photo() if (project != null && user != null && photo != null) { - Picasso.get() - .load(photo.little()) - .into(binding.projectPhoto) + binding.projectPhoto.loadImage(photo.little()) val title = when (activity().category()) { Activity.CATEGORY_FAILURE -> context().getString(R.string.activity_project_state_change_project_was_not_successfully_funded) diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/ProjectUpdateViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/ProjectUpdateViewHolder.kt index d26ee0d579..e24f232c24 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/ProjectUpdateViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/ProjectUpdateViewHolder.kt @@ -4,7 +4,7 @@ import com.kickstarter.R import com.kickstarter.databinding.ActivityProjectUpdateViewBinding import com.kickstarter.libs.utils.DateTimeUtils import com.kickstarter.models.Activity -import com.squareup.picasso.Picasso +import com.kickstarter.ui.extensions.loadImage import org.joda.time.DateTime class ProjectUpdateViewHolder( @@ -29,9 +29,7 @@ class ProjectUpdateViewHolder( if (project != null && user != null && photo != null && update != null) { val publishedAt = update.publishedAt() ?: DateTime() binding.projectName.text = project.name() - Picasso.get() - .load(photo.little()) - .into(binding.projectPhoto) + binding.projectPhoto.loadImage(photo.little()) binding.timestamp.text = DateTimeUtils.relative(context, ksString, publishedAt) binding.updateBody.text = update.truncatedBody() binding.updateSequence.text = ksString.format( diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/SurveyViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/SurveyViewHolder.kt index 3d8a8a6e0a..c6aad52f2e 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/SurveyViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/SurveyViewHolder.kt @@ -6,13 +6,12 @@ import android.view.View import com.kickstarter.R import com.kickstarter.databinding.ActivitySurveyViewBinding import com.kickstarter.libs.rx.transformers.Transformers -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.models.Project import com.kickstarter.models.SurveyResponse import com.kickstarter.ui.IntentKey import com.kickstarter.ui.activities.SurveyResponseActivity +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.viewmodels.SurveyHolderViewModel -import com.squareup.picasso.Picasso class SurveyViewHolder(private val binding: ActivitySurveyViewBinding) : KSViewHolder(binding.root) { @@ -40,10 +39,7 @@ class SurveyViewHolder(private val binding: ActivitySurveyViewBinding) : } private fun setCreatorAvatarImage(creatorAvatarImage: String) { - Picasso.get() - .load(creatorAvatarImage) - .transform(CircleTransformation()) - .into(binding.surveyAvatarImage) + binding.surveyAvatarImage.loadCircleImage(creatorAvatarImage) } private fun startSurveyResponseActivity(surveyResponse: SurveyResponse) { diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/discoverydrawer/LoggedInViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/discoverydrawer/LoggedInViewHolder.kt index d3d49cefc6..e9ec6ce191 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/discoverydrawer/LoggedInViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/discoverydrawer/LoggedInViewHolder.kt @@ -4,13 +4,12 @@ import androidx.annotation.NonNull import androidx.core.content.ContextCompat import com.kickstarter.databinding.DiscoveryDrawerLoggedInViewBinding import com.kickstarter.libs.rx.transformers.Transformers.observeForUI -import com.kickstarter.libs.transformations.CircleTransformation import com.kickstarter.libs.utils.NumberUtils import com.kickstarter.libs.utils.extensions.isNullOrZero import com.kickstarter.models.User +import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.ui.viewholders.KSViewHolder import com.kickstarter.viewmodels.LoggedInViewHolderViewModel -import com.squareup.picasso.Picasso class LoggedInViewHolder( private val binding: DiscoveryDrawerLoggedInViewBinding, @@ -32,10 +31,7 @@ class LoggedInViewHolder( .compose(bindToLifecycle()) .compose(observeForUI()) .subscribe { - Picasso.get() - .load(it) - .transform(CircleTransformation()) - .into(binding.userImageView) + binding.userImageView.loadCircleImage(it) } this.viewModel.outputs.name() diff --git a/app/src/main/java/com/kickstarter/ui/views/MediaHeader.kt b/app/src/main/java/com/kickstarter/ui/views/MediaHeader.kt index 93c7af14b1..c8e739b807 100644 --- a/app/src/main/java/com/kickstarter/ui/views/MediaHeader.kt +++ b/app/src/main/java/com/kickstarter/ui/views/MediaHeader.kt @@ -15,7 +15,7 @@ import com.kickstarter.libs.utils.ViewUtils.getScreenWidthDp import com.kickstarter.libs.utils.extensions.photoHeightFromWidthRatio import com.kickstarter.libs.utils.extensions.toVisibility import com.kickstarter.ui.data.MediaElement -import com.squareup.picasso.Picasso +import com.kickstarter.ui.extensions.loadImageWithResize import rx.Observable import rx.subjects.PublishSubject @@ -88,12 +88,7 @@ class MediaHeader @JvmOverloads constructor( if (element?.thumbnailUrl != null) { ResourcesCompat.getDrawable(context.resources, R.drawable.gray_gradient, null) ?.let { - Picasso.get() - .load(element.thumbnailUrl) - .resize(targetImageWidth, targetImageHeight) - .centerCrop() - .placeholder(it) - .into(binding.videoProjectPhoto) + binding.videoProjectPhoto.loadImageWithResize(element.thumbnailUrl, targetImageWidth, targetImageHeight, it) } }