diff --git a/WordPress/build.gradle b/WordPress/build.gradle index e3f33b5c6cf4..03965e2df258 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -44,6 +44,7 @@ repositories { includeGroupByRegex "org.wordpress.react-native-libraries.*" includeGroup "com.automattic" includeGroup "com.automattic.tracks" + includeGroup "com.gravatar" } } maven { @@ -388,6 +389,7 @@ dependencies { exclude group: 'com.mcxiaoke.volley' } implementation "org.wordpress:persistentedittext:$wordPressPersistentEditTextVersion" + implementation "$gradle.ext.gravatarBinaryPath:$gravatarVersion" implementation "androidx.arch.core:core-common:$androidxArchCoreVersion" implementation "androidx.arch.core:core-runtime:$androidxArchCoreVersion" @@ -438,7 +440,6 @@ dependencies { implementation "com.github.chrisbanes:PhotoView:$chrisbanesPhotoviewVersion" implementation "org.greenrobot:eventbus:$eventBusVersion" implementation "org.greenrobot:eventbus-java:$eventBusVersion" - implementation "com.squareup.okio:okio:$squareupOkioVersion" implementation "com.squareup.retrofit2:retrofit:$squareupRetrofitVersion" implementation "org.apache.commons:commons-text:$apacheCommonsTextVersion" implementation "com.airbnb.android:lottie:$lottieVersion" diff --git a/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java b/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java deleted file mode 100644 index 762b808321f9..000000000000 --- a/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.wordpress.android.networking; - -import android.content.Context; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -import javax.inject.Inject; - -import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertTrue; - -import dagger.hilt.android.testing.HiltAndroidRule; -import dagger.hilt.android.testing.HiltAndroidTest; -import okhttp3.Request; -import okhttp3.RequestBody; -import okio.Buffer; - -@HiltAndroidTest -public class GravatarApiTest { - @Rule - public HiltAndroidRule hiltRule = new HiltAndroidRule(this); - - @Inject Context mContext; - - @Before - public void setUp() { - hiltRule.inject(); - } - - @Test - public void testGravatarUploadRequest() throws IOException { - final String fileContent = "abcdefg"; - - File tempFile = new File(mContext.getCacheDir(), "tempFile.jpg"); - FileOutputStream fos = new FileOutputStream(tempFile); - fos.write(fileContent.getBytes()); - fos.flush(); - fos.close(); - - final String email = "a@b.com"; - Request uploadRequest = GravatarApi.prepareGravatarUpload(email, tempFile); - - assertEquals("POST", uploadRequest.method()); - - RequestBody requestBody = uploadRequest.body(); - assertTrue(requestBody.contentType().toString().startsWith("multipart/form-data")); - - final Buffer buffer = new Buffer(); - requestBody.writeTo(buffer); - final String body = buffer.readUtf8(); - - assertTrue(body.contains("Content-Disposition: form-data; name=\"account\"")); - assertTrue(body.contains("Content-Length: " + email.length())); - assertTrue(body.contains(email)); - - assertTrue(body.contains( - "Content-Disposition: form-data; name=\"filedata\"; filename=\"" + tempFile.getName() + "\"")); - assertTrue(body.contains("Content-Type: multipart/form-data")); - assertTrue(body.contains(fileContent)); - } -} diff --git a/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt new file mode 100644 index 000000000000..24cf7d8f9951 --- /dev/null +++ b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt @@ -0,0 +1,43 @@ +package org.wordpress.android.util + +import com.gravatar.DefaultAvatarOption +import dagger.hilt.android.testing.HiltAndroidTest +import junit.framework.TestCase.assertEquals +import org.junit.Test + +@HiltAndroidTest +class WPAvatarUtilsTest { + @Test + fun rewriteAvatarUrlReplaceNonGravatarUrlToPhotonUrl() { + assertEquals( + "https://i0.wp.com/example.com/image.jpg?strip=info&quality=65&resize=100,100&ssl=1", + WPAvatarUtils.rewriteAvatarUrl("https://example.com/image.jpg", 100) + ) + } + + @Test + fun rewriteAvatarUrlDropQueryParamsFromGravatarUrlAndAddDefaults() { + assertEquals( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66?d=mp&s=100", + WPAvatarUtils.rewriteAvatarUrl( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66?d=wavatar&s=1000", + 100 + ) + ) + } + + @Test + fun rewriteAvatarUrlAddDefaultsToGravatarUrl() { + assertEquals( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66?d=404&s=200", + WPAvatarUtils.rewriteAvatarUrl( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66", + 200, DefaultAvatarOption.Status404 + ) + ) + } +} diff --git a/WordPress/src/jetpack/assets/licenses.html b/WordPress/src/jetpack/assets/licenses.html index 2164dddc6107..cece0d1c64b8 100644 --- a/WordPress/src/jetpack/assets/licenses.html +++ b/WordPress/src/jetpack/assets/licenses.html @@ -31,7 +31,6 @@

