From aba43f8b65e9d88daa4b8d7f520cd6732bda1dbe Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Fri, 18 Oct 2024 13:49:37 +0200 Subject: [PATCH 01/16] Add gravatar-quickeditor dependency --- WordPress/build.gradle | 1 + config/gradle/included_builds.gradle | 1 + 2 files changed, 2 insertions(+) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index d8c8662fb381..471e9d57cced 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -430,6 +430,7 @@ dependencies { } implementation(libs.wordpress.persistent.edittext) implementation("$gradle.ext.gravatarBinaryPath:${libs.versions.gravatar.get()}") + implementation("$gradle.ext.gravatarQuickEditorBinaryPath:${libs.versions.gravatar.get()}") implementation(libs.google.play.app.update) diff --git a/config/gradle/included_builds.gradle b/config/gradle/included_builds.gradle index 5087f5888c7c..2be3ff78e2a2 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.gravatarBinaryPath = "com.gravatar:gravatar" +gradle.ext.gravatarQuickEditorBinaryPath = "com.gravatar:gravatar-quickeditor" def localBuilds = new File("${rootDir}/local-builds.gradle") if (localBuilds.exists()) { From 82b1b3ec6d98f2920aff825ffaece6efbd47b670 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Fri, 18 Oct 2024 13:50:55 +0200 Subject: [PATCH 02/16] Use Automattic uCrop fork --- WordPress/build.gradle | 3 ++- gradle/libs.versions.toml | 4 ++-- libs/image-editor/build.gradle | 10 ++++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 471e9d57cced..0cf2cc61a6fe 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -96,6 +96,7 @@ repositories { includeGroupByRegex "org.wordpress.react-native-libraries.*" includeGroup "com.automattic" includeGroup "com.automattic.tracks" + includeGroup "com.automattic.ucrop" includeGroup "com.gravatar" includeGroup "rs.wordpress.api" } @@ -479,7 +480,7 @@ dependencies { implementation(libs.apache.commons.text) implementation(libs.airbnb.lottie.main) implementation(libs.facebook.shimmer) - implementation(libs.yalantis.ucrop) { + implementation(libs.automattic.ucrop) { exclude group: 'androidx.core', module: 'core' exclude group: 'androidx.constraintlayout', module: 'constraintlayout' exclude group: 'androidx.appcompat', module: 'appcompat' diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 61a43638c680..344a3f5f623c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -92,7 +92,7 @@ wordpress-lint = '2.1.0' wordpress-persistent-edittext = '1.0.2' wordpress-rs = 'trunk-50f703a7f677084157d02f05d4d477d7eaf960b1' wordpress-utils = '3.14.0' -yalantis-ucrop = '2.2.9' +automattic-ucrop = '2.2.10' zendesk = '5.1.2' [libraries] @@ -225,7 +225,7 @@ wordpress-lint = { group = "org.wordpress", name = "lint", version.ref = "wordpr wordpress-persistent-edittext = { group = "org.wordpress", name = "persistentedittext", version.ref = "wordpress-persistent-edittext" } wordpress-rs-android = { group = "rs.wordpress.api", name = "android", version.ref = "wordpress-rs" } wordpress-utils = { group = "org.wordpress", name = "utils", version.ref = "wordpress-utils" } -yalantis-ucrop = { group = "com.github.yalantis", name = "ucrop", version.ref = "yalantis-ucrop" } +automattic-ucrop = { group = "com.automattic", name = "ucrop", version.ref = "automattic-ucrop" } zendesk-support = { group = "com.zendesk", name = "support", version.ref = "zendesk" } [plugins] diff --git a/libs/image-editor/build.gradle b/libs/image-editor/build.gradle index d9590df8fb88..b1fb720bc3b1 100644 --- a/libs/image-editor/build.gradle +++ b/libs/image-editor/build.gradle @@ -39,7 +39,13 @@ android { } repositories { - maven { url "https://www.jitpack.io" } + maven { + url 'https://a8c-libs.s3.amazonaws.com/android' + content { + includeGroup "com.automattic" + includeGroup "com.automattic.ucrop" + } + } } dependencies { @@ -57,7 +63,7 @@ dependencies { implementation(libs.androidx.lifecycle.viewmodel.main) implementation(libs.androidx.lifecycle.viewmodel.savedstate) implementation(libs.androidx.lifecycle.livedata.core) - implementation(libs.yalantis.ucrop) { + implementation(libs.automattic.ucrop) { exclude group: 'com.squareup.okhttp3' exclude group: 'androidx.core', module: 'core' exclude group: 'androidx.constraintlayout', module: 'constraintlayout' From d8aba3bacf1dd0420dbba2bcb5d615d0c1cc7bd7 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Fri, 18 Oct 2024 13:52:48 +0200 Subject: [PATCH 03/16] Fix deprecation issues from newer foundation library --- .../ui/barcodescanner/BarcodeScanner.kt | 2 +- .../ReadingPreferencesScreen.kt | 23 ++++++++----------- .../views/compose/tagsfeed/ReaderTagsFeed.kt | 5 ++-- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanner.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanner.kt index f935099a7003..b5621c4f077a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanner.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanner.kt @@ -17,11 +17,11 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat import org.wordpress.android.ui.compose.theme.AppThemeM2 +import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.camera.core.Preview as CameraPreview @Composable diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/readingpreferences/ReadingPreferencesScreen.kt b/WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/readingpreferences/ReadingPreferencesScreen.kt index f0a4de33be42..ae2356ac176d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/readingpreferences/ReadingPreferencesScreen.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/readingpreferences/ReadingPreferencesScreen.kt @@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.verticalScroll import androidx.compose.material.MaterialTheme import androidx.compose.material.Text @@ -37,6 +36,7 @@ import androidx.compose.ui.platform.rememberNestedScrollInteropConnection import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.onClick import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.LinkAnnotation import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString @@ -283,27 +283,22 @@ private fun ReadingPreferencesPreviewFeedback( end = endIndex, ) - addStringAnnotation( - tag = "url", - annotation = "feedback", + addLink( + clickable = LinkAnnotation.Clickable( + tag = "url", + linkInteractionListener = { + onSendFeedbackClick() + } + ), start = startIndex, end = endIndex, ) } val buttonLabel = stringResource(R.string.reader_preferences_screen_preview_text_feedback_label) - ClickableText( + Text( text = annotatedString, style = textStyle, - onClick = { offset -> - annotatedString.getStringAnnotations(tag = "url", start = offset, end = offset) - .firstOrNull() - ?.let { annotation -> - if (annotation.item == "feedback") { - onSendFeedbackClick() - } - } - }, modifier = Modifier.semantics { onClick( label = buttonLabel, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/tagsfeed/ReaderTagsFeed.kt b/WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/tagsfeed/ReaderTagsFeed.kt index 3cb4c64658f9..1d3a4f59e7d4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/tagsfeed/ReaderTagsFeed.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/tagsfeed/ReaderTagsFeed.kt @@ -1,7 +1,6 @@ package org.wordpress.android.ui.reader.views.compose.tagsfeed import android.content.res.Configuration -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -91,7 +90,7 @@ fun ReaderTagsFeed(uiState: UiState) { } } -@OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class) +@OptIn(ExperimentalMaterialApi::class) @Composable private fun Loaded(uiState: UiState.Loaded) { val pullRefreshState = rememberPullRefreshState( @@ -138,7 +137,7 @@ private fun Loaded(uiState: UiState.Loaded) { Column( modifier = Modifier - .animateItemPlacement() + .animateItem() .fillMaxWidth() .padding( top = Margin.Large.value, From 4e75b4c4714d78a44356dbfd52843ee2fbdff79c Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Fri, 18 Oct 2024 14:11:16 +0200 Subject: [PATCH 04/16] Setup remote feature flag for quick editor --- WordPress/build.gradle | 1 + .../GravatarQuickEditorFeatureConfig.kt | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/util/config/GravatarQuickEditorFeatureConfig.kt diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 0cf2cc61a6fe..a317bd754bdb 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -203,6 +203,7 @@ android { buildConfigField "boolean", "VOICE_TO_CONTENT", "false" buildConfigField "boolean", "READER_FLOATING_BUTTON", "false" buildConfigField "boolean", "ENABLE_SELF_HOSTED_USERS", "false" + buildConfigField "boolean", "GRAVATAR_QUICK_EDITOR", "true" // Override these constants in jetpack product flavor to enable/ disable features buildConfigField "boolean", "ENABLE_SITE_CREATION", "true" diff --git a/WordPress/src/main/java/org/wordpress/android/util/config/GravatarQuickEditorFeatureConfig.kt b/WordPress/src/main/java/org/wordpress/android/util/config/GravatarQuickEditorFeatureConfig.kt new file mode 100644 index 000000000000..05cf6284ebe5 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/util/config/GravatarQuickEditorFeatureConfig.kt @@ -0,0 +1,20 @@ +package org.wordpress.android.util.config + +import org.wordpress.android.BuildConfig +import org.wordpress.android.annotation.Feature +import javax.inject.Inject + +@Feature(GravatarQuickEditorFeatureConfig.GRAVATAR_QUICK_EDITOR_REMOTE_FIELD, true) +class GravatarQuickEditorFeatureConfig @Inject constructor(appConfig: AppConfig) : FeatureConfig( + appConfig, + BuildConfig.GRAVATAR_QUICK_EDITOR, + GRAVATAR_QUICK_EDITOR_REMOTE_FIELD +) { + override fun isEnabled(): Boolean { + return super.isEnabled() && BuildConfig.GRAVATAR_QUICK_EDITOR + } + + companion object { + const val GRAVATAR_QUICK_EDITOR_REMOTE_FIELD = "gravatar_quick_editor" + } +} From 0d378f922013f43385f92a24df1b702deffef19f Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Fri, 18 Oct 2024 14:11:45 +0200 Subject: [PATCH 05/16] Show Gravatar QuickEditor on Avatar tap --- .../wordpress/android/ui/main/MeFragment.kt | 29 +++++++++++++++++-- .../android/ui/main/utils/MeGravatarLoader.kt | 5 ++-- .../wordpress/android/util/WPAvatarUtils.java | 24 +++++++++++---- 3 files changed, 47 insertions(+), 11 deletions(-) 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 cb9fb855dde8..8b8d420e48d1 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 @@ -21,6 +21,10 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar +import com.gravatar.quickeditor.GravatarQuickEditor +import com.gravatar.quickeditor.ui.editor.AuthenticationMethod +import com.gravatar.quickeditor.ui.editor.AvatarPickerContentLayout +import com.gravatar.quickeditor.ui.editor.GravatarQuickEditorParams import com.gravatar.services.AvatarService import com.gravatar.services.GravatarResult import com.gravatar.types.Email @@ -82,6 +86,7 @@ import org.wordpress.android.util.ToastUtils import org.wordpress.android.util.ToastUtils.Duration.SHORT import org.wordpress.android.util.WPMediaUtils import org.wordpress.android.util.config.DomainManagementFeatureConfig +import org.wordpress.android.util.config.GravatarQuickEditorFeatureConfig import org.wordpress.android.util.config.QRCodeAuthFlowFeatureConfig import org.wordpress.android.util.config.RecommendTheAppFeatureConfig import org.wordpress.android.util.extensions.getColorFromAttribute @@ -131,6 +136,9 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { @Inject lateinit var qrCodeAuthFlowFeatureConfig: QRCodeAuthFlowFeatureConfig + @Inject + lateinit var gravatarQuickEditorFeatureConfig: GravatarQuickEditorFeatureConfig + @Inject lateinit var jetpackBrandingUtils: JetpackBrandingUtils @@ -156,6 +164,7 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { private val shouldShowDomainButton get() = BuildConfig.IS_JETPACK_APP && domainManagementFeatureConfig.isEnabled() && accountStore.hasAccessToken() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) (requireActivity().application as WordPress).component().inject(this) @@ -192,7 +201,21 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { val showPickerListener = OnClickListener { AnalyticsTracker.track(ME_GRAVATAR_TAPPED) - showPhotoPickerForGravatar() + if (gravatarQuickEditorFeatureConfig.isEnabled()) { + GravatarQuickEditor.show( + fragment = this@MeFragment, + gravatarQuickEditorParams = GravatarQuickEditorParams { + email = Email(accountStore.account.email) + avatarPickerContentLayout = AvatarPickerContentLayout.Horizontal + }, + authenticationMethod = AuthenticationMethod.Bearer(accountStore.accessToken.orEmpty()), + onAvatarSelected = { + loadAvatar(null, true) + }, + ) + } else { + showPhotoPickerForGravatar() + } } avatarContainer.setOnClickListener(showPickerListener) rowMyProfile.setOnClickListener { @@ -473,9 +496,9 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { isUpdatingGravatar = isUpdating } - private fun MeFragmentBinding.loadAvatar(injectFilePath: String?) { + private fun MeFragmentBinding.loadAvatar(injectFilePath: String?, forceRefresh: Boolean = false) { val newAvatarUploaded = !injectFilePath.isNullOrEmpty() - val avatarUrl = meGravatarLoader.constructGravatarUrl(accountStore.account.avatarUrl) + val avatarUrl = meGravatarLoader.constructGravatarUrl(accountStore.account.avatarUrl, forceRefresh) meGravatarLoader.load( newAvatarUploaded, avatarUrl, 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 f4b6ad1464fc..510aa29967bd 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 @@ -56,8 +56,9 @@ class MeGravatarLoader @Inject constructor( } } - fun constructGravatarUrl(rawAvatarUrl: String): String { + fun constructGravatarUrl(rawAvatarUrl: String, forceRefresh: Boolean = false): String { val avatarSz = resourseProvider.getDimensionPixelSize(R.dimen.avatar_sz_extra_small) - return WPAvatarUtils.rewriteAvatarUrl(rawAvatarUrl, avatarSz) + val cacheBuster = if (forceRefresh) System.currentTimeMillis().toString() else null + return WPAvatarUtils.rewriteAvatarUrl(rawAvatarUrl, avatarSz, cacheBuster) } } diff --git a/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtils.java b/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtils.java index 1c37575f6e4c..b2b11088bd09 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtils.java +++ b/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtils.java @@ -22,6 +22,7 @@ public class WPAvatarUtils { private WPAvatarUtils() { throw new IllegalStateException("Utility class"); } + public static final DefaultAvatarOption DEFAULT_AVATAR = MysteryPerson.INSTANCE; /** @@ -35,7 +36,8 @@ private WPAvatarUtils() { * @return the fixed url */ public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatarSz, - @Nullable DefaultAvatarOption defaultImage) { + @Nullable DefaultAvatarOption defaultImage, + @Nullable String cacheBuster) { if (TextUtils.isEmpty(imageUrl)) { return ""; } @@ -47,10 +49,10 @@ public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatar try { return new AvatarUrl(new URL(imageUrl), new AvatarQueryOptions.Builder() - .setPreferredSize(avatarSz) - .setDefaultAvatarOption(defaultImage) - .build() - ).url(null).toString(); + .setPreferredSize(avatarSz) + .setDefaultAvatarOption(defaultImage) + .build() + ).url(cacheBuster).toString(); } catch (MalformedURLException | IllegalArgumentException e) { return ""; } @@ -58,6 +60,16 @@ public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatar } public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatarSz) { - return rewriteAvatarUrl(imageUrl, avatarSz, DEFAULT_AVATAR); + return rewriteAvatarUrl(imageUrl, avatarSz, DEFAULT_AVATAR, null); + } + + public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatarSz, + @Nullable DefaultAvatarOption defaultImage) { + return rewriteAvatarUrl(imageUrl, avatarSz, defaultImage, null); + } + + public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatarSz, + @Nullable String cacheBuster) { + return rewriteAvatarUrl(imageUrl, avatarSz, DEFAULT_AVATAR, cacheBuster); } } From befee3c9f75b3cd70758da7b40d4f45751d851d8 Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Mon, 28 Oct 2024 14:36:36 +0100 Subject: [PATCH 06/16] Add QuickEditor to SignupEpilogueFragment --- .../accounts/signup/SignupEpilogueFragment.kt | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/signup/SignupEpilogueFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/accounts/signup/SignupEpilogueFragment.kt index 6401160c3517..15b559d1fa8b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/signup/SignupEpilogueFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/signup/SignupEpilogueFragment.kt @@ -30,6 +30,12 @@ import androidx.appcompat.view.ContextThemeWrapper import androidx.core.widget.NestedScrollView import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.gravatar.AvatarQueryOptions +import com.gravatar.AvatarUrl +import com.gravatar.quickeditor.GravatarQuickEditor +import com.gravatar.quickeditor.ui.editor.AuthenticationMethod +import com.gravatar.quickeditor.ui.editor.AvatarPickerContentLayout +import com.gravatar.quickeditor.ui.editor.GravatarQuickEditorParams import com.gravatar.services.AvatarService import com.gravatar.services.GravatarResult import com.gravatar.types.Email @@ -70,6 +76,7 @@ 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.config.GravatarQuickEditorFeatureConfig import org.wordpress.android.util.extensions.getColorFromAttribute import org.wordpress.android.util.extensions.redirectContextClickToLongPressListener import org.wordpress.android.util.image.ImageManager @@ -134,6 +141,9 @@ class SignupEpilogueFragment : LoginBaseFormFragment(), @Inject lateinit var mAvatarService: AvatarService + @Inject + lateinit var gravatarQuickEditorFeatureConfig: GravatarQuickEditorFeatureConfig + @LayoutRes override fun getContentLayout(): Int { return 0 // no content layout; entire view is inflated in createMainView @@ -163,7 +173,33 @@ class SignupEpilogueFragment : LoginBaseFormFragment(), headerAvatarLayout.isEnabled = mIsEmailSignup headerAvatarLayout.setOnClickListener { mUnifiedLoginTracker.trackClick(UnifiedLoginTracker.Click.SELECT_AVATAR) - mMediaPickerLauncher.showGravatarPicker(this@SignupEpilogueFragment) + if (gravatarQuickEditorFeatureConfig.isEnabled()) { + GravatarQuickEditor.show( + fragment = this, + gravatarQuickEditorParams = GravatarQuickEditorParams { + email = Email(mEmailAddress) + avatarPickerContentLayout = AvatarPickerContentLayout.Horizontal + }, + authenticationMethod = AuthenticationMethod.Bearer(mAccount.accessToken.orEmpty()), + onAvatarSelected = { + mPhotoUrl = AvatarUrl( + email = Email(mEmailAddress), + avatarQueryOptions = AvatarQueryOptions { + preferredSize = resources.getDimensionPixelSize(R.dimen.avatar_sz_large) + } + ).url(cacheBuster = System.currentTimeMillis().toString()).toString() + mImageManager.loadIntoCircle( + mHeaderAvatar, + ImageType.AVATAR_WITHOUT_BACKGROUND, + mPhotoUrl + ) + mHeaderAvatarAdd.visibility = View.GONE + mIsAvatarAdded = true + }, + ) + } else { + mMediaPickerLauncher.showGravatarPicker(this@SignupEpilogueFragment) + } } headerAvatarLayout.setOnLongClickListener { ToastUtils.showToast( From b62a12a7e14e80f7d4c915f1c4c45dc7544acf8b Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Wed, 30 Oct 2024 10:34:25 +0100 Subject: [PATCH 07/16] Bump navigation-compose to 2.8.3 to fix lint errors --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 344a3f5f623c..b05c6628d77b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ androidx-constraintlayout-compose = '1.0.1' androidx-core = '1.13.1' androidx-fragment = '1.8.4' androidx-lifecycle = '2.8.5' -androidx-navigation = '2.7.7' +androidx-navigation = '2.8.3' androidx-percentlayout = '1.0.0' androidx-preference = '1.2.1' androidx-recyclerview = '1.3.2' From 050e46abdb094bd20ea36080c0d9c35834683095 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Tue, 12 Nov 2024 13:11:51 -0500 Subject: [PATCH 08/16] Add "-testing" to support email for Automatticians so they can create Zendesk tickets --- .../org/wordpress/android/ui/ActivityLauncher.java | 1 - .../java/org/wordpress/android/ui/prefs/AppPrefs.java | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java b/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java index 4ff218801c45..e26a1ddbb622 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java @@ -1313,7 +1313,6 @@ public static void viewHelp(@NonNull Context context, @NonNull Origin origin, @N } public static void viewFeedbackForm(@NonNull Context context) { - warnIfIdentityA8C(context); AnalyticsTracker.track(Stat.APP_REVIEWS_FEEDBACK_SCREEN_OPENED); Intent intent = new Intent(context, FeedbackFormActivity.class); context.startActivity(intent); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java index df82fd7f5212..d00677af9c3a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java @@ -894,7 +894,15 @@ public static void setSupportEmail(String email) { } public static String getSupportEmail() { - return getString(DeletablePrefKey.SUPPORT_EMAIL); + String email = "nbradbury@automattic.com"; // TODO getString(DeletablePrefKey.SUPPORT_EMAIL); + // Zendesk can't create support tickets for Automattic email addresses from + // those with a staff member role (admin, agent, etc.), so insert "-testing" + // into the email to make it work + if ((email.contains("@automattic.com") || email.contains("@a8c.com")) && !email.contains("-testing@")) { + return email.replace("@", "-testing@"); + } else { + return email; + } } public static void removeSupportEmail() { From a0dccc1011dc0e10d62bd5f4ace11e0166ca95a1 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Tue, 12 Nov 2024 13:17:17 -0500 Subject: [PATCH 09/16] Removed warning about Automatticians not being able to submit Zendesk tickets --- .../org/wordpress/android/ui/ActivityLauncher.java | 13 ------------- .../wordpress/android/ui/accounts/HelpActivity.kt | 3 --- WordPress/src/main/res/values/strings.xml | 1 - 3 files changed, 17 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java b/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java index e26a1ddbb622..ef3442da21e2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java @@ -95,7 +95,6 @@ import org.wordpress.android.ui.posts.PostsListActivity; import org.wordpress.android.ui.posts.RemotePreviewLogicHelper.RemotePreviewType; import org.wordpress.android.ui.prefs.AccountSettingsActivity; -import org.wordpress.android.ui.prefs.AppPrefs; import org.wordpress.android.ui.prefs.AppSettingsActivity; import org.wordpress.android.ui.prefs.BlogPreferencesActivity; import org.wordpress.android.ui.prefs.MyProfileActivity; @@ -128,7 +127,6 @@ import org.wordpress.android.util.AppLog; import org.wordpress.android.util.AppLog.T; import org.wordpress.android.util.ToastUtils; -import org.wordpress.android.util.ToastUtils.Duration; import org.wordpress.android.util.UriWrapper; import org.wordpress.android.util.UrlUtils; import org.wordpress.android.util.WPActivityUtils; @@ -1323,17 +1321,6 @@ public static void viewZendeskTickets(@NonNull Context context, viewHelpInNewStack(context, Origin.ZENDESK_NOTIFICATION, selectedSite, null); } - /** - * Warn A8C users that they can't create Zendesk tickets - */ - @NonNull - public static void warnIfIdentityA8C(@NonNull Context context) { - String supportEmail = AppPrefs.getSupportEmail(); - if (supportEmail.contains("@automattic.com") || supportEmail.contains("@a8c.com")) { - ToastUtils.showToast(context, R.string.support_warn_if_user_a8c, Duration.LONG); - } - } - public static void viewSSLCerts(Context context, String certificateString) { Intent intent = new Intent(context, SSLCertsViewActivity.class); intent.putExtra(SSLCertsViewActivity.CERT_DETAILS_KEYS, certificateString.replaceAll("\n", "
")); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/HelpActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/accounts/HelpActivity.kt index c598cd683094..373d3ebac9bc 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/HelpActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/HelpActivity.kt @@ -173,7 +173,6 @@ class HelpActivity : LocaleAwareActivity() { } private fun launchSupportWidget() { - ActivityLauncher.warnIfIdentityA8C(this) val intent = SupportWebViewActivity.createIntent( this, originFromExtras, @@ -184,7 +183,6 @@ class HelpActivity : LocaleAwareActivity() { } private fun createNewZendeskTicket() { - ActivityLauncher.warnIfIdentityA8C(this) zendeskHelper.createNewTicket( this, originFromExtras, @@ -199,7 +197,6 @@ class HelpActivity : LocaleAwareActivity() { } private fun showZendeskTickets() { - ActivityLauncher.warnIfIdentityA8C(this) zendeskHelper.showAllTickets( this, originFromExtras, diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index 3a5204be5ac1..961232556cd6 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -1144,7 +1144,6 @@ Unable to create temporary file Add attachments If you need support, please get in touch using the \"Help & Support\" screen - Automattic email accounts can\'t submit or view support tickets Remove item %1$d From 312b6da9e1ff89f5b41ea4355829e4d824fa35da Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Tue, 12 Nov 2024 13:20:38 -0500 Subject: [PATCH 10/16] Removed TODO --- .../src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java index d00677af9c3a..3a97ae36648c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java @@ -894,7 +894,7 @@ public static void setSupportEmail(String email) { } public static String getSupportEmail() { - String email = "nbradbury@automattic.com"; // TODO getString(DeletablePrefKey.SUPPORT_EMAIL); + String email = getString(DeletablePrefKey.SUPPORT_EMAIL); // Zendesk can't create support tickets for Automattic email addresses from // those with a staff member role (admin, agent, etc.), so insert "-testing" // into the email to make it work From 98fe3207fe5a4bab1fc7b1dcc48205bd65c07c34 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Tue, 12 Nov 2024 15:07:56 -0500 Subject: [PATCH 11/16] Use +testing --- .../main/java/org/wordpress/android/ui/prefs/AppPrefs.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java index 3a97ae36648c..3ea62c3bc9ec 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java @@ -896,10 +896,10 @@ public static void setSupportEmail(String email) { public static String getSupportEmail() { String email = getString(DeletablePrefKey.SUPPORT_EMAIL); // Zendesk can't create support tickets for Automattic email addresses from - // those with a staff member role (admin, agent, etc.), so insert "-testing" + // those with a staff member role (admin, agent, etc.), so insert "+testing" // into the email to make it work if ((email.contains("@automattic.com") || email.contains("@a8c.com")) && !email.contains("-testing@")) { - return email.replace("@", "-testing@"); + return email.replace("@", "+testing@"); } else { return email; } From fa1a5c12b8a27a20775da23918f8fff226bd6dcb Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Tue, 12 Nov 2024 15:10:10 -0500 Subject: [PATCH 12/16] Use +testing, p2 --- .../src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java index 3ea62c3bc9ec..94e7c29cac3d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java @@ -898,7 +898,7 @@ public static String getSupportEmail() { // Zendesk can't create support tickets for Automattic email addresses from // those with a staff member role (admin, agent, etc.), so insert "+testing" // into the email to make it work - if ((email.contains("@automattic.com") || email.contains("@a8c.com")) && !email.contains("-testing@")) { + if ((email.contains("@automattic.com") || email.contains("@a8c.com")) && !email.contains("+testing@")) { return email.replace("@", "+testing@"); } else { return email; From c704bda5541aec2aa87ee90c2d3c6bf91513275a Mon Sep 17 00:00:00 2001 From: AdamGrzybkowski Date: Wed, 13 Nov 2024 15:49:15 +0100 Subject: [PATCH 13/16] Store updated avatar in the bitmap cache --- .../java/org/wordpress/android/ui/main/MeFragment.kt | 7 ++++--- .../android/ui/main/utils/MeGravatarLoader.kt | 10 ++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) 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 bb5bf62f19a6..01aaf4fb828e 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 @@ -495,9 +495,10 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { private fun MeFragmentBinding.loadAvatar(injectFilePath: String?, forceRefresh: Boolean = false) { val newAvatarUploaded = !injectFilePath.isNullOrEmpty() - val avatarUrl = meGravatarLoader.constructGravatarUrl(accountStore.account.avatarUrl, forceRefresh) + val avatarUrl = meGravatarLoader.constructGravatarUrl(accountStore.account.avatarUrl) + val newAvatarSelected = newAvatarUploaded || forceRefresh meGravatarLoader.load( - newAvatarUploaded, + newAvatarSelected, avatarUrl, injectFilePath, meAvatar, @@ -531,7 +532,7 @@ class MeFragment : Fragment(R.layout.me_fragment), OnScrollToTopListener { resource: Drawable, model: Any? ) { - if (newAvatarUploaded && resource is BitmapDrawable) { + if (newAvatarSelected && resource is BitmapDrawable) { var bitmap = resource.bitmap // create a copy since the original bitmap may by automatically recycled bitmap = bitmap.copy(bitmap.config, true) 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 510aa29967bd..3a25df553a77 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 @@ -20,14 +20,14 @@ class MeGravatarLoader @Inject constructor( private val resourseProvider: ResourceProvider ) { fun load( - newAvatarUploaded: Boolean, + newAvatarSelected: Boolean, avatarUrl: String, injectFilePath: String?, imageView: ImageView, imageType: ImageType, listener: RequestListener? = null ) { - if (newAvatarUploaded) { + if (newAvatarSelected) { // invalidate the specific gravatar entry from the bitmap cache. It will be updated via the injected // request cache. WordPress.getBitmapCache().removeSimilar(avatarUrl) @@ -45,10 +45,12 @@ class MeGravatarLoader @Inject constructor( imageManager.loadIntoCircle( imageView, imageType, - if (newAvatarUploaded && injectFilePath != null) { + if (newAvatarSelected && injectFilePath != null) { injectFilePath } else { - avatarUrl + // If new avatar selected we force refresh the avatar + val constructGravatarUrl = constructGravatarUrl(avatarUrl, newAvatarSelected) + constructGravatarUrl }, listener, appPrefsWrapper.avatarVersion From d4ef0a49044e75d96cdecf63ebaf80249b7a25c9 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 14 Nov 2024 06:20:15 -0500 Subject: [PATCH 14/16] Don't adjust email if it contains "+" already --- .../src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java index 94e7c29cac3d..730015636893 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java @@ -898,7 +898,7 @@ public static String getSupportEmail() { // Zendesk can't create support tickets for Automattic email addresses from // those with a staff member role (admin, agent, etc.), so insert "+testing" // into the email to make it work - if ((email.contains("@automattic.com") || email.contains("@a8c.com")) && !email.contains("+testing@")) { + if ((email.contains("@automattic.com") || email.contains("@a8c.com")) && !email.contains("+")) { return email.replace("@", "+testing@"); } else { return email; From fe3c13c01dbe43df64f005cccab74afb3c5798ce Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 14 Nov 2024 06:22:36 -0500 Subject: [PATCH 15/16] Updated comment --- .../main/java/org/wordpress/android/ui/prefs/AppPrefs.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java index 730015636893..1f68f23d1bd9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java @@ -895,9 +895,9 @@ public static void setSupportEmail(String email) { public static String getSupportEmail() { String email = getString(DeletablePrefKey.SUPPORT_EMAIL); - // Zendesk can't create support tickets for Automattic email addresses from - // those with a staff member role (admin, agent, etc.), so insert "+testing" - // into the email to make it work + // Zendesk can't create support tickets for Automattic email addresses + // with a staff member role (admin, agent, etc.), so insert an "+testing" + // alias into the email to make it work if ((email.contains("@automattic.com") || email.contains("@a8c.com")) && !email.contains("+")) { return email.replace("@", "+testing@"); } else { From 7d7722286e3edf1e4568fef280ef1a99008aa701 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 14 Nov 2024 06:46:26 -0500 Subject: [PATCH 16/16] Updated string --- WordPress/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index 43cf9bf27844..78401d0c00f3 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -1146,7 +1146,7 @@ Attachment already added Unable to create temporary file Add attachments - If you need support, please get in touch using the \"Help & Support\" screen + If you need support, please get in touch using the \"Contact Support\" screen Remove item %1$d