From a84a61816abe9291d1c9c6117330d25245b854b6 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Wed, 10 Jan 2024 16:36:46 +0100 Subject: [PATCH 1/7] Very first modularization test of the Gravatar API --- WordPress/build.gradle | 1 + .../android/networking/GravatarApiTest.java | 2 + .../signup/SignupEpilogueFragment.java | 2 +- .../wordpress/android/ui/main/MeFragment.kt | 4 +- config/gradle/included_builds.gradle | 1 + libs/gravatar/.gitignore | 1 + libs/gravatar/build.gradle.kts | 47 +++++++++++++++++++ libs/gravatar/consumer-rules.pro | 0 libs/gravatar/proguard-rules.pro | 21 +++++++++ .../com/gravatar/ExampleInstrumentedTest.kt | 24 ++++++++++ libs/gravatar/src/main/AndroidManifest.xml | 4 ++ .../main/java/com/gravatar}/GravatarApi.java | 20 ++++---- .../java/com/gravatar/StreamingRequest.java | 41 ++++++++++++++++ .../test/java/com/gravatar/ExampleUnitTest.kt | 17 +++++++ local-builds.gradle-example | 1 + settings.gradle | 1 + 16 files changed, 174 insertions(+), 13 deletions(-) create mode 100644 libs/gravatar/.gitignore create mode 100644 libs/gravatar/build.gradle.kts create mode 100644 libs/gravatar/consumer-rules.pro create mode 100644 libs/gravatar/proguard-rules.pro create mode 100644 libs/gravatar/src/androidTest/java/com/gravatar/ExampleInstrumentedTest.kt create mode 100644 libs/gravatar/src/main/AndroidManifest.xml rename {WordPress/src/main/java/org/wordpress/android/networking => libs/gravatar/src/main/java/com/gravatar}/GravatarApi.java (89%) create mode 100644 libs/gravatar/src/main/java/com/gravatar/StreamingRequest.java create mode 100644 libs/gravatar/src/test/java/com/gravatar/ExampleUnitTest.kt diff --git a/WordPress/build.gradle b/WordPress/build.gradle index e3f33b5c6cf4..eca4a69442b7 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -388,6 +388,7 @@ dependencies { exclude group: 'com.mcxiaoke.volley' } implementation "org.wordpress:persistentedittext:$wordPressPersistentEditTextVersion" + implementation project(':libs:gravatar') implementation "androidx.arch.core:core-common:$androidxArchCoreVersion" implementation "androidx.arch.core:core-runtime:$androidxArchCoreVersion" diff --git a/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java b/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java index 762b808321f9..831189e51940 100644 --- a/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java +++ b/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java @@ -21,6 +21,8 @@ import okhttp3.RequestBody; import okio.Buffer; +import com.gravatar.GravatarApi; + @HiltAndroidTest public class GravatarApiTest { @Rule 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..53bacde22244 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 @@ -52,7 +52,7 @@ 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 com.gravatar.GravatarApi; import org.wordpress.android.ui.FullScreenDialogFragment; import org.wordpress.android.ui.FullScreenDialogFragment.OnConfirmListener; import org.wordpress.android.ui.FullScreenDialogFragment.OnDismissListener; 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..3921b1307c8d 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 @@ -44,8 +44,8 @@ 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 com.gravatar.GravatarApi +import com.gravatar.GravatarApi.GravatarUploadListener import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.RequestCodes import org.wordpress.android.ui.about.UnifiedAboutActivity diff --git a/config/gradle/included_builds.gradle b/config/gradle/included_builds.gradle index bbce4b7c0153..d4d73d4e2ad3 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()) { diff --git a/libs/gravatar/.gitignore b/libs/gravatar/.gitignore new file mode 100644 index 000000000000..42afabfd2abe --- /dev/null +++ b/libs/gravatar/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/libs/gravatar/build.gradle.kts b/libs/gravatar/build.gradle.kts new file mode 100644 index 000000000000..8d048e404b30 --- /dev/null +++ b/libs/gravatar/build.gradle.kts @@ -0,0 +1,47 @@ +plugins { + id("com.android.library") + id("org.jetbrains.kotlin.android") +} + +repositories { + google() + mavenCentral() +} + +android { + namespace = "com.gravatar" + compileSdk = 34 + + defaultConfig { + minSdk = 23 + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } +} + +dependencies { + implementation("androidx.core:core-ktx:1.12.0") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.material:material:1.11.0") + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + implementation("com.squareup.okhttp3:okhttp:4.12.0") +} diff --git a/libs/gravatar/consumer-rules.pro b/libs/gravatar/consumer-rules.pro new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/libs/gravatar/proguard-rules.pro b/libs/gravatar/proguard-rules.pro new file mode 100644 index 000000000000..481bb4348141 --- /dev/null +++ b/libs/gravatar/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/libs/gravatar/src/androidTest/java/com/gravatar/ExampleInstrumentedTest.kt b/libs/gravatar/src/androidTest/java/com/gravatar/ExampleInstrumentedTest.kt new file mode 100644 index 000000000000..cf9b4ccb21e0 --- /dev/null +++ b/libs/gravatar/src/androidTest/java/com/gravatar/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.gravatar + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.gravatar.test", appContext.packageName) + } +} diff --git a/libs/gravatar/src/main/AndroidManifest.xml b/libs/gravatar/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..8bdb7e14b389 --- /dev/null +++ b/libs/gravatar/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/WordPress/src/main/java/org/wordpress/android/networking/GravatarApi.java b/libs/gravatar/src/main/java/com/gravatar/GravatarApi.java similarity index 89% rename from WordPress/src/main/java/org/wordpress/android/networking/GravatarApi.java rename to libs/gravatar/src/main/java/com/gravatar/GravatarApi.java index 3c6f8d82eb82..7680811bd690 100644 --- a/WordPress/src/main/java/org/wordpress/android/networking/GravatarApi.java +++ b/libs/gravatar/src/main/java/com/gravatar/GravatarApi.java @@ -1,10 +1,8 @@ -package org.wordpress.android.networking; +package com.gravatar; import android.os.Handler; import android.os.Looper; - -import org.wordpress.android.analytics.AnalyticsTracker; -import org.wordpress.android.util.AppLog; +import android.util.Log; import java.io.File; import java.io.IOException; @@ -24,6 +22,7 @@ public class GravatarApi { public static final String API_BASE_URL = "https://api.gravatar.com/v1/"; private static final int DEFAULT_TIMEOUT = 15000; + private static final String LOG_TAG = "Gravatar"; public interface GravatarUploadListener { void onSuccess(); @@ -92,10 +91,10 @@ public void onResponse(Call call, final Response response) throws IOException { 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: " + // TODO: we should remove this + // AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_UNSUCCESSFUL, + // properties); + Log.w(LOG_TAG, "Network call unsuccessful trying to upload Gravatar: " + responseBody); } @@ -116,7 +115,7 @@ 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!" + Log.w(LOG_TAG, "Network call failure trying to upload Gravatar!" + exceptionMessage); // Don't track exceptions caused by poor internet connectivity @@ -124,7 +123,8 @@ public void onFailure(okhttp3.Call call, final IOException e) { 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); + // TODO: we should remove this + // AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_EXCEPTION, properties); } new Handler(Looper.getMainLooper()).post(new Runnable() { diff --git a/libs/gravatar/src/main/java/com/gravatar/StreamingRequest.java b/libs/gravatar/src/main/java/com/gravatar/StreamingRequest.java new file mode 100644 index 000000000000..42cc93ac24a8 --- /dev/null +++ b/libs/gravatar/src/main/java/com/gravatar/StreamingRequest.java @@ -0,0 +1,41 @@ +package com.gravatar; + +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/libs/gravatar/src/test/java/com/gravatar/ExampleUnitTest.kt b/libs/gravatar/src/test/java/com/gravatar/ExampleUnitTest.kt new file mode 100644 index 000000000000..3f3e584f60d6 --- /dev/null +++ b/libs/gravatar/src/test/java/com/gravatar/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.gravatar + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/local-builds.gradle-example b/local-builds.gradle-example index d0324a57cf65..039af3ced3bc 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 = "../GravatarSDK-Android" } diff --git a/settings.gradle b/settings.gradle index 0d1018fd702f..687afea4a074 100644 --- a/settings.gradle +++ b/settings.gradle @@ -56,6 +56,7 @@ include ':libs:analytics' include ':libs:editor' include ':libs:processors' include ':libs:annotations' +include ':libs:gravatar' include ':libs:mocks' From b705d62d2db6a65666a6a21586f3437072f334f3 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Thu, 11 Jan 2024 09:49:13 +0100 Subject: [PATCH 2/7] Convert code to Kotlin and move some analytics and error logging out of GravatarAPI add some FIXME so I don't forget to update the analytics Move the Gravatar module out the project --- WordPress/build.gradle | 2 +- .../signup/SignupEpilogueFragment.java | 24 ++- .../wordpress/android/ui/main/MeFragment.kt | 10 +- build.gradle | 1 + config/gradle/included_builds.gradle | 9 ++ libs/gravatar/.gitignore | 1 - libs/gravatar/build.gradle.kts | 47 ------ libs/gravatar/consumer-rules.pro | 0 libs/gravatar/proguard-rules.pro | 21 --- .../com/gravatar/ExampleInstrumentedTest.kt | 24 --- libs/gravatar/src/main/AndroidManifest.xml | 4 - .../main/java/com/gravatar/GravatarApi.java | 139 ------------------ .../java/com/gravatar/StreamingRequest.java | 41 ------ .../test/java/com/gravatar/ExampleUnitTest.kt | 17 --- 14 files changed, 38 insertions(+), 302 deletions(-) delete mode 100644 libs/gravatar/.gitignore delete mode 100644 libs/gravatar/build.gradle.kts delete mode 100644 libs/gravatar/consumer-rules.pro delete mode 100644 libs/gravatar/proguard-rules.pro delete mode 100644 libs/gravatar/src/androidTest/java/com/gravatar/ExampleInstrumentedTest.kt delete mode 100644 libs/gravatar/src/main/AndroidManifest.xml delete mode 100644 libs/gravatar/src/main/java/com/gravatar/GravatarApi.java delete mode 100644 libs/gravatar/src/main/java/com/gravatar/StreamingRequest.java delete mode 100644 libs/gravatar/src/test/java/com/gravatar/ExampleUnitTest.kt diff --git a/WordPress/build.gradle b/WordPress/build.gradle index eca4a69442b7..4fe829fa855e 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -388,7 +388,7 @@ dependencies { exclude group: 'com.mcxiaoke.volley' } implementation "org.wordpress:persistentedittext:$wordPressPersistentEditTextVersion" - implementation project(':libs:gravatar') + implementation "$gradle.ext.gravatarBinaryPath:$gravatarVersion" implementation "androidx.arch.core:core-common:$androidxArchCoreVersion" implementation "androidx.arch.core:core-runtime:$androidxArchCoreVersion" 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 53bacde22244..c9cf412a613c 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,7 @@ import androidx.core.widget.NestedScrollView.OnScrollChangeListener; import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.gravatar.GravatarApi; import com.yalantis.ucrop.UCrop; import com.yalantis.ucrop.UCropActivity; @@ -52,7 +53,6 @@ import org.wordpress.android.fluxc.store.AccountStore.PushUsernamePayload; import org.wordpress.android.login.LoginBaseFormFragment; import org.wordpress.android.login.widgets.WPLoginInputRow; -import com.gravatar.GravatarApi; import org.wordpress.android.ui.FullScreenDialogFragment; import org.wordpress.android.ui.FullScreenDialogFragment.OnConfirmListener; import org.wordpress.android.ui.FullScreenDialogFragment.OnDismissListener; @@ -88,6 +88,7 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.Objects; import javax.inject.Inject; @@ -724,14 +725,19 @@ protected void startCropActivity(Uri uri) { protected void startGravatarUpload(final String filePath) { if (!TextUtils.isEmpty(filePath)) { final File file = new File(filePath); + if (!mAccount.hasAccessToken()) { + // FIXME: show a toast + return; + } if (file.exists()) { startProgress(false); - - GravatarApi.uploadGravatar(file, mAccountStore.getAccount().getEmail(), mAccountStore.getAccessToken(), + GravatarApi.uploadGravatar(file, mAccountStore.getAccount().getEmail(), + Objects.requireNonNull(mAccountStore.getAccessToken()), new GravatarApi.GravatarUploadListener() { @Override public void onSuccess() { + // FIXME: log analytics endProgress(); mPhotoUrl = GravatarUtils.fixGravatarUrl(mAccount.getAccount().getAvatarUrl(), getResources().getDimensionPixelSize(R.dimen.avatar_sz_large)); @@ -741,9 +747,10 @@ public void onSuccess() { } @Override - public void onError() { + public void onError(@NonNull String exceptionClass, @NonNull String exceptionMessage) { endProgress(); showErrorDialogWithCloseButton(getString(R.string.signup_epilogue_error_avatar)); + // FIXME: log analytics AppLog.e(T.NUX, "Uploading image to Gravatar failed"); } }); @@ -829,12 +836,19 @@ public void run() { new GravatarApi.GravatarUploadListener() { @Override public void onSuccess() { + // FIXME: log analytics AppLog.i(T.NUX, "Google avatar download and Gravatar upload succeeded."); + AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_UNSUCCESSFUL); } @Override - public void onError() { + public void onError(String exceptionClass, String exceptionMessage) { AppLog.i(T.NUX, "Google avatar download and Gravatar upload failed."); + // FIXME: Don't track exceptions caused by poor internet connectivity + 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); } }); } catch (NullPointerException | URISyntaxException exception) { 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 3921b1307c8d..556c56d8afa0 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 @@ -677,13 +677,19 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { return } binding?.showGravatarProgressBar(true) - GravatarApi.uploadGravatar(file, accountStore.account.email, accountStore.accessToken, + if (!accountStore.hasAccessToken()) { + // FIXME: Change the toast message + ToastUtils.showToast(activity, R.string.error_locating_image, SHORT); + } + GravatarApi.uploadGravatar(file, accountStore.account.email, accountStore.accessToken!!, object : GravatarUploadListener { override fun onSuccess() { + // FIXME: log analytics EventBus.getDefault().post(GravatarUploadFinished(filePath, true)) } - override fun onError() { + override fun onError(exceptionClass: String, exceptionMessage: String) { + // FIXME: log analytics EventBus.getDefault().post(GravatarUploadFinished(filePath, false)) } }) diff --git a/build.gradle b/build.gradle index 8ff1878da99f..d1469ebb5cf8 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,7 @@ ext { wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' + gravatarVersion = '1.0.0' // debug flipperVersion = '0.245.0' diff --git a/config/gradle/included_builds.gradle b/config/gradle/included_builds.gradle index d4d73d4e2ad3..e7ed11230846 100644 --- a/config/gradle/included_builds.gradle +++ b/config/gradle/included_builds.gradle @@ -105,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/libs/gravatar/.gitignore b/libs/gravatar/.gitignore deleted file mode 100644 index 42afabfd2abe..000000000000 --- a/libs/gravatar/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/libs/gravatar/build.gradle.kts b/libs/gravatar/build.gradle.kts deleted file mode 100644 index 8d048e404b30..000000000000 --- a/libs/gravatar/build.gradle.kts +++ /dev/null @@ -1,47 +0,0 @@ -plugins { - id("com.android.library") - id("org.jetbrains.kotlin.android") -} - -repositories { - google() - mavenCentral() -} - -android { - namespace = "com.gravatar" - compileSdk = 34 - - defaultConfig { - minSdk = 23 - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = "1.8" - } -} - -dependencies { - implementation("androidx.core:core-ktx:1.12.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("com.google.android.material:material:1.11.0") - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - implementation("com.squareup.okhttp3:okhttp:4.12.0") -} diff --git a/libs/gravatar/consumer-rules.pro b/libs/gravatar/consumer-rules.pro deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/libs/gravatar/proguard-rules.pro b/libs/gravatar/proguard-rules.pro deleted file mode 100644 index 481bb4348141..000000000000 --- a/libs/gravatar/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/libs/gravatar/src/androidTest/java/com/gravatar/ExampleInstrumentedTest.kt b/libs/gravatar/src/androidTest/java/com/gravatar/ExampleInstrumentedTest.kt deleted file mode 100644 index cf9b4ccb21e0..000000000000 --- a/libs/gravatar/src/androidTest/java/com/gravatar/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.gravatar - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.gravatar.test", appContext.packageName) - } -} diff --git a/libs/gravatar/src/main/AndroidManifest.xml b/libs/gravatar/src/main/AndroidManifest.xml deleted file mode 100644 index 8bdb7e14b389..000000000000 --- a/libs/gravatar/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/libs/gravatar/src/main/java/com/gravatar/GravatarApi.java b/libs/gravatar/src/main/java/com/gravatar/GravatarApi.java deleted file mode 100644 index 7680811bd690..000000000000 --- a/libs/gravatar/src/main/java/com/gravatar/GravatarApi.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.gravatar; - -import android.os.Handler; -import android.os.Looper; -import android.util.Log; - -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; - private static final String LOG_TAG = "Gravatar"; - - 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); - // TODO: we should remove this - // AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_UNSUCCESSFUL, - // properties); - Log.w(LOG_TAG, "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"; - - Log.w(LOG_TAG, "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); - // TODO: we should remove this - // 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/libs/gravatar/src/main/java/com/gravatar/StreamingRequest.java b/libs/gravatar/src/main/java/com/gravatar/StreamingRequest.java deleted file mode 100644 index 42cc93ac24a8..000000000000 --- a/libs/gravatar/src/main/java/com/gravatar/StreamingRequest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.gravatar; - -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/libs/gravatar/src/test/java/com/gravatar/ExampleUnitTest.kt b/libs/gravatar/src/test/java/com/gravatar/ExampleUnitTest.kt deleted file mode 100644 index 3f3e584f60d6..000000000000 --- a/libs/gravatar/src/test/java/com/gravatar/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.gravatar - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} From e8f23bb0655ba0b577ad3fe60de7ec992f9c705e Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Thu, 4 Apr 2024 08:46:23 +0200 Subject: [PATCH 3/7] Convert code to Kotlin and move some analytics and error logging out of GravatarAPI add some FIXME so I don't forget to update the analytics Move the Gravatar module out the project Remove Okio dependency from WPAndroid As we've moved the Gravatar update to an external library. We no longer need the Okio dependency in this project. Move WordPress Analytics from GravatarApi to WPAndroid Remove uncessary FIXMEs, let the app crash on null access tokens (like previously) Injecting GravatarApi and using the instance to upload avatars Replace GravatarUtils from WPUtils, use Gravatar-SDK-Android instead Rename function to rewriteGravatarImageUrlQueryParams Update Gravatar integration with updated API Update to most recent version of Gravatar SDK Update to latest Gravatar-SDK version Replace uri() calls by url() returning a java.net.URL Fix code smell Update gravatar dependency from maven repo --- WordPress/build.gradle | 2 +- .../android/networking/GravatarApiTest.java | 69 ------------------- .../wordpress/android/util/WPAvatarUtil.kt | 39 +++++++++++ WordPress/src/jetpack/assets/licenses.html | 1 - WordPress/src/main/assets/licenses.html | 1 - .../android/datasets/ReaderUserTable.java | 4 +- .../android/modules/GravatarModule.kt | 17 +++++ .../android/networking/StreamingRequest.java | 41 ----------- .../accounts/login/LoginHeaderViewHolder.java | 16 +++-- .../signup/SignupEpilogueFragment.java | 46 ++++++------- .../android/ui/avatars/AvatarViewHolder.kt | 4 +- .../ui/comments/CommentDetailFragment.java | 10 ++- .../unified/UnifiedCommentListAdapter.kt | 6 +- .../unified/UnifiedCommentViewHolder.kt | 18 ++--- .../ui/compose/views/TrainOfAvatarsView.kt | 4 +- .../ui/engagement/LikedItemViewHolder.kt | 4 +- .../android/ui/engagement/LikerViewHolder.kt | 4 +- .../UserProfileBottomSheetFragment.kt | 4 +- .../wordpress/android/ui/main/MeFragment.kt | 33 ++++----- .../migration/JetpackMigrationViewModel.kt | 6 +- .../android/ui/main/utils/MeGravatarLoader.kt | 4 +- .../blocks/CommentUserNoteBlock.java | 4 +- .../notifications/blocks/HeaderNoteBlock.java | 5 +- .../notifications/blocks/UserNoteBlock.java | 4 +- .../android/ui/people/PeopleListFragment.java | 4 +- .../ui/people/PersonDetailFragment.java | 4 +- .../posts/adapters/AuthorSelectionAdapter.kt | 4 +- .../reader/ReaderPostDetailUiStateBuilder.kt | 6 +- .../reader/adapters/ReaderCommentAdapter.java | 4 +- .../ui/reader/adapters/ReaderPostAdapter.java | 6 +- .../ui/reader/adapters/ReaderUserAdapter.java | 4 +- .../discover/ReaderPostUiStateBuilder.kt | 12 ++-- .../adapters/SuggestionAdapter.java | 4 +- .../android/util/GravatarUtilsWrapper.kt | 23 ------- .../wordpress/android/util/WPAvatarUtils.java | 59 ++++++++++++++++ .../android/util/WPAvatarUtilsWrapper.kt | 24 +++++++ .../JetpackMigrationViewModelTest.kt | 8 +-- .../ReaderPostDetailUiStateBuilderTest.kt | 8 +-- .../discover/ReaderPostUiStateBuilderTest.kt | 10 +-- build.gradle | 5 +- ...test_instructions_per_dependency_update.md | 27 ++------ 41 files changed, 278 insertions(+), 280 deletions(-) delete mode 100644 WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java create mode 100644 WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt create mode 100644 WordPress/src/main/java/org/wordpress/android/modules/GravatarModule.kt delete mode 100644 WordPress/src/main/java/org/wordpress/android/networking/StreamingRequest.java delete mode 100644 WordPress/src/main/java/org/wordpress/android/util/GravatarUtilsWrapper.kt create mode 100644 WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtils.java create mode 100644 WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtilsWrapper.kt diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 4fe829fa855e..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 { @@ -439,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 831189e51940..000000000000 --- a/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java +++ /dev/null @@ -1,69 +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; - -import com.gravatar.GravatarApi; - -@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/WPAvatarUtil.kt b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt new file mode 100644 index 000000000000..96f0c71e8f91 --- /dev/null +++ b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt @@ -0,0 +1,39 @@ +package org.wordpress.android.util + +import com.gravatar.DefaultAvatarImage +import dagger.hilt.android.testing.HiltAndroidTest +import org.junit.Test + +import junit.framework.TestCase.assertEquals + +@HiltAndroidTest +class WPAvatarUtil { + @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, DefaultAvatarImage.STATUS_404) + ) + } +} 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/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 c9cf412a613c..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,7 +32,10 @@ import androidx.core.widget.NestedScrollView.OnScrollChangeListener; import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.gravatar.GravatarApi; +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; @@ -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; @@ -95,6 +98,8 @@ 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; @@ -148,6 +153,7 @@ public class SignupEpilogueFragment extends LoginBaseFormFragment() { @Override - public void onSuccess() { - // FIXME: log analytics + 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); @@ -747,10 +748,12 @@ public void onSuccess() { } @Override - public void onError(@NonNull String exceptionClass, @NonNull String exceptionMessage) { + public void onError(@NonNull ErrorType errorType) { endProgress(); showErrorDialogWithCloseButton(getString(R.string.signup_epilogue_error_avatar)); - // FIXME: log analytics + 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"); } }); @@ -832,22 +835,19 @@ 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() { - // FIXME: log analytics + public void onSuccess(@NonNull Unit response) { AppLog.i(T.NUX, "Google avatar download and Gravatar upload succeeded."); - AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_UNSUCCESSFUL); + AnalyticsTracker.track(Stat.ME_GRAVATAR_UPLOADED); } @Override - public void onError(String exceptionClass, String exceptionMessage) { + public void onError(@NonNull ErrorType errorType) { AppLog.i(T.NUX, "Google avatar download and Gravatar upload failed."); - // FIXME: Don't track exceptions caused by poor internet connectivity Map properties = new HashMap<>(); - properties.put("network_exception_class", exceptionClass); - properties.put("network_exception_message", exceptionMessage); + properties.put("error_type", errorType); AnalyticsTracker.track(AnalyticsTracker.Stat.ME_GRAVATAR_UPLOAD_EXCEPTION, properties); } }); 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 556c56d8afa0..cd629da830a6 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 com.gravatar.GravatarApi -import com.gravatar.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,27 +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) - if (!accountStore.hasAccessToken()) { - // FIXME: Change the toast message - ToastUtils.showToast(activity, R.string.error_locating_image, SHORT); - } - GravatarApi.uploadGravatar(file, accountStore.account.email, accountStore.accessToken!!, - object : GravatarUploadListener { - override fun onSuccess() { - // FIXME: log analytics + avatarService.upload(file, Email(accountStore.account.email), accountStore.accessToken!!, + object : GravatarListener { + override fun onSuccess(response: Unit) { + AnalyticsTracker.track(ME_GRAVATAR_UPLOADED) EventBus.getDefault().post(GravatarUploadFinished(filePath, true)) } - override fun onError(exceptionClass: String, exceptionMessage: String) { - // FIXME: log analytics + override fun onError(errorType: ErrorType) { + AnalyticsTracker.track(ME_GRAVATAR_UPLOAD_EXCEPTION, mapOf("error_type" to errorType.name)) EventBus.getDefault().post(GravatarUploadFinished(filePath, false)) } }) @@ -701,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 d1469ebb5cf8..8ca0905bb3a9 100644 --- a/build.gradle +++ b/build.gradle @@ -26,11 +26,11 @@ ext { gutenbergMobileVersion = 'v1.116.0' wordPressAztecVersion = 'v2.1.1' wordPressFluxCVersion = '2.72.0' - wordPressLoginVersion = '1.14.1' + wordPressLoginVersion = '134-fbddbe084f24fafd0dc299667674a822bdd9626d' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' - gravatarVersion = '1.0.0' + gravatarVersion = '0.2.0' // debug flipperVersion = '0.245.0' @@ -87,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/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)]
    From 50aea7192235bc25e2a31a9e37a2a1b52002107a Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Mon, 8 Apr 2024 09:36:13 +0200 Subject: [PATCH 4/7] Bump WPLoginFlow version to 1.15.0 --- build.gradle | 2 +- settings.gradle | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 8ca0905bb3a9..ad9222367bcd 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ ext { gutenbergMobileVersion = 'v1.116.0' wordPressAztecVersion = 'v2.1.1' wordPressFluxCVersion = '2.72.0' - wordPressLoginVersion = '134-fbddbe084f24fafd0dc299667674a822bdd9626d' + wordPressLoginVersion = '1.15.0' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' diff --git a/settings.gradle b/settings.gradle index 687afea4a074..0d1018fd702f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -56,7 +56,6 @@ include ':libs:analytics' include ':libs:editor' include ':libs:processors' include ':libs:annotations' -include ':libs:gravatar' include ':libs:mocks' From cf2b43bda47f068176a27c100ec87ef742b91d8a Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Mon, 8 Apr 2024 17:52:54 +0200 Subject: [PATCH 5/7] Fix WPAvatarUtilsTest and update localGravatarAndroidPath --- .../wordpress/android/util/WPAvatarUtil.kt | 28 +++++++++++-------- local-builds.gradle-example | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt index 96f0c71e8f91..46a8478ba65e 100644 --- a/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt +++ b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt @@ -1,39 +1,43 @@ package org.wordpress.android.util -import com.gravatar.DefaultAvatarImage +import com.gravatar.DefaultAvatarOption import dagger.hilt.android.testing.HiltAndroidTest -import org.junit.Test - import junit.framework.TestCase.assertEquals +import org.junit.Test @HiltAndroidTest class WPAvatarUtil { @Test fun rewriteAvatarUrlReplaceNonGravatarUrlToPhotonUrl() { - assertEquals("https://i0.wp.com/example.com/image.jpg?strip=info&quality=65&resize=100,100&ssl=1", + 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( + assertEquals( "https://www.gravatar.com/avatar/" + - "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66?d=wavatar&s=1000", - 100) + "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", + assertEquals( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66?d=404&s=200", WPAvatarUtils.rewriteAvatarUrl( "https://www.gravatar.com/avatar/" + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66", - 200, DefaultAvatarImage.STATUS_404) + 200, DefaultAvatarOption.Status404 + ) ) } } diff --git a/local-builds.gradle-example b/local-builds.gradle-example index 039af3ced3bc..1a144af244bb 100644 --- a/local-builds.gradle-example +++ b/local-builds.gradle-example @@ -21,5 +21,5 @@ ext { //localLoginFlowPath = "../WordPress-Login-Flow-Android" //localAztecAndroidPath = "../AztecEditor-Android" //localTracksPath = "../Automattic-Tracks-Android" - //localGravatarAndroidPath = "../GravatarSDK-Android" + //localGravatarAndroidPath = "../Gravatar-SDK-Android" } From b07db2da787b51d5bfb34b8fc683954f42f73692 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Tue, 9 Apr 2024 08:12:37 +0200 Subject: [PATCH 6/7] Rename test file WPAvatarUtil to WPAvatarUtilsTest --- .../android/util/{WPAvatarUtil.kt => WPAvatarUtilsTest.kt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename WordPress/src/androidTest/java/org/wordpress/android/util/{WPAvatarUtil.kt => WPAvatarUtilsTest.kt} (98%) diff --git a/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt similarity index 98% rename from WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt rename to WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt index 46a8478ba65e..24cf7d8f9951 100644 --- a/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtil.kt +++ b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt @@ -6,7 +6,7 @@ import junit.framework.TestCase.assertEquals import org.junit.Test @HiltAndroidTest -class WPAvatarUtil { +class WPAvatarUtilsTest { @Test fun rewriteAvatarUrlReplaceNonGravatarUrlToPhotonUrl() { assertEquals( From 1bdd94d3356d2fe34e71f7f8f4d56b0399977594 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Tue, 9 Apr 2024 10:10:06 +0200 Subject: [PATCH 7/7] Null check accountStore.accessToken when uploading a new avatar --- .../src/main/java/org/wordpress/android/ui/main/MeFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 cd629da830a6..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 @@ -679,7 +679,7 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { return } binding?.showGravatarProgressBar(true) - avatarService.upload(file, Email(accountStore.account.email), accountStore.accessToken!!, + avatarService.upload(file, Email(accountStore.account.email), accountStore.accessToken.orEmpty(), object : GravatarListener { override fun onSuccess(response: Unit) { AnalyticsTracker.track(ME_GRAVATAR_UPLOADED)