Additional Libraries

  • TagSoup: Copyright 2002-2008, John Cowan
  • uCrop: Copyright 2017, Yalantis
  • Simple Tool Tip: Copyright 2016, Xizhi Zhu
  • -
  • okio/okhttp: Copyright 2013 Square, Inc.
  • EventBus: Copyright 2012-2016 Markus Junginger, greenrobot
  • Mobile 4 Media: Copyright 2016, INDExOS
  • Tenor Android Core: Copyright 2017, Tenor Inc
  • diff --git a/WordPress/src/main/assets/licenses.html b/WordPress/src/main/assets/licenses.html index f774c12d914c..ef5943951f07 100644 --- a/WordPress/src/main/assets/licenses.html +++ b/WordPress/src/main/assets/licenses.html @@ -31,7 +31,6 @@

    Additional Libraries

  • TagSoup: Copyright 2002-2008, John Cowan
  • uCrop: Copyright 2017, Yalantis
  • Simple Tool Tip: Copyright 2016, Xizhi Zhu
  • -
  • okio/okhttp: Copyright 2013 Square, Inc.
  • EventBus: Copyright 2012-2016 Markus Junginger, greenrobot
  • Mobile 4 Media: Copyright 2016, INDExOS
  • Tenor Android Core: Copyright 2017, Tenor Inc
  • diff --git a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderUserTable.java b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderUserTable.java index 51451930d5e2..e8222d43127b 100644 --- a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderUserTable.java +++ b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderUserTable.java @@ -7,7 +7,7 @@ import org.wordpress.android.models.ReaderUser; import org.wordpress.android.models.ReaderUserIdList; import org.wordpress.android.models.ReaderUserList; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.SqlUtils; import java.util.ArrayList; @@ -108,7 +108,7 @@ public static ArrayList getAvatarUrls(ReaderUserIdList userIds, int max, if (c.moveToFirst()) { do { long userId = c.getLong(0); - String url = GravatarUtils.fixGravatarUrl(c.getString(1), avatarSz); + String url = WPAvatarUtils.rewriteAvatarUrl(c.getString(1), avatarSz); // add current user to the top if (userId == wpComUserId) { avatars.add(0, url); diff --git a/WordPress/src/main/java/org/wordpress/android/modules/GravatarModule.kt b/WordPress/src/main/java/org/wordpress/android/modules/GravatarModule.kt new file mode 100644 index 000000000000..771be2044923 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/modules/GravatarModule.kt @@ -0,0 +1,17 @@ +package org.wordpress.android.modules + +import com.gravatar.services.AvatarService +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@InstallIn(SingletonComponent::class) +@Module +class GravatarModule { + @Singleton + @Provides + fun provideGravatarApi( + ): AvatarService = AvatarService() +} diff --git a/WordPress/src/main/java/org/wordpress/android/networking/GravatarApi.java b/WordPress/src/main/java/org/wordpress/android/networking/GravatarApi.java deleted file mode 100644 index 3c6f8d82eb82..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/networking/GravatarApi.java +++ /dev/null @@ -1,139 +0,0 @@ -package org.wordpress.android.networking; - -import android.os.Handler; -import android.os.Looper; - -import org.wordpress.android.analytics.AnalyticsTracker; -import org.wordpress.android.util.AppLog; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.ConnectionPool; -import okhttp3.Interceptor; -import okhttp3.MultipartBody; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -public class GravatarApi { - public static final String API_BASE_URL = "https://api.gravatar.com/v1/"; - private static final int DEFAULT_TIMEOUT = 15000; - - public interface GravatarUploadListener { - void onSuccess(); - - void onError(); - } - - private static OkHttpClient createClient(final String accessToken) { - OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); - // This should help with recovery from the SocketTimeoutException - // https://github.com/square/okhttp/issues/3146#issuecomment-311158567 - httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS) - .retryOnConnectionFailure(true) - .readTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS) - .connectionPool( - new ConnectionPool(0, 1, TimeUnit.NANOSECONDS) - ); - // // uncomment the following line to add logcat logging - // httpClientBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)); - - // add oAuth token usage - httpClientBuilder.addInterceptor(new Interceptor() { - @Override - public Response intercept(Interceptor.Chain chain) throws IOException { - Request original = chain.request(); - Request.Builder requestBuilder = original.newBuilder() - .header("Authorization", "Bearer " + accessToken) - .method(original.method(), original.body()); - Request request = requestBuilder.build(); - return chain.proceed(request); - } - }); - - return httpClientBuilder.build(); - } - - public static Request prepareGravatarUpload(String email, File file) { - return new Request.Builder() - .url(API_BASE_URL + "upload-image") - .post(new MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart("account", email) - .addFormDataPart("filedata", file.getName(), new StreamingRequest(file)) - .build()) - .build(); - } - - public static void uploadGravatar(final File file, final String email, final String accessToken, - final GravatarUploadListener gravatarUploadListener) { - Request request = prepareGravatarUpload(email, file); - - createClient(accessToken).newCall(request).enqueue( - new Callback() { - @Override - public void onResponse(Call call, final Response response) throws IOException { - if (!response.isSuccessful()) { - Map properties = new HashMap<>(); - properties.put("network_response_code", response.code()); - - // response's body can only be read once so, keep it in a local variable - String responseBody; - - try { - responseBody = response.body().string(); - } catch (IOException e) { - responseBody = "null"; - } - properties.put("network_response_body", responseBody); - - AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_UNSUCCESSFUL, - properties); - AppLog.w(AppLog.T.API, "Network call unsuccessful trying to upload Gravatar: " - + responseBody); - } - - new Handler(Looper.getMainLooper()).post(new Runnable() { - @Override - public void run() { - if (response.isSuccessful()) { - gravatarUploadListener.onSuccess(); - } else { - gravatarUploadListener.onError(); - } - } - }); - } - - @Override - public void onFailure(okhttp3.Call call, final IOException e) { - String exceptionClass = e != null ? e.getClass().getCanonicalName() : "null"; - String exceptionMessage = e != null ? e.getMessage() : "null"; - - AppLog.w(AppLog.T.API, "Network call failure trying to upload Gravatar!" - + exceptionMessage); - - // Don't track exceptions caused by poor internet connectivity - if (!(e instanceof java.net.UnknownHostException)) { - Map properties = new HashMap<>(); - properties.put("network_exception_class", exceptionClass); - properties.put("network_exception_message", exceptionMessage); - AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_EXCEPTION, properties); - } - - new Handler(Looper.getMainLooper()).post(new Runnable() { - @Override - public void run() { - gravatarUploadListener.onError(); - } - }); - } - }); - } -} diff --git a/WordPress/src/main/java/org/wordpress/android/networking/StreamingRequest.java b/WordPress/src/main/java/org/wordpress/android/networking/StreamingRequest.java deleted file mode 100644 index 60c6880feb27..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/networking/StreamingRequest.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.wordpress.android.networking; - -import java.io.File; -import java.io.IOException; - -import okhttp3.MediaType; -import okhttp3.RequestBody; -import okhttp3.internal.Util; -import okio.BufferedSink; -import okio.Okio; -import okio.Source; - -public class StreamingRequest extends RequestBody { - public static final int CHUNK_SIZE = 2048; - - private final File mFile; - - public StreamingRequest(File file) { - mFile = file; - } - - @Override - public MediaType contentType() { - return MediaType.parse("multipart/form-data"); - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - Source source = null; - try { - source = Okio.source(mFile); - - while (source.read(sink.buffer(), CHUNK_SIZE) != -1) { - sink.flush(); - } - } finally { - Util.closeQuietly(source); - } - } -}; - diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/login/LoginHeaderViewHolder.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/login/LoginHeaderViewHolder.java index e677cf3f4598..3f232d9dbcc1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/login/LoginHeaderViewHolder.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/login/LoginHeaderViewHolder.java @@ -10,14 +10,18 @@ import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; +import com.gravatar.AvatarQueryOptions; +import com.gravatar.AvatarUrl; +import com.gravatar.DefaultAvatarOption; +import com.gravatar.types.Email; + import org.wordpress.android.R; import org.wordpress.android.fluxc.model.AccountModel; import org.wordpress.android.fluxc.model.SiteModel; -import org.wordpress.android.util.GravatarUtils; import org.wordpress.android.util.StringUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.image.ImageManager; -import static org.wordpress.android.util.GravatarUtils.DefaultImage.STATUS_404; import static org.wordpress.android.util.image.ImageType.AVATAR_WITHOUT_BACKGROUND; /** @@ -97,10 +101,14 @@ private int getAvatarSize(Context context) { } private String constructGravatarUrl(Context context, AccountModel account) { - return GravatarUtils.fixGravatarUrl(account.getAvatarUrl(), getAvatarSize(context), STATUS_404); + return WPAvatarUtils.rewriteAvatarUrl(account.getAvatarUrl(), getAvatarSize(context), + DefaultAvatarOption.Status404.INSTANCE); } private String constructGravatarUrl(Context context, SiteModel site) { - return GravatarUtils.gravatarFromEmail(site.getEmail(), getAvatarSize(context), STATUS_404); + return new AvatarUrl( + new Email(site.getEmail()), + new AvatarQueryOptions(getAvatarSize(context), DefaultAvatarOption.Status404.INSTANCE, null, null) + ).url().toString(); } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/signup/SignupEpilogueFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/signup/SignupEpilogueFragment.java index ece755888abb..568bb21ad430 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/signup/SignupEpilogueFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/signup/SignupEpilogueFragment.java @@ -32,6 +32,10 @@ import androidx.core.widget.NestedScrollView.OnScrollChangeListener; import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.gravatar.services.AvatarService; +import com.gravatar.services.ErrorType; +import com.gravatar.services.GravatarListener; +import com.gravatar.types.Email; import com.yalantis.ucrop.UCrop; import com.yalantis.ucrop.UCropActivity; @@ -52,7 +56,6 @@ import org.wordpress.android.fluxc.store.AccountStore.PushUsernamePayload; import org.wordpress.android.login.LoginBaseFormFragment; import org.wordpress.android.login.widgets.WPLoginInputRow; -import org.wordpress.android.networking.GravatarApi; import org.wordpress.android.ui.FullScreenDialogFragment; import org.wordpress.android.ui.FullScreenDialogFragment.OnConfirmListener; import org.wordpress.android.ui.FullScreenDialogFragment.OnDismissListener; @@ -69,10 +72,10 @@ import org.wordpress.android.ui.reader.services.update.ReaderUpdateServiceStarter; import org.wordpress.android.util.AppLog; import org.wordpress.android.util.AppLog.T; -import org.wordpress.android.util.GravatarUtils; import org.wordpress.android.util.MediaUtils; import org.wordpress.android.util.StringUtils; import org.wordpress.android.util.ToastUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.WPMediaUtils; import org.wordpress.android.util.extensions.ContextExtensionsKt; import org.wordpress.android.util.extensions.ViewExtensionsKt; @@ -88,12 +91,15 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.Objects; import javax.inject.Inject; import static org.wordpress.android.analytics.AnalyticsTracker.Stat.SIGNUP_EMAIL_EPILOGUE_GRAVATAR_GALLERY_PICKED; import static org.wordpress.android.analytics.AnalyticsTracker.Stat.SIGNUP_EMAIL_EPILOGUE_GRAVATAR_SHOT_NEW; +import kotlin.Unit; + public class SignupEpilogueFragment extends LoginBaseFormFragment implements OnConfirmListener, OnDismissListener, OnShownListener { private EditText mEditTextDisplayName; @@ -147,6 +153,7 @@ public class SignupEpilogueFragment extends LoginBaseFormFragment() { @Override - public void onSuccess() { + public void onSuccess(@NonNull Unit response) { endProgress(); - mPhotoUrl = GravatarUtils.fixGravatarUrl(mAccount.getAccount().getAvatarUrl(), + AnalyticsTracker.track(Stat.ME_GRAVATAR_UPLOADED); + mPhotoUrl = WPAvatarUtils.rewriteAvatarUrl(mAccount.getAccount().getAvatarUrl(), getResources().getDimensionPixelSize(R.dimen.avatar_sz_large)); loadAvatar(mPhotoUrl, filePath); mHeaderAvatarAdd.setVisibility(View.GONE); @@ -741,9 +748,12 @@ public void onSuccess() { } @Override - public void onError() { + public void onError(@NonNull ErrorType errorType) { endProgress(); showErrorDialogWithCloseButton(getString(R.string.signup_epilogue_error_avatar)); + Map properties = new HashMap<>(); + properties.put("error_type", errorType); + AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_EXCEPTION, properties); AppLog.e(T.NUX, "Uploading image to Gravatar failed"); } }); @@ -825,16 +835,20 @@ public void run() { try { Uri uri = MediaUtils.downloadExternalMedia(getContext(), Uri.parse(mUrl)); File file = new File(new URI(uri.toString())); - GravatarApi.uploadGravatar(file, mEmail, mToken, - new GravatarApi.GravatarUploadListener() { + mAvatarService.upload(file, new Email(mEmail), mToken, + new GravatarListener() { @Override - public void onSuccess() { + public void onSuccess(@NonNull Unit response) { AppLog.i(T.NUX, "Google avatar download and Gravatar upload succeeded."); + AnalyticsTracker.track(Stat.ME_GRAVATAR_UPLOADED); } @Override - public void onError() { + public void onError(@NonNull ErrorType errorType) { AppLog.i(T.NUX, "Google avatar download and Gravatar upload failed."); + Map properties = new HashMap<>(); + properties.put("error_type", errorType); + AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_EXCEPTION, properties); } }); } catch (NullPointerException | URISyntaxException exception) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/avatars/AvatarViewHolder.kt b/WordPress/src/main/java/org/wordpress/android/ui/avatars/AvatarViewHolder.kt index 495f8b8d9726..a606202ea5cd 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/avatars/AvatarViewHolder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/avatars/AvatarViewHolder.kt @@ -3,17 +3,17 @@ package org.wordpress.android.ui.avatars import android.view.ViewGroup import org.wordpress.android.databinding.AvatarItemBinding import org.wordpress.android.ui.avatars.TrainOfAvatarsItem.AvatarItem -import org.wordpress.android.util.GravatarUtils import org.wordpress.android.util.extensions.viewBinding import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.image.ImageType +import org.wordpress.android.util.WPAvatarUtils class AvatarViewHolder( parent: ViewGroup, private val imageManager: ImageManager ) : TrainOfAvatarsViewHolder(parent.viewBinding(AvatarItemBinding::inflate)) { fun bind(avatarDetails: AvatarItem) = with(binding) { - val likerAvatarUrl = GravatarUtils.fixGravatarUrl( + val likerAvatarUrl = WPAvatarUtils.rewriteAvatarUrl( avatarDetails.userAvatarUrl, itemView.context.resources.getDimensionPixelSize(AVATAR_SIZE_DIMEN) ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/comments/CommentDetailFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/comments/CommentDetailFragment.java index 555a834cf46e..3a89b0e25e65 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/comments/CommentDetailFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/comments/CommentDetailFragment.java @@ -31,6 +31,9 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.elevation.ElevationOverlayProvider; import com.google.android.material.snackbar.Snackbar; +import com.gravatar.AvatarQueryOptions; +import com.gravatar.AvatarUrl; +import com.gravatar.types.Email; import org.apache.commons.text.StringEscapeUtils; import org.greenrobot.eventbus.EventBus; @@ -96,11 +99,11 @@ import org.wordpress.android.util.ColorUtils; import org.wordpress.android.util.DateTimeUtils; import org.wordpress.android.util.EditTextUtils; -import org.wordpress.android.util.GravatarUtils; import org.wordpress.android.util.HtmlUtils; import org.wordpress.android.util.NetworkUtils; import org.wordpress.android.util.SiteUtils; import org.wordpress.android.util.ToastUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.WPLinkMovementMethod; import org.wordpress.android.util.analytics.AnalyticsUtils; import org.wordpress.android.util.extensions.ContextExtensionsKt; @@ -814,9 +817,10 @@ private void showCommentWhenNonNull( int avatarSz = getResources().getDimensionPixelSize(R.dimen.avatar_sz_large); String avatarUrl = ""; if (comment.getAuthorProfileImageUrl() != null) { - avatarUrl = GravatarUtils.fixGravatarUrl(comment.getAuthorProfileImageUrl(), avatarSz); + avatarUrl = WPAvatarUtils.rewriteAvatarUrl(comment.getAuthorProfileImageUrl(), avatarSz); } else if (comment.getAuthorEmail() != null) { - avatarUrl = GravatarUtils.gravatarFromEmail(comment.getAuthorEmail(), avatarSz); + avatarUrl = new AvatarUrl(new Email(comment.getAuthorEmail()), + new AvatarQueryOptions(avatarSz, null, null, null)).url().toString(); } mImageManager.loadIntoCircle(binding.imageAvatar, ImageType.AVATAR_WITH_BACKGROUND, avatarUrl); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/comments/unified/UnifiedCommentListAdapter.kt b/WordPress/src/main/java/org/wordpress/android/ui/comments/unified/UnifiedCommentListAdapter.kt index e1f1997ed617..c84c375e05c2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/comments/unified/UnifiedCommentListAdapter.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/comments/unified/UnifiedCommentListAdapter.kt @@ -13,7 +13,7 @@ import org.wordpress.android.ui.comments.unified.UnifiedCommentListItem.NextPage import org.wordpress.android.ui.comments.unified.UnifiedCommentListItem.SubHeader import org.wordpress.android.ui.utils.AnimationUtilsWrapper import org.wordpress.android.ui.utils.UiHelpers -import org.wordpress.android.util.GravatarUtilsWrapper +import org.wordpress.android.util.WPAvatarUtilsWrapper import org.wordpress.android.util.image.ImageManager import org.wordpress.android.viewmodel.ResourceProvider import javax.inject.Inject @@ -35,7 +35,7 @@ class UnifiedCommentListAdapter(context: Context) : ListAdapter LoadStateViewHolder(parent) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/comments/unified/UnifiedCommentViewHolder.kt b/WordPress/src/main/java/org/wordpress/android/ui/comments/unified/UnifiedCommentViewHolder.kt index b0b79887eca7..1caae111024a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/comments/unified/UnifiedCommentViewHolder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/comments/unified/UnifiedCommentViewHolder.kt @@ -2,13 +2,15 @@ package org.wordpress.android.ui.comments.unified import android.text.TextUtils import android.view.ViewGroup +import com.gravatar.AvatarQueryOptions +import com.gravatar.AvatarUrl +import com.gravatar.types.Email import org.wordpress.android.R import org.wordpress.android.databinding.CommentListItemBinding import org.wordpress.android.ui.comments.unified.UnifiedCommentListItem.Comment import org.wordpress.android.ui.utils.AnimationUtilsWrapper import org.wordpress.android.ui.utils.UiHelpers -import org.wordpress.android.util.GravatarUtils -import org.wordpress.android.util.GravatarUtilsWrapper +import org.wordpress.android.util.WPAvatarUtilsWrapper import org.wordpress.android.util.extensions.viewBinding import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.image.ImageType.AVATAR_WITH_BACKGROUND @@ -21,7 +23,7 @@ class UnifiedCommentViewHolder( private val uiHelpers: UiHelpers, private val commentListUiUtils: CommentListUiUtils, private val resourceProvider: ResourceProvider, - private val gravatarUtilsWrapper: GravatarUtilsWrapper, + private val avatarUtilsWrapper: WPAvatarUtilsWrapper, private val animationUtilsWrapper: AnimationUtilsWrapper ) : UnifiedCommentListViewHolder(parent.viewBinding(CommentListItemBinding::inflate)) { fun bind(item: Comment) = with(binding) { @@ -76,15 +78,15 @@ class UnifiedCommentViewHolder( private fun getGravatarUrl(comment: Comment): String { return if (!TextUtils.isEmpty(comment.authorAvatarUrl)) { - gravatarUtilsWrapper.fixGravatarUrl( + avatarUtilsWrapper.rewriteAvatarUrl( comment.authorAvatarUrl, resourceProvider.getDimensionPixelSize(R.dimen.avatar_sz_medium) ) } else if (!TextUtils.isEmpty(comment.authorEmail)) { - GravatarUtils.gravatarFromEmail( - comment.authorEmail, - resourceProvider.getDimensionPixelSize(R.dimen.avatar_sz_medium) - ) + AvatarUrl( + Email(comment.authorEmail), + AvatarQueryOptions(preferredSize = resourceProvider.getDimensionPixelSize(R.dimen.avatar_sz_medium)) + ).url().toString() } else { "" } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/compose/views/TrainOfAvatarsView.kt b/WordPress/src/main/java/org/wordpress/android/ui/compose/views/TrainOfAvatarsView.kt index c887301a7ad5..ad76a38cc315 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/compose/views/TrainOfAvatarsView.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/compose/views/TrainOfAvatarsView.kt @@ -22,7 +22,7 @@ import org.wordpress.android.ui.compose.components.TrainOfIcons import org.wordpress.android.ui.compose.components.TrainOfIconsModel import org.wordpress.android.ui.compose.theme.AppTheme import org.wordpress.android.util.DisplayUtils -import org.wordpress.android.util.GravatarUtils +import org.wordpress.android.util.WPAvatarUtils @Suppress("MemberVisibilityCanBePrivate", "unused") class TrainOfAvatarsView @JvmOverloads constructor( @@ -113,7 +113,7 @@ class TrainOfAvatarsView @JvmOverloads constructor( // returning null for a model will cause the Composable to render a placeholder private fun avatarModels(): List = avatarsState.value - .map { GravatarUtils.fixGravatarUrl(it.userAvatarUrl, iconSize) } + .map { WPAvatarUtils.rewriteAvatarUrl(it.userAvatarUrl, iconSize) } .map { TrainOfIconsModel( it.takeIf { gravatarUrl -> gravatarUrl.isNotEmpty() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/engagement/LikedItemViewHolder.kt b/WordPress/src/main/java/org/wordpress/android/ui/engagement/LikedItemViewHolder.kt index 55347a487000..d86bbfe11fc2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/engagement/LikedItemViewHolder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/engagement/LikedItemViewHolder.kt @@ -9,7 +9,7 @@ import org.wordpress.android.R import org.wordpress.android.ui.engagement.AuthorName.AuthorNameCharSequence import org.wordpress.android.ui.engagement.AuthorName.AuthorNameString import org.wordpress.android.ui.engagement.EngageItem.LikedItem -import org.wordpress.android.util.GravatarUtils +import org.wordpress.android.util.WPAvatarUtils import org.wordpress.android.util.extensions.getDrawableResIdFromAttribute import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.image.ImageType @@ -33,7 +33,7 @@ class LikedItemViewHolder( this.name.text = authorName this.snippet.text = likedItem.postOrCommentText - val avatarUrl = GravatarUtils.fixGravatarUrl( + val avatarUrl = WPAvatarUtils.rewriteAvatarUrl( likedItem.authorAvatarUrl, rootView.context.resources.getDimensionPixelSize(R.dimen.avatar_sz_small) ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/engagement/LikerViewHolder.kt b/WordPress/src/main/java/org/wordpress/android/ui/engagement/LikerViewHolder.kt index f6b81e415bd1..e4fc6b615215 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/engagement/LikerViewHolder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/engagement/LikerViewHolder.kt @@ -7,7 +7,7 @@ import android.widget.TextView import org.wordpress.android.R import org.wordpress.android.ui.engagement.EngageItem.Liker import org.wordpress.android.ui.engagement.EngagedListNavigationEvent.OpenUserProfileBottomSheet.UserProfile -import org.wordpress.android.util.GravatarUtils +import org.wordpress.android.util.WPAvatarUtils import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.image.ImageType import org.wordpress.android.viewmodel.ResourceProvider @@ -30,7 +30,7 @@ class LikerViewHolder( liker.login } - val likerAvatarUrl = GravatarUtils.fixGravatarUrl( + val likerAvatarUrl = WPAvatarUtils.rewriteAvatarUrl( liker.userAvatarUrl, likerRootView.context.resources.getDimensionPixelSize(R.dimen.avatar_sz_medium) ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/engagement/UserProfileBottomSheetFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/engagement/UserProfileBottomSheetFragment.kt index 76b2484b91bb..b0c6e5a13d83 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/engagement/UserProfileBottomSheetFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/engagement/UserProfileBottomSheetFragment.kt @@ -19,10 +19,10 @@ import org.wordpress.android.R import org.wordpress.android.WordPress import org.wordpress.android.ui.engagement.BottomSheetUiState.UserProfileUiState import org.wordpress.android.ui.utils.UiHelpers -import org.wordpress.android.util.GravatarUtils import org.wordpress.android.util.PhotonUtils import org.wordpress.android.util.PhotonUtils.Quality.HIGH import org.wordpress.android.util.UrlUtils +import org.wordpress.android.util.WPAvatarUtils import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.image.ImageType.AVATAR_WITH_BACKGROUND import org.wordpress.android.util.image.ImageType.BLAVATAR @@ -114,7 +114,7 @@ class UserProfileBottomSheetFragment : BottomSheetDialogFragment() { imageManager.loadIntoCircle( userAvatar, AVATAR_WITH_BACKGROUND, - GravatarUtils.fixGravatarUrl(state.userAvatarUrl, avatarSz) + WPAvatarUtils.rewriteAvatarUrl(state.userAvatarUrl, avatarSz) ) userName.text = state.userName userLogin.text = if (state.userLogin.isNotBlank()) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.kt index 347e700f21d3..0b823574eaf1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.kt @@ -20,6 +20,10 @@ import androidx.fragment.app.viewModels import androidx.lifecycle.ViewModelProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar +import com.gravatar.services.AvatarService +import com.gravatar.services.ErrorType +import com.gravatar.services.GravatarListener +import com.gravatar.types.Email import com.yalantis.ucrop.UCrop import com.yalantis.ucrop.UCrop.Options import com.yalantis.ucrop.UCropActivity @@ -36,6 +40,7 @@ import org.wordpress.android.analytics.AnalyticsTracker.Stat.ME_GRAVATAR_GALLERY import org.wordpress.android.analytics.AnalyticsTracker.Stat.ME_GRAVATAR_SHOT_NEW import org.wordpress.android.analytics.AnalyticsTracker.Stat.ME_GRAVATAR_TAPPED import org.wordpress.android.analytics.AnalyticsTracker.Stat.ME_GRAVATAR_UPLOADED +import org.wordpress.android.analytics.AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_EXCEPTION import org.wordpress.android.databinding.MeFragmentBinding import org.wordpress.android.designsystem.DesignSystemActivity import org.wordpress.android.fluxc.Dispatcher @@ -44,8 +49,6 @@ import org.wordpress.android.fluxc.store.AccountStore.OnAccountChanged import org.wordpress.android.fluxc.store.PostStore import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.models.JetpackPoweredScreen -import org.wordpress.android.networking.GravatarApi -import org.wordpress.android.networking.GravatarApi.GravatarUploadListener import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.RequestCodes import org.wordpress.android.ui.about.UnifiedAboutActivity @@ -145,6 +148,9 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { @Inject lateinit var domainManagementFeatureConfig: DomainManagementFeatureConfig + @Inject + lateinit var avatarService: AvatarService + private val viewModel: MeViewModel by viewModels() private val shouldShowDomainButton @@ -669,21 +675,19 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { } val file = File(filePath) if (!file.exists()) { - ToastUtils.showToast( - activity, - R.string.error_locating_image, - SHORT - ) + ToastUtils.showToast(activity, R.string.error_locating_image, SHORT) return } binding?.showGravatarProgressBar(true) - GravatarApi.uploadGravatar(file, accountStore.account.email, accountStore.accessToken, - object : GravatarUploadListener { - override fun onSuccess() { + avatarService.upload(file, Email(accountStore.account.email), accountStore.accessToken.orEmpty(), + object : GravatarListener { + override fun onSuccess(response: Unit) { + AnalyticsTracker.track(ME_GRAVATAR_UPLOADED) EventBus.getDefault().post(GravatarUploadFinished(filePath, true)) } - override fun onError() { + override fun onError(errorType: ErrorType) { + AnalyticsTracker.track(ME_GRAVATAR_UPLOAD_EXCEPTION, mapOf("error_type" to errorType.name)) EventBus.getDefault().post(GravatarUploadFinished(filePath, false)) } }) @@ -695,7 +699,6 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { fun onEventMainThread(event: GravatarUploadFinished) { binding?.showGravatarProgressBar(false) if (event.success) { - AnalyticsTracker.track(ME_GRAVATAR_UPLOADED) binding?.loadAvatar(event.filePath) binding?.gravatarSyncView?.gravatarSyncContainer?.visibility = View.VISIBLE } else { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModel.kt index 979d709290ed..29584be672ee 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModel.kt @@ -65,7 +65,7 @@ import org.wordpress.android.ui.utils.UiString import org.wordpress.android.ui.utils.UiString.UiStringRes import org.wordpress.android.util.AppLog import org.wordpress.android.util.AppLog.T -import org.wordpress.android.util.GravatarUtilsWrapper +import org.wordpress.android.util.WPAvatarUtilsWrapper import org.wordpress.android.util.JetpackMigrationLanguageUtil import org.wordpress.android.util.LocaleManagerWrapper import org.wordpress.android.util.SiteUtilsWrapper @@ -81,7 +81,7 @@ class JetpackMigrationViewModel @Inject constructor( @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, private val dispatcher: Dispatcher, private val siteUtilsWrapper: SiteUtilsWrapper, - private val gravatarUtilsWrapper: GravatarUtilsWrapper, + private val avatarUtilsWrapper: WPAvatarUtilsWrapper, private val contextProvider: ContextProvider, private val preventDuplicateNotifsFeatureConfig: PreventDuplicateNotifsFeatureConfig, private val appPrefsWrapper: AppPrefsWrapper, @@ -386,7 +386,7 @@ class JetpackMigrationViewModel @Inject constructor( postActionEvent(FinishActivity) } - private fun resizeAvatarUrl(avatarUrl: String) = gravatarUtilsWrapper.fixGravatarUrlWithResource( + private fun resizeAvatarUrl(avatarUrl: String) = avatarUtilsWrapper.rewriteAvatarUrlWithResource( avatarUrl, R.dimen.jp_migration_user_avatar_size ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/utils/MeGravatarLoader.kt b/WordPress/src/main/java/org/wordpress/android/ui/main/utils/MeGravatarLoader.kt index ecd43e0eb385..f4b6ad1464fc 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/utils/MeGravatarLoader.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/utils/MeGravatarLoader.kt @@ -5,7 +5,7 @@ import android.widget.ImageView import org.wordpress.android.R import org.wordpress.android.WordPress import org.wordpress.android.ui.prefs.AppPrefsWrapper -import org.wordpress.android.util.GravatarUtils +import org.wordpress.android.util.WPAvatarUtils import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.image.ImageManager.RequestListener import org.wordpress.android.util.image.ImageType @@ -58,6 +58,6 @@ class MeGravatarLoader @Inject constructor( fun constructGravatarUrl(rawAvatarUrl: String): String { val avatarSz = resourseProvider.getDimensionPixelSize(R.dimen.avatar_sz_extra_small) - return GravatarUtils.fixGravatarUrl(rawAvatarUrl, avatarSz) + return WPAvatarUtils.rewriteAvatarUrl(rawAvatarUrl, avatarSz) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/CommentUserNoteBlock.java b/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/CommentUserNoteBlock.java index f01012a50da9..d655626e83f3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/CommentUserNoteBlock.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/CommentUserNoteBlock.java @@ -19,7 +19,7 @@ import org.wordpress.android.ui.notifications.utils.NotificationsUtilsWrapper; import org.wordpress.android.util.extensions.ContextExtensionsKt; import org.wordpress.android.util.DateTimeUtils; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.image.ImageManager; import org.wordpress.android.util.image.ImageType; @@ -116,7 +116,7 @@ private void setUserCommentSite() { private void setUserAvatar() { String imageUrl = ""; if (hasImageMediaItem()) { - imageUrl = GravatarUtils.fixGravatarUrl(getNoteMediaItem().getUrl(), getAvatarSize()); + imageUrl = WPAvatarUtils.rewriteAvatarUrl(getNoteMediaItem().getUrl(), getAvatarSize()); mNoteBlockHolder.mAvatarImageView.setContentDescription( mContext.getString(R.string.profile_picture, getNoteText().toString()) ); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/HeaderNoteBlock.java b/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/HeaderNoteBlock.java index 3d4d8b5b0c82..603b977d059c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/HeaderNoteBlock.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/HeaderNoteBlock.java @@ -14,7 +14,7 @@ import org.wordpress.android.fluxc.tools.FormattableContent; import org.wordpress.android.ui.notifications.utils.NotificationsUtilsWrapper; import org.wordpress.android.util.FormattableContentUtilsKt; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.image.ImageManager; import org.wordpress.android.util.image.ImageType; @@ -123,7 +123,8 @@ public void onClick(View v) { }; private String getAvatarUrl() { - return GravatarUtils.fixGravatarUrl(FormattableContentUtilsKt.getMediaUrlOrEmpty(getHeader(0), 0), mAvatarSize); + return WPAvatarUtils.rewriteAvatarUrl(FormattableContentUtilsKt.getMediaUrlOrEmpty( + getHeader(0), 0), mAvatarSize); } private String getUserUrl() { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/UserNoteBlock.java b/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/UserNoteBlock.java index 18182d76620a..8702d938f7f6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/UserNoteBlock.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/notifications/blocks/UserNoteBlock.java @@ -13,7 +13,7 @@ import org.wordpress.android.fluxc.tools.FormattableContent; import org.wordpress.android.ui.notifications.utils.NotificationsUtilsWrapper; import org.wordpress.android.util.FormattableContentUtilsKt; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.image.ImageManager; import org.wordpress.android.util.image.ImageType; @@ -93,7 +93,7 @@ public View configureView(View view) { String imageUrl = ""; if (hasImageMediaItem()) { - imageUrl = GravatarUtils.fixGravatarUrl(getNoteMediaItem().getUrl(), getAvatarSize()); + imageUrl = WPAvatarUtils.rewriteAvatarUrl(getNoteMediaItem().getUrl(), getAvatarSize()); if (!TextUtils.isEmpty(getUserUrl())) { //noinspection AndroidLintClickableViewAccessibility noteBlockHolder.mAvatarImageView.setOnTouchListener(mOnGravatarTouchListener); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/people/PeopleListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/people/PeopleListFragment.java index 0b54712b2919..efd9979b7d62 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/people/PeopleListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/people/PeopleListFragment.java @@ -43,7 +43,7 @@ import org.wordpress.android.ui.prefs.AppPrefs; import org.wordpress.android.ui.utils.UiHelpers; import org.wordpress.android.util.AppLog; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.JetpackBrandingUtils; import org.wordpress.android.util.NetworkUtils; import org.wordpress.android.util.image.ImageManager; @@ -442,7 +442,7 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi final Person person = getPerson(position); if (person != null) { - String avatarUrl = GravatarUtils.fixGravatarUrl(person.getAvatarUrl(), mAvatarSz); + String avatarUrl = WPAvatarUtils.rewriteAvatarUrl(person.getAvatarUrl(), mAvatarSz); mImageManager.loadIntoCircle(peopleViewHolder.mImgAvatar, ImageType.AVATAR_WITH_BACKGROUND, avatarUrl); peopleViewHolder.mTxtDisplayName.setText(StringEscapeUtils.unescapeHtml4(person.getDisplayName())); if (person.getRole() != null) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/people/PersonDetailFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/people/PersonDetailFragment.java index 0a75b0f9a5e5..6f901c97faa1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/people/PersonDetailFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/people/PersonDetailFragment.java @@ -31,7 +31,7 @@ import org.wordpress.android.ui.mysite.jetpackbadge.JetpackPoweredBottomSheetFragment; import org.wordpress.android.ui.utils.UiHelpers; import org.wordpress.android.util.AppLog; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.JetpackBrandingUtils; import org.wordpress.android.util.image.ImageManager; import org.wordpress.android.util.image.ImageType; @@ -183,7 +183,7 @@ void refreshPersonDetails() { Person person = loadPerson(); if (person != null) { int avatarSz = getResources().getDimensionPixelSize(R.dimen.people_avatar_sz); - String avatarUrl = GravatarUtils.fixGravatarUrl(person.getAvatarUrl(), avatarSz); + String avatarUrl = WPAvatarUtils.rewriteAvatarUrl(person.getAvatarUrl(), avatarSz); mImageManager.loadIntoCircle(mAvatarImageView, ImageType.AVATAR_WITH_BACKGROUND, avatarUrl); mDisplayNameTextView.setText(StringEscapeUtils.unescapeHtml4(person.getDisplayName())); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/adapters/AuthorSelectionAdapter.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/adapters/AuthorSelectionAdapter.kt index 360fc0926632..21c8ac075cd1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/adapters/AuthorSelectionAdapter.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/adapters/AuthorSelectionAdapter.kt @@ -15,7 +15,7 @@ import org.wordpress.android.WordPress import org.wordpress.android.ui.posts.AuthorFilterListItemUIState import org.wordpress.android.ui.posts.AuthorFilterSelection import org.wordpress.android.ui.utils.UiHelpers -import org.wordpress.android.util.GravatarUtils +import org.wordpress.android.util.WPAvatarUtils import org.wordpress.android.util.extensions.getColorFromAttribute import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.image.ImageType.NO_PLACEHOLDER @@ -122,7 +122,7 @@ class AuthorSelectionAdapter(context: Context) : BaseAdapter() { } is AuthorFilterListItemUIState.Me -> { val avatarSize = image.resources.getDimensionPixelSize(R.dimen.avatar_sz_small) - val url = GravatarUtils.fixGravatarUrl(state.avatarUrl, avatarSize) + val url = WPAvatarUtils.rewriteAvatarUrl(state.avatarUrl ?: "", avatarSize) imageManager.loadIntoCircle(image, NO_PLACEHOLDER, url) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailUiStateBuilder.kt b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailUiStateBuilder.kt index 28e7a30fca3b..fb25d19d4a26 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailUiStateBuilder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailUiStateBuilder.kt @@ -40,7 +40,7 @@ import org.wordpress.android.util.AppLog import org.wordpress.android.util.AppLog.T import org.wordpress.android.util.DateTimeUtilsWrapper import org.wordpress.android.util.DisplayUtilsWrapper -import org.wordpress.android.util.GravatarUtilsWrapper +import org.wordpress.android.util.WPAvatarUtilsWrapper import org.wordpress.android.viewmodel.ContextProvider import org.wordpress.android.viewmodel.ResourceProvider import javax.inject.Inject @@ -59,7 +59,7 @@ class ReaderPostDetailUiStateBuilder @Inject constructor( private val htmlUtilsWrapper: HtmlUtilsWrapper, private val htmlMessageUtils: HtmlMessageUtils, private val dateTimeUtilsWrapper: DateTimeUtilsWrapper, - private val gravatarUtilsWrapper: GravatarUtilsWrapper, + private val avatarUtilsWrapper: WPAvatarUtilsWrapper, private val threadedCommentsUtils: ThreadedCommentsUtils, resourceProvider: ResourceProvider ) { @@ -141,7 +141,7 @@ class ReaderPostDetailUiStateBuilder @Inject constructor( readerComment.published ) ), - avatarUrl = gravatarUtilsWrapper.fixGravatarUrl( + avatarUrl = avatarUtilsWrapper.rewriteAvatarUrl( readerComment.authorAvatar, contextProvider.getContext().resources.getDimensionPixelSize( R.dimen.avatar_sz_extra_small diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderCommentAdapter.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderCommentAdapter.java index c310f44e143a..9179bf1760e7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderCommentAdapter.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderCommentAdapter.java @@ -53,7 +53,7 @@ import org.wordpress.android.util.extensions.ContextExtensionsKt; import org.wordpress.android.util.DateTimeUtils; import org.wordpress.android.util.DisplayUtils; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.NetworkUtils; import org.wordpress.android.util.ToastUtils; import org.wordpress.android.util.analytics.AnalyticsUtils.AnalyticsCommentActionSource; @@ -308,7 +308,7 @@ public void onClick(View view) { } commentHolder.mTxtDate.setText(DateTimeUtils.javaDateToTimeSpan(dtPublished, WordPress.getContext())); - String avatarUrl = GravatarUtils.fixGravatarUrl(comment.getAuthorAvatar(), mAvatarSz); + String avatarUrl = WPAvatarUtils.rewriteAvatarUrl(comment.getAuthorAvatar(), mAvatarSz); mImageManager.loadIntoCircle(commentHolder.mImgAvatar, ImageType.AVATAR, avatarUrl); // tapping avatar or author name opens blog preview diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java index 176f696f6126..5ae4c5d68fa7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java @@ -59,7 +59,7 @@ import org.wordpress.android.util.AppLog.T; import org.wordpress.android.util.ColorUtils; import org.wordpress.android.util.DisplayUtils; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.NetworkUtils; import org.wordpress.android.util.NetworkUtilsWrapper; import org.wordpress.android.util.SiteUtils; @@ -383,11 +383,11 @@ private void renderXPost(int position, ReaderXPostViewHolder holder) { mImageManager .loadIntoCircle(holder.mImgAvatar, ImageType.AVATAR, - GravatarUtils.fixGravatarUrl(post.getPostAvatar(), mAvatarSzSmall)); + WPAvatarUtils.rewriteAvatarUrl(post.getPostAvatar(), mAvatarSzSmall)); mImageManager.loadIntoCircle(holder.mImgBlavatar, SiteUtils.getSiteImageType(post.isP2orA8C(), BlavatarShape.CIRCULAR), - GravatarUtils.fixGravatarUrl(post.getBlogImageUrl(), mAvatarSzSmall)); + WPAvatarUtils.rewriteAvatarUrl(post.getBlogImageUrl(), mAvatarSzSmall)); holder.mTxtTitle.setText(ReaderXPostUtils.getXPostTitle(post)); holder.mTxtSubtitle.setText(ReaderXPostUtils.getXPostSubtitleHtml(post)); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderUserAdapter.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderUserAdapter.java index 844ac7e670f3..7594b8b9b64b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderUserAdapter.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderUserAdapter.java @@ -17,7 +17,7 @@ import org.wordpress.android.ui.reader.ReaderActivityLauncher; import org.wordpress.android.ui.reader.ReaderInterfaces.DataLoadedListener; import org.wordpress.android.ui.reader.tracker.ReaderTracker; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.image.ImageManager; import org.wordpress.android.util.image.ImageType; @@ -95,7 +95,7 @@ public void onClick(View v) { } mImageManager.loadIntoCircle(holder.mImgAvatar, ImageType.AVATAR, - GravatarUtils.fixGravatarUrl(user.getAvatarUrl(), mAvatarSz)); + WPAvatarUtils.rewriteAvatarUrl(user.getAvatarUrl(), mAvatarSz)); } @Override diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/discover/ReaderPostUiStateBuilder.kt b/WordPress/src/main/java/org/wordpress/android/ui/reader/discover/ReaderPostUiStateBuilder.kt index d5dbaf10043e..d9dfc8b418ba 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/discover/ReaderPostUiStateBuilder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/discover/ReaderPostUiStateBuilder.kt @@ -50,7 +50,7 @@ import org.wordpress.android.ui.utils.UiString.UiStringRes import org.wordpress.android.ui.utils.UiString.UiStringResWithParams import org.wordpress.android.ui.utils.UiString.UiStringText import org.wordpress.android.util.DateTimeUtilsWrapper -import org.wordpress.android.util.GravatarUtilsWrapper +import org.wordpress.android.util.WPAvatarUtilsWrapper import org.wordpress.android.util.SiteUtils import org.wordpress.android.util.UrlUtilsWrapper import org.wordpress.android.util.image.BlavatarShape.CIRCULAR @@ -66,7 +66,7 @@ private const val READER_RECOMMENDED_BLOGS_LIST_SIZE_LIMIT = 3 class ReaderPostUiStateBuilder @Inject constructor( private val accountStore: AccountStore, private val urlUtilsWrapper: UrlUtilsWrapper, - private val gravatarUtilsWrapper: GravatarUtilsWrapper, + private val avatarUtilsWrapper: WPAvatarUtilsWrapper, private val dateTimeUtilsWrapper: DateTimeUtilsWrapper, private val readerImageScannerProvider: ReaderImageScannerProvider, private val readerUtilsWrapper: ReaderUtilsWrapper, @@ -326,7 +326,7 @@ class ReaderPostUiStateBuilder @Inject constructor( avatarOrBlavatarUrl = buildAvatarOrBlavatarUrl(post), isAuthorAvatarVisible = isP2Post || (isReaderImprovementsEnabled && post.hasBlogImageUrl()), blavatarType = SiteUtils.getSiteImageType(isP2Post, CIRCULAR), - authorAvatarUrl = gravatarUtilsWrapper.fixGravatarUrlWithResource( + authorAvatarUrl = avatarUtilsWrapper.rewriteAvatarUrlWithResource( post.postAvatar, R.dimen.avatar_sz_medium ), @@ -348,7 +348,7 @@ class ReaderPostUiStateBuilder @Inject constructor( avatarOrBlavatarUrl = buildAvatarOrBlavatarUrl(post), isAuthorAvatarVisible = isP2Post, blavatarType = SiteUtils.getSiteImageType(isP2Post, CIRCULAR), - authorAvatarUrl = gravatarUtilsWrapper.fixGravatarUrlWithResource( + authorAvatarUrl = avatarUtilsWrapper.rewriteAvatarUrlWithResource( post.postAvatar, R.dimen.avatar_sz_medium ), @@ -452,7 +452,7 @@ class ReaderPostUiStateBuilder @Inject constructor( private fun buildAvatarOrBlavatarUrl(post: ReaderPost) = post.takeIf { it.hasBlogImageUrl() } ?.blogImageUrl - ?.let { gravatarUtilsWrapper.fixGravatarUrlWithResource(it, R.dimen.avatar_sz_medium) } + ?.let { avatarUtilsWrapper.rewriteAvatarUrlWithResource(it, R.dimen.avatar_sz_medium) } private fun buildDateLine(post: ReaderPost) = dateTimeUtilsWrapper.javaDateToTimeSpan(post.getDisplayDate(dateTimeUtilsWrapper)) @@ -463,7 +463,7 @@ class ReaderPostUiStateBuilder @Inject constructor( onDiscoverSectionClicked: (Long, Long) -> Unit ): DiscoverLayoutUiState { val discoverText = discoverData.attributionHtml - val discoverAvatarUrl = gravatarUtilsWrapper.fixGravatarUrlWithResource( + val discoverAvatarUrl = avatarUtilsWrapper.rewriteAvatarUrlWithResource( discoverData.avatarUrl, R.dimen.avatar_sz_small ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/suggestion/adapters/SuggestionAdapter.java b/WordPress/src/main/java/org/wordpress/android/ui/suggestion/adapters/SuggestionAdapter.java index 41b005e9664e..8014a6939c1b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/suggestion/adapters/SuggestionAdapter.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/suggestion/adapters/SuggestionAdapter.java @@ -18,7 +18,7 @@ import org.wordpress.android.R; import org.wordpress.android.WordPress; import org.wordpress.android.ui.suggestion.Suggestion; -import org.wordpress.android.util.GravatarUtils; +import org.wordpress.android.util.WPAvatarUtils; import org.wordpress.android.util.image.ImageManager; import org.wordpress.android.util.image.ImageType; @@ -106,7 +106,7 @@ public View getView(int position, View convertView, ViewGroup parent) { Suggestion suggestion = getItem(position); if (suggestion != null) { - String avatarUrl = GravatarUtils.fixGravatarUrl(suggestion.getAvatarUrl(), mAvatarSz); + String avatarUrl = WPAvatarUtils.rewriteAvatarUrl(suggestion.getAvatarUrl(), mAvatarSz); mImageManager.loadIntoCircle(holder.mImgAvatar, ImageType.AVATAR_WITH_BACKGROUND, avatarUrl); String value = mPrefix + suggestion.getValue(); holder.mValue.setText(value); diff --git a/WordPress/src/main/java/org/wordpress/android/util/GravatarUtilsWrapper.kt b/WordPress/src/main/java/org/wordpress/android/util/GravatarUtilsWrapper.kt deleted file mode 100644 index e31b4e95bf05..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/util/GravatarUtilsWrapper.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.wordpress.android.util - -import android.content.Context -import androidx.annotation.DimenRes -import dagger.Reusable -import javax.inject.Inject - -/** - * Injectable wrapper around GravatarUtils. - * - * GravatarUtils interface is consisted of static methods, which makes the client code difficult to test/mock. - * Main purpose of this wrapper is to make testing easier. - */ -@Reusable -class GravatarUtilsWrapper @Inject constructor(private val appContext: Context) { - fun fixGravatarUrl(imageUrl: String, avatarSz: Int): String { - return GravatarUtils.fixGravatarUrl(imageUrl, avatarSz) - } - - fun fixGravatarUrlWithResource(imageUrl: String, @DimenRes avatarSzRes: Int): String { - return GravatarUtils.fixGravatarUrl(imageUrl, appContext.resources.getDimensionPixelSize(avatarSzRes)) - } -} diff --git a/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtils.java b/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtils.java new file mode 100644 index 000000000000..2c6e56b60d75 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtils.java @@ -0,0 +1,59 @@ +package org.wordpress.android.util; + +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.gravatar.AvatarQueryOptions; +import com.gravatar.AvatarUrl; +import com.gravatar.DefaultAvatarOption; +import com.gravatar.DefaultAvatarOption.MysteryPerson; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * This file contains utility functions for working with avatar urls coming from WordPress accounts. + *

    + * see https://docs.gravatar.com/general/images/ + */ +public class WPAvatarUtils { + private WPAvatarUtils() { + throw new IllegalStateException("Utility class"); + } + public static final DefaultAvatarOption DEFAULT_AVATAR = MysteryPerson.INSTANCE; + + /** + * Remove all query params from a gravatar url and set them to the given size and + * default image. If the imageUrl parameters is not a gravatar link, + * then use Photon to resize according to the avatarSz parameter. + * + * @param imageUrl the url of the avatar image + * @param avatarSz the size of the avatar image + * @param defaultImage the default image to use if the user doesn't have a gravatar + * @return the fixed url + */ + public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatarSz, + @Nullable DefaultAvatarOption defaultImage) { + if (TextUtils.isEmpty(imageUrl)) { + return ""; + } + + // if this isn't a gravatar image, return as resized photon image url + if (!imageUrl.contains("gravatar.com")) { + return PhotonUtils.getPhotonImageUrl(imageUrl, avatarSz, avatarSz); + } else { + try { + return new AvatarUrl(new URL(imageUrl), + new AvatarQueryOptions(avatarSz, defaultImage, null, null)).url().toString(); + } catch (MalformedURLException e) { + return ""; + } + } + } + + public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatarSz) { + return rewriteAvatarUrl(imageUrl, avatarSz, DEFAULT_AVATAR); + } +} diff --git a/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtilsWrapper.kt b/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtilsWrapper.kt new file mode 100644 index 000000000000..493cfcf30fc1 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtilsWrapper.kt @@ -0,0 +1,24 @@ +package org.wordpress.android.util + +import android.content.Context +import androidx.annotation.DimenRes +import dagger.Reusable +import javax.inject.Inject + +/** + * Injectable wrapper around GravatarUtils. + * + * WordPressAvatarUtils interface is consisted of static methods, which makes the client code difficult to test/mock. + * Main purpose of this wrapper is to make testing easier. + */ +@Reusable +class WPAvatarUtilsWrapper @Inject constructor(private val appContext: Context) { + fun rewriteAvatarUrl(imageUrl: String, avatarSz: Int): String { + return WPAvatarUtils.rewriteAvatarUrl(imageUrl, avatarSz) + } + + fun rewriteAvatarUrlWithResource(imageUrl: String, @DimenRes avatarSzRes: Int): String { + return WPAvatarUtils.rewriteAvatarUrl(imageUrl, + appContext.resources.getDimensionPixelSize(avatarSzRes)) + } +} diff --git a/WordPress/src/test/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModelTest.kt index 984812bf8e71..6e33aee504e3 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModelTest.kt @@ -40,7 +40,7 @@ import org.wordpress.android.ui.main.jetpack.migration.JetpackMigrationViewModel import org.wordpress.android.ui.main.jetpack.migration.JetpackMigrationViewModel.UiState.Loading import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.utils.UiString.UiStringRes -import org.wordpress.android.util.GravatarUtilsWrapper +import org.wordpress.android.util.WPAvatarUtilsWrapper import org.wordpress.android.util.JetpackMigrationLanguageUtil import org.wordpress.android.util.LocaleManagerWrapper import org.wordpress.android.util.SiteUtilsWrapper @@ -54,7 +54,7 @@ class JetpackMigrationViewModelTest : BaseUnitTest() { private val refreshAppThemeObserver: Observer = mock() private val refreshAppLanguageObserver: Observer = mock() private val siteUtilsWrapper: SiteUtilsWrapper = mock() - private val gravatarUtilsWrapper: GravatarUtilsWrapper = mock() + private val avatarUtilsWrapper: WPAvatarUtilsWrapper = mock() private val appPrefsWrapper: AppPrefsWrapper = mock() private val localMigrationOrchestrator: LocalMigrationOrchestrator = mock() private val migrationEmailHelper: MigrationEmailHelper = mock() @@ -71,13 +71,13 @@ class JetpackMigrationViewModelTest : BaseUnitTest() { @Before fun setUp() { - whenever(gravatarUtilsWrapper.fixGravatarUrlWithResource(any(), any())).thenReturn("") + whenever(avatarUtilsWrapper.rewriteAvatarUrlWithResource(any(), any())).thenReturn("") whenever(localeManagerWrapper.getLanguage()).thenReturn("") classToTest = JetpackMigrationViewModel( mainDispatcher = testDispatcher(), dispatcher = dispatcher, siteUtilsWrapper = siteUtilsWrapper, - gravatarUtilsWrapper = gravatarUtilsWrapper, + avatarUtilsWrapper = avatarUtilsWrapper, contextProvider = contextProvider, preventDuplicateNotifsFeatureConfig = preventDuplicateNotifsFeatureConfig, appPrefsWrapper = appPrefsWrapper, diff --git a/WordPress/src/test/java/org/wordpress/android/ui/reader/ReaderPostDetailUiStateBuilderTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/reader/ReaderPostDetailUiStateBuilderTest.kt index 3034cd8ddb0e..7fde3c85fcdf 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/reader/ReaderPostDetailUiStateBuilderTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/reader/ReaderPostDetailUiStateBuilderTest.kt @@ -41,7 +41,7 @@ import org.wordpress.android.ui.utils.UiString.UiStringResWithParams import org.wordpress.android.ui.utils.UiString.UiStringText import org.wordpress.android.util.DateTimeUtilsWrapper import org.wordpress.android.util.DisplayUtilsWrapper -import org.wordpress.android.util.GravatarUtilsWrapper +import org.wordpress.android.util.WPAvatarUtilsWrapper import org.wordpress.android.viewmodel.ContextProvider import org.wordpress.android.viewmodel.ResourceProvider import java.util.Date @@ -91,7 +91,7 @@ class ReaderPostDetailUiStateBuilderTest : BaseUnitTest() { lateinit var dateTimeUtilsWrapper: DateTimeUtilsWrapper @Mock - lateinit var gravatarUtilsWrapper: GravatarUtilsWrapper + lateinit var avatarUtilsWrapper: WPAvatarUtilsWrapper @Mock lateinit var threadedCommentsUtils: ThreadedCommentsUtils @@ -122,7 +122,7 @@ class ReaderPostDetailUiStateBuilderTest : BaseUnitTest() { htmlUtilsWrapper, htmlMessageUtils, dateTimeUtilsWrapper, - gravatarUtilsWrapper, + avatarUtilsWrapper, threadedCommentsUtils, resourceProvider ) @@ -305,7 +305,7 @@ class ReaderPostDetailUiStateBuilderTest : BaseUnitTest() { whenever(dateTimeUtilsWrapper.dateFromIso8601(anyString())).thenReturn(Date()) whenever(dateTimeUtilsWrapper.javaDateToTimeSpan(anyOrNull())).thenReturn("") - whenever(gravatarUtilsWrapper.fixGravatarUrl(anyString(), anyInt())).thenReturn("") + whenever(avatarUtilsWrapper.rewriteAvatarUrl(anyString(), anyInt())).thenReturn("") val comment = ReaderComment().apply { authorName = "" diff --git a/WordPress/src/test/java/org/wordpress/android/ui/reader/discover/ReaderPostUiStateBuilderTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/reader/discover/ReaderPostUiStateBuilderTest.kt index 59490ec0c869..34d170375c98 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/reader/discover/ReaderPostUiStateBuilderTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/reader/discover/ReaderPostUiStateBuilderTest.kt @@ -54,7 +54,7 @@ import org.wordpress.android.ui.utils.UiString.UiStringRes import org.wordpress.android.ui.utils.UiString.UiStringResWithParams import org.wordpress.android.ui.utils.UiString.UiStringText import org.wordpress.android.util.DateTimeUtilsWrapper -import org.wordpress.android.util.GravatarUtilsWrapper +import org.wordpress.android.util.WPAvatarUtilsWrapper import org.wordpress.android.util.UrlUtilsWrapper import org.wordpress.android.util.image.ImageType import java.util.Date @@ -73,7 +73,7 @@ class ReaderPostUiStateBuilderTest : BaseUnitTest() { lateinit var urlUtilsWrapper: UrlUtilsWrapper @Mock - lateinit var gravatarUtilsWrapper: GravatarUtilsWrapper + lateinit var avatarUtilsWrapper: WPAvatarUtilsWrapper @Mock lateinit var dateTimeUtilsWrapper: DateTimeUtilsWrapper @@ -92,7 +92,7 @@ class ReaderPostUiStateBuilderTest : BaseUnitTest() { builder = ReaderPostUiStateBuilder( accountStore, urlUtilsWrapper, - gravatarUtilsWrapper, + avatarUtilsWrapper, dateTimeUtilsWrapper, readerImageScannerProvider, readerUtilsWrapper, @@ -100,7 +100,7 @@ class ReaderPostUiStateBuilderTest : BaseUnitTest() { testDispatcher() ) whenever(dateTimeUtilsWrapper.javaDateToTimeSpan(anyOrNull())).thenReturn("") - whenever(gravatarUtilsWrapper.fixGravatarUrlWithResource(anyOrNull(), anyInt())).thenReturn("") + whenever(avatarUtilsWrapper.rewriteAvatarUrlWithResource(anyOrNull(), anyInt())).thenReturn("") val imageScanner: ReaderImageScanner = mock() whenever(readerImageScannerProvider.createReaderImageScanner(anyOrNull(), anyBoolean())) .thenReturn(imageScanner) @@ -264,7 +264,7 @@ class ReaderPostUiStateBuilderTest : BaseUnitTest() { fun `discover uses fixed avatar URL`() = test { // Arrange val post = createPost(isDiscoverPost = true) - whenever(gravatarUtilsWrapper.fixGravatarUrlWithResource(anyOrNull(), anyInt())).thenReturn("12345") + whenever(avatarUtilsWrapper.rewriteAvatarUrlWithResource(anyOrNull(), anyInt())).thenReturn("12345") // Act val uiState = mapPostToUiState(post) // Assert diff --git a/build.gradle b/build.gradle index 46baee6f28d8..ce046e95634c 100644 --- a/build.gradle +++ b/build.gradle @@ -26,10 +26,11 @@ ext { gutenbergMobileVersion = 'v1.116.0' wordPressAztecVersion = 'v2.1.1' wordPressFluxCVersion = 'trunk-f154a1ace883ee3e0f4b1308a76c9316109b6b03' - wordPressLoginVersion = '1.14.1' + wordPressLoginVersion = '1.15.0' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' + gravatarVersion = '0.2.0' // debug flipperVersion = '0.245.0' @@ -86,7 +87,6 @@ ext { lottieVersion = '6.1.0' philjayMpAndroidChartVersion = 'v3.1.0' squareupKotlinPoetVersion = '1.16.0' - squareupOkioVersion = '3.6.0' squareupRetrofitVersion = '2.9.0' uCropVersion = '2.2.8' zendeskVersion = '5.1.2' diff --git a/config/gradle/included_builds.gradle b/config/gradle/included_builds.gradle index bbce4b7c0153..e7ed11230846 100644 --- a/config/gradle/included_builds.gradle +++ b/config/gradle/included_builds.gradle @@ -10,6 +10,7 @@ gradle.ext.aztecAndroidGlideLoaderPath = "org.wordpress.aztec:glide-loader" gradle.ext.aztecAndroidPicassoLoaderPath = "org.wordpress.aztec:picasso-loader" gradle.ext.aboutAutomatticBinaryPath = "com.automattic:about" gradle.ext.tracksBinaryPath = "com.automattic:Automattic-Tracks-Android" +gradle.ext.gravatarBinaryPath = "com.gravatar:gravatar" def localBuilds = new File("${rootDir}/local-builds.gradle") if (localBuilds.exists()) { @@ -104,4 +105,13 @@ if (localBuilds.exists()) { } } } + + if (ext.has("localGravatarAndroidPath")) { + includeBuild(ext.localGravatarAndroidPath) { + dependencySubstitution { + println "Substituting Gravatar-Android with the local build" + substitute module("$gradle.ext.gravatarBinaryPath") using project(':gravatar') + } + } + } } diff --git a/docs/test_instructions_per_dependency_update.md b/docs/test_instructions_per_dependency_update.md index fb2b328411a2..7c373357c0cc 100644 --- a/docs/test_instructions_per_dependency_update.md +++ b/docs/test_instructions_per_dependency_update.md @@ -55,19 +55,17 @@ rather than strict requirements. 4. [PlayServicesAuth](#playservicesauth) 5. [PlayServicesCoreScanner](#playservicescodescanner) 6. [PlayReview](#playreview) -5. Network - 1. [Okio](#okio) -6. Tool +5. Tool 1. [Zendesk](#zendesk) 2. [JSoup](#jsoup) -7. Other Core +6. Other Core 1. [AutoService](#autoservice) 2. [KotlinPoet](#kotlinpoet) -8. Other UI +7. Other UI 1. [Lottie](#lottie) 2. [UCrop](#ucrop) -9. [Smoke Test](#smoke-test) -10. [Special](#special) +8. [Smoke Test](#smoke-test) +9. [Special](#special) ℹ️ Every test instruction should be prefixed with one of the following: - [JP/WP] This test applies to both, the `Jetpack` and `WordPress` apps. @@ -435,21 +433,6 @@ Step.3: ----- -### Okio [[squareupOkioVersion](https://github.com/wordpress-mobile/WordPress-Android/blob/trunk/build.gradle)] - -

    - 1. [JP/WP] Me Screen [GravatarApi.java + StreamingRequest.java] - -- Go to `Me` tab. -- From the `Me` screen you are in, click on your profile's icon (`CHANGE PHOTO`). -- Choose an image and wait for the `Edit Photo` screen to appear. -- Crop the image and click the `done` menu option (top right). -- Verify the image is updated accordingly. - -
    - ------ - ### Zendesk [[zendeskVersion](https://github.com/wordpress-mobile/WordPress-Android/blob/trunk/build.gradle)]
    diff --git a/local-builds.gradle-example b/local-builds.gradle-example index d0324a57cf65..1a144af244bb 100644 --- a/local-builds.gradle-example +++ b/local-builds.gradle-example @@ -21,4 +21,5 @@ ext { //localLoginFlowPath = "../WordPress-Login-Flow-Android" //localAztecAndroidPath = "../AztecEditor-Android" //localTracksPath = "../Automattic-Tracks-Android" + //localGravatarAndroidPath = "../Gravatar-SDK-Android" }