From 653f01e98f0231af3e5e4690438186cea0e25c14 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 10 Sep 2024 17:25:11 +0200 Subject: [PATCH 01/30] Add GutenbergKit feature flag --- WordPress/build.gradle | 1 + .../util/config/NewGutenbergFeatureConfig.kt | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/util/config/NewGutenbergFeatureConfig.kt diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 739eef69b74a..e321c3900b68 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -217,6 +217,7 @@ android { buildConfigField "boolean", "ENABLE_SITE_MONITORING", "false" buildConfigField "boolean", "SYNC_PUBLISHING", "false" buildConfigField "boolean", "ENABLE_IN_APP_UPDATES", "false" + buildConfigField "boolean", "ENABLE_NEW_GUTENBERG", "false" manifestPlaceholders = [magicLinkScheme:"wordpress"] } diff --git a/WordPress/src/main/java/org/wordpress/android/util/config/NewGutenbergFeatureConfig.kt b/WordPress/src/main/java/org/wordpress/android/util/config/NewGutenbergFeatureConfig.kt new file mode 100644 index 000000000000..57c65030f957 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/util/config/NewGutenbergFeatureConfig.kt @@ -0,0 +1,16 @@ +package org.wordpress.android.util.config + +import org.wordpress.android.BuildConfig +import org.wordpress.android.annotation.Feature +import javax.inject.Inject + +private const val NEW_GUTENBERG_FEATURE_REMOTE_FIELD = "experimental_block_editor" + +@Feature(NEW_GUTENBERG_FEATURE_REMOTE_FIELD, false) +class NewGutenbergFeatureConfig @Inject constructor( + appConfig: AppConfig +) : FeatureConfig( + appConfig, + BuildConfig.ENABLE_NEW_GUTENBERG, + NEW_GUTENBERG_FEATURE_REMOTE_FIELD +) From ede76fc7c3ac45ae183e10bbb78ab3fe17b038de Mon Sep 17 00:00:00 2001 From: Gerardo Date: Wed, 11 Sep 2024 12:15:12 +0200 Subject: [PATCH 02/30] Add GutenbergKit dependency --- WordPress/build.gradle | 1 + build.gradle | 1 + libs/editor/build.gradle | 2 ++ 3 files changed, 4 insertions(+) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index e321c3900b68..382e3b293e08 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -93,6 +93,7 @@ repositories { includeGroup "org.wordpress.fluxc" includeGroup "org.wordpress.wellsql" includeGroup "org.wordpress.gutenberg-mobile" + includeGroup "org.wordpress.gutenbergkit" includeGroupByRegex "org.wordpress.react-native-libraries.*" includeGroup "com.automattic" includeGroup "com.automattic.tracks" diff --git a/build.gradle b/build.gradle index 5d088b8b0eb6..e02f2ddd0b10 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' + gutenbergKitVersion = '23-e1e299bf87790a11d6fa8946962aeff226cb50de' // main androidInstallReferrerVersion = '2.2' diff --git a/libs/editor/build.gradle b/libs/editor/build.gradle index aff1c1205df7..06eba2b90af8 100644 --- a/libs/editor/build.gradle +++ b/libs/editor/build.gradle @@ -12,6 +12,7 @@ repositories { includeGroup "org.wordpress" includeGroup "org.wordpress.aztec" includeGroup "org.wordpress.gutenberg-mobile" + includeGroup "org.wordpress.gutenbergkit" includeGroupByRegex "org.wordpress.react-native-libraries.*" includeGroup "com.automattic" includeGroup "com.automattic.tracks" @@ -94,6 +95,7 @@ dependencies { } implementation "org.wordpress:utils:$wordPressUtilsVersion" + implementation "org.wordpress.gutenbergkit:android:$gutenbergKitVersion" implementation "androidx.lifecycle:lifecycle-common:$androidxLifecycleVersion" implementation "androidx.lifecycle:lifecycle-runtime:$androidxLifecycleVersion" From 7b5d5f92cadf5194f50cc257ac5dccfa2f434749 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Wed, 11 Sep 2024 17:09:30 +0200 Subject: [PATCH 03/30] Add initial support for GutenbergKit --- .../android/ui/posts/EditPostActivity.kt | 6 ++- .../gutenberg/GutenbergEditorFragment.java | 54 +++++++++++++++---- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index 9aa19afc9cf5..f69de93539aa 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -235,6 +235,7 @@ import org.wordpress.android.util.analytics.AnalyticsUtils.BlockEditorEnabledSou import org.wordpress.android.util.config.ContactSupportFeatureConfig import org.wordpress.android.util.config.GlobalStyleSupportFeatureConfig import org.wordpress.android.util.config.PostConflictResolutionFeatureConfig +import org.wordpress.android.util.config.NewGutenbergFeatureConfig import org.wordpress.android.util.extensions.setLiftOnScrollTargetViewIdAndRequestLayout import org.wordpress.android.util.helpers.MediaFile import org.wordpress.android.util.helpers.MediaGallery @@ -406,6 +407,8 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm @Inject lateinit var postConflictResolutionFeatureConfig: PostConflictResolutionFeatureConfig + @Inject lateinit var newGutenbergFeatureConfig: NewGutenbergFeatureConfig + @Inject lateinit var storePostViewModel: StorePostViewModel @Inject lateinit var storageUtilsViewModel: StorageUtilsViewModel @Inject lateinit var editorBloggingPromptsViewModel: EditorBloggingPromptsViewModel @@ -2403,7 +2406,8 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm isNewPost, gutenbergWebViewAuthorizationData, gutenbergPropsBuilder, - jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures() + jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(), + newGutenbergFeatureConfig.isEnabled() ) } else { // If gutenberg editor is not selected, default to Aztec. diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 859dadef8272..bda37adec17d 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -89,6 +89,7 @@ import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnMediaLibraryButtonListener; import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnReattachMediaUploadQueryListener; import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnSetFeaturedImageListener; +import org.wordpress.gutenberg.GutenbergView; import java.util.ArrayList; import java.util.Date; @@ -109,6 +110,7 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements GutenbergDialogPositiveClickInterface, GutenbergDialogNegativeClickInterface, GutenbergNetworkConnectionListener { + private GutenbergView mGutenbergView; private static final String GUTENBERG_EDITOR_NAME = "gutenberg"; private static final String KEY_HTML_MODE_ENABLED = "KEY_HTML_MODE_ENABLED"; private static final String KEY_EDITOR_DID_MOUNT = "KEY_EDITOR_DID_MOUNT"; @@ -156,6 +158,7 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private boolean mIsNewPost; private boolean mIsJetpackSsoEnabled; + private static boolean mIsNewGutenbergEnabled; private boolean mEditorDidMount; private GutenbergPropsBuilder mCurrentGutenbergPropsBuilder; @@ -171,13 +174,15 @@ public static GutenbergEditorFragment newInstance(Context context, boolean isNewPost, GutenbergWebViewAuthorizationData webViewAuthorizationData, GutenbergPropsBuilder gutenbergPropsBuilder, - boolean jetpackFeaturesEnabled) { + boolean jetpackFeaturesEnabled, + boolean newGutenbergEnabled) { GutenbergEditorFragment fragment = new GutenbergEditorFragment(); Bundle args = new Bundle(); args.putBoolean(ARG_IS_NEW_POST, isNewPost); args.putBoolean(ARG_JETPACK_FEATURES_ENABLED, jetpackFeaturesEnabled); fragment.setArguments(args); SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(context); + mIsNewGutenbergEnabled = newGutenbergEnabled; if (db != null) { db.addParcel(ARG_GUTENBERG_WEB_VIEW_AUTH_DATA, webViewAuthorizationData); db.addParcel(ARG_GUTENBERG_PROPS_BUILDER, gutenbergPropsBuilder); @@ -210,16 +215,18 @@ public void onCreate(@Nullable Bundle savedInstanceState) { } mCurrentGutenbergPropsBuilder = gutenbergPropsBuilder; - FragmentManager fragmentManager = getChildFragmentManager(); - FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - GutenbergContainerFragment fragment = - GutenbergContainerFragment.newInstance(requireContext(), gutenbergPropsBuilder); - fragment.setRetainInstance(true); - fragmentTransaction.add(fragment, GutenbergContainerFragment.TAG); - fragmentTransaction.commitNow(); + if (!mIsNewGutenbergEnabled) { + FragmentManager fragmentManager = getChildFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + GutenbergContainerFragment fragment = + GutenbergContainerFragment.newInstance(requireContext(), gutenbergPropsBuilder); + fragment.setRetainInstance(true); + fragmentTransaction.add(fragment, GutenbergContainerFragment.TAG); + fragmentTransaction.commitNow(); + } } - if (mUpdateCapabilitiesOnCreate) { + if (mUpdateCapabilitiesOnCreate && !mIsNewGutenbergEnabled) { getGutenbergContainerFragment().updateCapabilities(mCurrentGutenbergPropsBuilder); } @@ -239,6 +246,25 @@ public void onCreate(@Nullable Bundle savedInstanceState) { @SuppressWarnings("MethodLength") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + if (mIsNewGutenbergEnabled) { + mGutenbergView = new GutenbergView(requireContext()); + mGutenbergView.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + )); + mGutenbergView.start( + "", + "", + "", + false, + null, + "post", + "", + "" + ); + + return mGutenbergView; + } View view = inflater.inflate(R.layout.fragment_gutenberg_editor, container, false); initializeSavingProgressDialog(); @@ -778,6 +804,10 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis } private void setEditorProgressBarVisibility(boolean shown) { + if (mIsNewGutenbergEnabled) { + return; + } + if (isAdded() && getView() != null) { getView().findViewById(R.id.editor_progress).setVisibility(shown ? View.VISIBLE : View.GONE); } @@ -1170,6 +1200,9 @@ private String removeVisualEditorProgressTag(String originalText) { @Override public Pair getTitleAndContent(CharSequence originalContent) throws EditorFragmentNotAddedException { + if (mIsNewGutenbergEnabled) { + return new Pair<>("", ""); + } if (!isAdded()) { throw new EditorFragmentNotAddedException(); } @@ -1442,6 +1475,9 @@ public void onGalleryMediaUploadSucceeded(final long galleryId, long remoteMedia @Override public void onEditorThemeUpdated(Bundle editorTheme) { + if (mIsNewGutenbergEnabled) { + return; + } getGutenbergContainerFragment().updateTheme(editorTheme); } From 8414f9df73d28f0a69b323d04bb216ea279d115c Mon Sep 17 00:00:00 2001 From: Gerardo Date: Wed, 11 Sep 2024 20:10:49 +0200 Subject: [PATCH 04/30] Set editor settings --- .../android/ui/posts/EditPostActivity.kt | 19 ++++++++++++++++- .../gutenberg/GutenbergEditorFragment.java | 21 +++++++++++-------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index f69de93539aa..9fa5a8d4b747 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -2401,13 +2401,30 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm userAgent.toString(), isJetpackSsoEnabled ) + val postType = if (editPostRepository.isPage) "page" else "post" + val siteApiRoot = if (isWpCom) "https://public-api.wordpress.com/" else "" + val siteId = site.siteId + val authToken = accountStore.accessToken + val authHeader = "Bearer $authToken" + val siteApiNamespace = "sites/${siteId}" + + val settings = mutableMapOf( + "postId" to editPostRepository.getPost()?.remotePostId?.toInt(), + "postType" to postType, + "postTitle" to editPostRepository.getPost()?.title, + "postContent" to editPostRepository.getPost()?.content, + "siteApiRoot" to siteApiRoot, + "authHeader" to authHeader, + "siteApiNamespace" to siteApiNamespace + ) return GutenbergEditorFragment.newInstance( getContext(), isNewPost, gutenbergWebViewAuthorizationData, gutenbergPropsBuilder, jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(), - newGutenbergFeatureConfig.isEnabled() + newGutenbergFeatureConfig.isEnabled(), + settings ) } else { // If gutenberg editor is not selected, default to Aztec. diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index bda37adec17d..123cecd79d7e 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -169,13 +169,15 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private String mUpdatedStoryBlockContent = null; private ProgressDialog mSavingContentProgressDialog; + private static Map mSettings; public static GutenbergEditorFragment newInstance(Context context, boolean isNewPost, GutenbergWebViewAuthorizationData webViewAuthorizationData, GutenbergPropsBuilder gutenbergPropsBuilder, boolean jetpackFeaturesEnabled, - boolean newGutenbergEnabled) { + boolean newGutenbergEnabled, + Map settings) { GutenbergEditorFragment fragment = new GutenbergEditorFragment(); Bundle args = new Bundle(); args.putBoolean(ARG_IS_NEW_POST, isNewPost); @@ -183,6 +185,7 @@ public static GutenbergEditorFragment newInstance(Context context, fragment.setArguments(args); SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(context); mIsNewGutenbergEnabled = newGutenbergEnabled; + mSettings = settings; if (db != null) { db.addParcel(ARG_GUTENBERG_WEB_VIEW_AUTH_DATA, webViewAuthorizationData); db.addParcel(ARG_GUTENBERG_PROPS_BUILDER, gutenbergPropsBuilder); @@ -253,14 +256,14 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa ViewGroup.LayoutParams.MATCH_PARENT )); mGutenbergView.start( - "", - "", - "", - false, - null, - "post", - "", - "" + (String) mSettings.get("siteApiRoot"), + (String) mSettings.get("siteApiNamespace"), + (String) mSettings.get("authHeader"), + true, + (Integer) mSettings.get("postId"), + (String) mSettings.get("postType"), + (String) mSettings.get("postTitle"), + (String) mSettings.get("postContent") ); return mGutenbergView; From 693fe0410c1422ef437eae4c19d5af5391de0806 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Thu, 12 Sep 2024 17:15:29 +0200 Subject: [PATCH 05/30] Destroy view --- .../android/editor/gutenberg/GutenbergEditorFragment.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 123cecd79d7e..87e32ac704c5 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -1405,6 +1405,9 @@ private boolean hideSavingProgressDialog() { @Override public void onDestroy() { + if (mIsNewGutenbergEnabled && mGutenbergView != null) { + mGutenbergView.destroy(); + } hideSavingProgressDialog(); super.onDestroy(); } From c0b808782647b4e948a482a0e12e361eee874a89 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Thu, 12 Sep 2024 17:15:39 +0200 Subject: [PATCH 06/30] Update GutenbergKit ref --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e02f2ddd0b10..f0ab3aa8b744 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-e1e299bf87790a11d6fa8946962aeff226cb50de' + gutenbergKitVersion = '23-21bc472bbbe9e6bea683e40a60a7502dec5aaf3f' // main androidInstallReferrerVersion = '2.2' From 689ccc97bd7b5c2993d90916865bb5b08a0fbf44 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 17 Sep 2024 18:23:47 +0200 Subject: [PATCH 07/30] Split SectionPagerAdapter --- .../android/ui/posts/EditPostActivity.kt | 133 +++++++++--------- 1 file changed, 68 insertions(+), 65 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index 9fa5a8d4b747..803d28d0bf20 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -2371,84 +2371,87 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm */ inner class SectionsPagerAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + @Suppress("ReturnCount") override fun getItem(position: Int): Fragment { - // getItem is called to instantiate the fragment for the given page. - when (position) { - PAGE_CONTENT -> if (showGutenbergEditor) { - // Enable gutenberg on the site & show the informative popup upon opening - // the GB editor the first time when the remote setting value is still null - setGutenbergEnabledIfNeeded() - xPostsCapabilityChecker.retrieveCapability(siteModel) { isXpostsCapable: Boolean -> - onXpostsSettingsCapability( - isXpostsCapable - ) + return when (position) { + PAGE_CONTENT -> { + if (showGutenbergEditor) { + createGutenbergEditorFragment() + } else { + // If gutenberg editor is not selected, default to Aztec. + AztecEditorFragment.newInstance("", "", AppPrefs.isAztecEditorToolbarExpanded()) } - val isWpCom: Boolean = site.isWPCom || siteModel.isPrivateWPComAtomic || siteModel.isWPComAtomic - val gutenbergPropsBuilder = gutenbergPropsBuilder - val gutenbergWebViewAuthorizationData = - GutenbergWebViewAuthorizationData( - siteModel.url, - isWpCom, - accountStore.account.userId, - accountStore.account.userName, - accountStore.accessToken, - siteModel.selfHostedSiteId, - siteModel.username, - siteModel.password, - siteModel.isUsingWpComRestApi, - siteModel.webEditor, - userAgent.toString(), - isJetpackSsoEnabled - ) - val postType = if (editPostRepository.isPage) "page" else "post" - val siteApiRoot = if (isWpCom) "https://public-api.wordpress.com/" else "" - val siteId = site.siteId - val authToken = accountStore.accessToken - val authHeader = "Bearer $authToken" - val siteApiNamespace = "sites/${siteId}" - - val settings = mutableMapOf( - "postId" to editPostRepository.getPost()?.remotePostId?.toInt(), - "postType" to postType, - "postTitle" to editPostRepository.getPost()?.title, - "postContent" to editPostRepository.getPost()?.content, - "siteApiRoot" to siteApiRoot, - "authHeader" to authHeader, - "siteApiNamespace" to siteApiNamespace - ) - return GutenbergEditorFragment.newInstance( - getContext(), - isNewPost, - gutenbergWebViewAuthorizationData, - gutenbergPropsBuilder, - jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(), - newGutenbergFeatureConfig.isEnabled(), - settings - ) - } else { - // If gutenberg editor is not selected, default to Aztec. - return AztecEditorFragment.newInstance("", "", AppPrefs.isAztecEditorToolbarExpanded()) } - - PAGE_SETTINGS -> return EditPostSettingsFragment.newInstance() - PAGE_PUBLISH_SETTINGS -> return newInstance() - PAGE_HISTORY -> return newInstance( - editPostRepository.id, siteModel - ) - + PAGE_SETTINGS -> EditPostSettingsFragment.newInstance() + PAGE_PUBLISH_SETTINGS -> newInstance() + PAGE_HISTORY -> newInstance(editPostRepository.id, siteModel) else -> throw IllegalArgumentException("Unexpected page type") } } + private fun createGutenbergEditorFragment(): GutenbergEditorFragment { + // Enable gutenberg on the site & show the informative popup upon opening + // the GB editor the first time when the remote setting value is still null + setGutenbergEnabledIfNeeded() + xPostsCapabilityChecker.retrieveCapability(siteModel) { isXpostsCapable -> + onXpostsSettingsCapability(isXpostsCapable) + } + + val isWpCom = site.isWPCom || siteModel.isPrivateWPComAtomic || siteModel.isWPComAtomic + val gutenbergPropsBuilder = gutenbergPropsBuilder + val gutenbergWebViewAuthorizationData = GutenbergWebViewAuthorizationData( + siteModel.url, + isWpCom, + accountStore.account.userId, + accountStore.account.userName, + accountStore.accessToken, + siteModel.selfHostedSiteId, + siteModel.username, + siteModel.password, + siteModel.isUsingWpComRestApi, + siteModel.webEditor, + userAgent.toString(), + isJetpackSsoEnabled + ) + + val postType = if (editPostRepository.isPage) "page" else "post" + val siteApiRoot = if (isWpCom) "https://public-api.wordpress.com/" else "" + val siteId = site.siteId + val authToken = accountStore.accessToken + val authHeader = "Bearer $authToken" + val siteApiNamespace = "sites/$siteId" + + val settings = mutableMapOf( + "postId" to editPostRepository.getPost()?.remotePostId?.toInt(), + "postType" to postType, + "postTitle" to editPostRepository.getPost()?.title, + "postContent" to editPostRepository.getPost()?.content, + "siteApiRoot" to siteApiRoot, + "authHeader" to authHeader, + "siteApiNamespace" to siteApiNamespace + ) + + return GutenbergEditorFragment.newInstance( + getContext(), + isNewPost, + gutenbergWebViewAuthorizationData, + gutenbergPropsBuilder, + jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(), + newGutenbergFeatureConfig.isEnabled(), + settings + ) + } + override fun instantiateItem(container: ViewGroup, position: Int): Any { val fragment: Fragment = super.instantiateItem(container, position) as Fragment when (position) { PAGE_CONTENT -> { editorFragment = fragment as EditorFragmentAbstract editorFragment?.setImageLoader(imageLoader) - editorFragment?.titleOrContentChanged?.observe(this@EditPostActivity - ) { _: Editable? -> storePostViewModel.savePostWithDelay() } + editorFragment?.titleOrContentChanged?.observe(this@EditPostActivity) { _: Editable? -> + storePostViewModel.savePostWithDelay() + } if (editorFragment is EditorMediaUploadListener) { editorMediaUploadListener = editorFragment as EditorMediaUploadListener? @@ -2457,7 +2460,6 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm reattachUploadingMediaForAztec() } } - PAGE_SETTINGS -> editPostSettingsFragment = fragment as EditPostSettingsFragment } return fragment @@ -2466,6 +2468,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm override fun getCount(): Int { return numPagesInEditor } + private val numPagesInEditor: Int = 4 } From da9e2463eb4c5ccfd65d7ab594223ee892a91bbb Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 17 Sep 2024 18:24:13 +0200 Subject: [PATCH 08/30] Update GutenbergKit ref --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d8f71eebb3e3..099b6f271c3c 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-21bc472bbbe9e6bea683e40a60a7502dec5aaf3f' + gutenbergKitVersion = '23-033a1172512e89027a36f6b65cc566e72a852567' // main androidInstallReferrerVersion = '2.2' From e7242ee20e5cec37f6ab8eae96dfd04bf6dfcdf2 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Wed, 18 Sep 2024 11:35:04 +0200 Subject: [PATCH 09/30] Fix code style issue --- .../main/java/org/wordpress/android/ui/posts/EditPostActivity.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index 803d28d0bf20..1319a81c9053 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -2371,7 +2371,6 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm */ inner class SectionsPagerAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { - @Suppress("ReturnCount") override fun getItem(position: Int): Fragment { return when (position) { From 3c98992ebaf46c6e939aed8c035c930e28204a0a Mon Sep 17 00:00:00 2001 From: Gerardo Date: Wed, 18 Sep 2024 20:03:53 +0200 Subject: [PATCH 10/30] Update getTitleAndContent --- build.gradle | 2 +- .../gutenberg/GutenbergEditorFragment.java | 36 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 099b6f271c3c..a8f2a302d8be 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-033a1172512e89027a36f6b65cc566e72a852567' + gutenbergKitVersion = '23-200b4c4ae4a687333c8f65844cd7051d68ca9f61' // main androidInstallReferrerVersion = '2.2' diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 87e32ac704c5..ea2fcbeb1d00 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -90,6 +90,7 @@ import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnReattachMediaUploadQueryListener; import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnSetFeaturedImageListener; import org.wordpress.gutenberg.GutenbergView; +import org.wordpress.gutenberg.GutenbergView.TitleAndContentCallback; import java.util.ArrayList; import java.util.Date; @@ -99,6 +100,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; import java.util.stream.Collectors; import static org.wordpress.mobile.WPAndroidGlue.Media.createRNMediaUsingMimeType; @@ -255,12 +257,18 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT )); + + Integer postId = (Integer) mSettings.get("postId"); + if (postId != null && postId == 0) { + postId = null; + } + mGutenbergView.start( (String) mSettings.get("siteApiRoot"), (String) mSettings.get("siteApiNamespace"), (String) mSettings.get("authHeader"), true, - (Integer) mSettings.get("postId"), + postId, (String) mSettings.get("postType"), (String) mSettings.get("postTitle"), (String) mSettings.get("postContent") @@ -1116,6 +1124,9 @@ public void setTitle(CharSequence title) { title = ""; } + if (mIsNewGutenbergEnabled) { + return; + } getGutenbergContainerFragment().setTitle(title.toString()); } @@ -1180,6 +1191,9 @@ private void toggleHtmlMode() { } public void sendToJSPostSaveEvent() { + if (mIsNewGutenbergEnabled) { + return; + } getGutenbergContainerFragment().sendToJSPostSaveEvent(); } @@ -1204,7 +1218,25 @@ private String removeVisualEditorProgressTag(String originalText) { public Pair getTitleAndContent(CharSequence originalContent) throws EditorFragmentNotAddedException { if (mIsNewGutenbergEnabled) { - return new Pair<>("", ""); + final Pair[] result = new Pair[1]; + final CountDownLatch latch = new CountDownLatch(1); + + mGutenbergView.getTitleAndContent(new TitleAndContentCallback() { + @Override + public void onResult(@Nullable String title, @NonNull String content) { + result[0] = new Pair<>(title, content); + latch.countDown(); + } + }); + + try { + latch.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return new Pair<>("", ""); + } + + return result[0] != null ? result[0] : new Pair<>("", ""); } if (!isAdded()) { throw new EditorFragmentNotAddedException(); From 907308779613574be4fad22119857eb4cc5c3dce Mon Sep 17 00:00:00 2001 From: Gerardo Date: Thu, 19 Sep 2024 16:06:12 +0200 Subject: [PATCH 11/30] Add support for file uploads --- build.gradle | 2 +- .../gutenberg/GutenbergEditorFragment.java | 39 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index a8f2a302d8be..96a245d97e90 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-200b4c4ae4a687333c8f65844cd7051d68ca9f61' + gutenbergKitVersion = '23-2b36ffb00beb38fbd6c5b5d77d9e31ab25c09b82' // main androidInstallReferrerVersion = '2.2' diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index ea2fcbeb1d00..d63cc9c97830 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -2,9 +2,11 @@ import android.app.Activity; import android.app.ProgressDialog; +import android.content.ClipData; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -18,6 +20,7 @@ import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.webkit.URLUtil; +import android.webkit.ValueCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -257,17 +260,20 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT )); + mGutenbergView.setOnFileChooserRequested((intent, requestCode) -> { + startActivityForResult(intent, requestCode); + return null; + }); Integer postId = (Integer) mSettings.get("postId"); if (postId != null && postId == 0) { - postId = null; + postId = -1; } - mGutenbergView.start( (String) mSettings.get("siteApiRoot"), (String) mSettings.get("siteApiNamespace"), (String) mSettings.get("authHeader"), - true, + true, // Set as a FeatureFlag postId, (String) mSettings.get("postType"), (String) mSettings.get("postTitle"), @@ -712,6 +718,33 @@ private void openGutenbergEmbedWebViewActivity(String html, String title) { public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); + if (mIsNewGutenbergEnabled) { + if (requestCode == mGutenbergView.getPickImageRequestCode()) { + ValueCallback filePathCallback = mGutenbergView.getFilePathCallback(); + + if (filePathCallback != null) { + if (resultCode == Activity.RESULT_OK && data != null) { + if (data.getClipData() != null) { + ClipData clipData = data.getClipData(); + Uri[] uris = new Uri[clipData.getItemCount()]; + for (int i = 0; i < clipData.getItemCount(); i++) { + uris[i] = clipData.getItemAt(i).getUri(); + } + filePathCallback.onReceiveValue(uris); + } else if (data.getData() != null) { + Uri uri = data.getData(); + filePathCallback.onReceiveValue(new Uri[]{uri}); + } else { + filePathCallback.onReceiveValue(null); + } + } else { + filePathCallback.onReceiveValue(null); + } + mGutenbergView.resetFilePathCallback(); + } + } + } + if (requestCode == UNSUPPORTED_BLOCK_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { String blockId = data.getStringExtra(WPGutenbergWebViewActivity.ARG_BLOCK_ID); From 11c41a6d950686be264677aa36e48f7f5ae1773b Mon Sep 17 00:00:00 2001 From: Gerardo Date: Thu, 19 Sep 2024 18:24:41 +0200 Subject: [PATCH 12/30] Restore instance when the activity is stopped while in the background --- .../android/ui/posts/EditPostActivity.kt | 7 ++++- .../ui/posts/EditPostActivityConstants.kt | 1 + .../gutenberg/GutenbergEditorFragment.java | 27 ++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index 1319a81c9053..209cb86519d0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -311,6 +311,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm private var isXPostsCapable: Boolean? = null private var onGetSuggestionResult: Consumer? = null private var isVoiceContentSet = false + private var isNewGutenbergEditor = false // For opening the context menu after permissions have been granted private var menuView: View? = null @@ -513,6 +514,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm } onBackPressedDispatcher.addCallback(this, callback) dispatcher.register(this) + isNewGutenbergEditor = newGutenbergFeatureConfig.isEnabled() createEditShareMessageActivityResultLauncher() @@ -721,6 +723,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm } isNewPost = state.getBoolean(EditPostActivityConstants.STATE_KEY_IS_NEW_POST, false) + isNewGutenbergEditor = state.getBoolean(EditPostActivityConstants.STATE_KEY_IS_NEW_GUTENBERG, false) isVoiceContentSet = state.getBoolean(EditPostActivityConstants.STATE_KEY_IS_VOICE_CONTENT_SET, false) updatePostLoadingAndDialogState( fromInt( @@ -1191,6 +1194,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm outState.putInt(EditPostActivityConstants.STATE_KEY_POST_LOADING_STATE, postLoadingState.value) outState.putBoolean(EditPostActivityConstants.STATE_KEY_IS_NEW_POST, isNewPost) outState.putBoolean(EditPostActivityConstants.STATE_KEY_IS_VOICE_CONTENT_SET, isVoiceContentSet) + outState.putBoolean(EditPostActivityConstants.STATE_KEY_IS_NEW_GUTENBERG, isNewGutenbergEditor) outState.putBoolean( EditPostActivityConstants.STATE_KEY_IS_PHOTO_PICKER_VISIBLE, editorPhotoPicker?.isPhotoPickerShowing() ?: false @@ -2146,6 +2150,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm i.putExtra(EditPostActivityConstants.EXTRA_RESTART_EDITOR, restartEditorOption.name) i.putExtra(EditPostActivityConstants.STATE_KEY_EDITOR_SESSION_DATA, postEditorAnalyticsSession) i.putExtra(EditPostActivityConstants.EXTRA_IS_NEW_POST, isNewPost) + i.putExtra(EditPostActivityConstants.STATE_KEY_IS_NEW_GUTENBERG, isNewGutenbergEditor) setResult(RESULT_OK, i) } @@ -2437,7 +2442,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm gutenbergWebViewAuthorizationData, gutenbergPropsBuilder, jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(), - newGutenbergFeatureConfig.isEnabled(), + isNewGutenbergEditor, settings ) } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivityConstants.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivityConstants.kt index 77cf11f42b7f..efd64596609a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivityConstants.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivityConstants.kt @@ -42,4 +42,5 @@ object EditPostActivityConstants{ const val STATE_KEY_UNDO = "stateKeyUndo" const val STATE_KEY_REDO = "stateKeyRedo" const val STATE_KEY_IS_VOICE_CONTENT_SET = "stateKeyIsVoiceContentSet" + const val STATE_KEY_IS_NEW_GUTENBERG = "stateKeyIsNewGutenberg" } diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index d63cc9c97830..128151a7bd15 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -95,6 +95,7 @@ import org.wordpress.gutenberg.GutenbergView; import org.wordpress.gutenberg.GutenbergView.TitleAndContentCallback; +import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -126,6 +127,8 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements public static final String ARG_FAILED_MEDIAS = "arg_failed_medias"; public static final String ARG_FEATURED_IMAGE_ID = "featured_image_id"; public static final String ARG_JETPACK_FEATURES_ENABLED = "jetpack_features_enabled"; + public static final String ARG_IS_NEW_GUTENBERG_ENABLED = "new_gutenberg"; + public static final String ARG_NEW_GUTENBERG_SETTINGS = "new_gutenberg_settings"; private static final int CAPTURE_PHOTO_PERMISSION_REQUEST_CODE = 101; private static final int CAPTURE_VIDEO_PERMISSION_REQUEST_CODE = 102; @@ -187,6 +190,8 @@ public static GutenbergEditorFragment newInstance(Context context, Bundle args = new Bundle(); args.putBoolean(ARG_IS_NEW_POST, isNewPost); args.putBoolean(ARG_JETPACK_FEATURES_ENABLED, jetpackFeaturesEnabled); + args.putBoolean(ARG_IS_NEW_GUTENBERG_ENABLED, newGutenbergEnabled); + args.putSerializable(ARG_NEW_GUTENBERG_SETTINGS, (Serializable) settings); fragment.setArguments(args); SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(context); mIsNewGutenbergEnabled = newGutenbergEnabled; @@ -199,6 +204,10 @@ public static GutenbergEditorFragment newInstance(Context context, } private GutenbergContainerFragment getGutenbergContainerFragment() { + if (mIsNewGutenbergEnabled) { + return mRetainedGutenbergContainerFragment; + } + if (mRetainedGutenbergContainerFragment == null) { mRetainedGutenbergContainerFragment = (GutenbergContainerFragment) getChildFragmentManager() .findFragmentByTag(GutenbergContainerFragment.TAG); @@ -215,6 +224,10 @@ private GutenbergContainerFragment getGutenbergContainerFragment() { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (getArguments() != null) { + mIsNewGutenbergEnabled = getArguments().getBoolean(ARG_IS_NEW_GUTENBERG_ENABLED); + } + if (getGutenbergContainerFragment() == null) { GutenbergPropsBuilder gutenbergPropsBuilder = null; SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(getContext()); @@ -248,12 +261,19 @@ public void onCreate(@Nullable Bundle savedInstanceState) { ARG_STORY_BLOCK_EXTERNALLY_EDITED_ORIGINAL_HASH); mFailedMediaIds = (HashSet) savedInstanceState.getSerializable(ARG_FAILED_MEDIAS); mFeaturedImageId = savedInstanceState.getLong(ARG_FEATURED_IMAGE_ID); + mIsNewGutenbergEnabled = savedInstanceState.getBoolean(ARG_IS_NEW_GUTENBERG_ENABLED); } } @SuppressWarnings("MethodLength") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + if (getArguments() != null) { + mIsNewPost = getArguments().getBoolean(ARG_IS_NEW_POST); + mIsNewGutenbergEnabled = getArguments().getBoolean(ARG_IS_NEW_GUTENBERG_ENABLED); + mSettings = (Map) getArguments().getSerializable(ARG_NEW_GUTENBERG_SETTINGS); + } + if (mIsNewGutenbergEnabled) { mGutenbergView = new GutenbergView(requireContext()); mGutenbergView.setLayoutParams(new ViewGroup.LayoutParams( @@ -286,10 +306,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa initializeSavingProgressDialog(); - if (getArguments() != null) { - mIsNewPost = getArguments().getBoolean(ARG_IS_NEW_POST); - } - ViewGroup gutenbergContainer = view.findViewById(R.id.gutenberg_container); getGutenbergContainerFragment().attachToContainer(gutenbergContainer, new OnMediaLibraryButtonListener() { @@ -1590,6 +1606,9 @@ public void onGutenbergDialogNegativeClicked(@NonNull String instanceTag) { @Override public void onConnectionStatusChange(boolean isConnected) { + if (mIsNewGutenbergEnabled) { + return; + } getGutenbergContainerFragment().onConnectionStatusChange(isConnected); if (isConnected && hasFailedMediaUploads()) { mEditorFragmentListener.onMediaRetryAll(mFailedMediaIds); From 483f9aa9fc65b0c554e4db92dba7584d19a72210 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 20 Sep 2024 18:19:58 +0200 Subject: [PATCH 13/30] Disable appending media for the new editor until is supported --- .../android/editor/gutenberg/GutenbergEditorFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 128151a7bd15..9f94cddf771f 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -1383,7 +1383,8 @@ public void appendMediaFile(final MediaFile mediaFile, final String mediaUrl, Im @Override public void appendMediaFiles(Map mediaList) { - if (getActivity() == null) { + // Disabling media sharing with the new editor until support is added. + if (getActivity() == null || mIsNewGutenbergEnabled) { // appendMediaFile may be called from a background thread (example: EditPostActivity.java#L2165) and // Activity may have already be gone. // Ticket: https://github.com/wordpress-mobile/WordPress-Android/issues/7386 From 013c6c9ebb03bf8a837a67af583d24662a7ecdc3 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 20 Sep 2024 18:20:09 +0200 Subject: [PATCH 14/30] Update Gutenberg ref --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 96a245d97e90..f675b6c5f5b8 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-2b36ffb00beb38fbd6c5b5d77d9e31ab25c09b82' + gutenbergKitVersion = '23-160254e86cf227decf31693c1dc608ca1ea70082' // main androidInstallReferrerVersion = '2.2' From a8b2e1e2f2ba938cc22a3a68bdd535c46ae30284 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 20 Sep 2024 18:23:02 +0200 Subject: [PATCH 15/30] Disable themeStyles --- .../android/editor/gutenberg/GutenbergEditorFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 9f94cddf771f..ac9d2688bb94 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -293,7 +293,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa (String) mSettings.get("siteApiRoot"), (String) mSettings.get("siteApiNamespace"), (String) mSettings.get("authHeader"), - true, // Set as a FeatureFlag + false, // Set as a FeatureFlag postId, (String) mSettings.get("postType"), (String) mSettings.get("postTitle"), From 7d7f7431761c951b8e87d94abb5a0a0b9150ecbc Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 20 Sep 2024 20:25:25 +0200 Subject: [PATCH 16/30] Try peloading GutenbergKit --- WordPress/build.gradle | 1 + .../java/org/wordpress/android/ui/posts/EditPostActivity.kt | 4 ++++ build.gradle | 2 +- .../android/editor/gutenberg/GutenbergEditorFragment.java | 4 +++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 382e3b293e08..6a1de6b6db80 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -437,6 +437,7 @@ dependencies { strictly automatticTracksVersion } } + implementation "org.wordpress.gutenbergkit:android:$gutenbergKitVersion" implementation ("com.automattic:rest:$automatticRestVersion") { exclude group: 'com.mcxiaoke.volley' diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index 209cb86519d0..66a96493aa03 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -248,6 +248,7 @@ import org.wordpress.android.viewmodel.storage.StorageUtilsViewModel import org.wordpress.android.widgets.AppReviewManager.incrementInteractions import org.wordpress.android.widgets.WPSnackbar.Companion.make import org.wordpress.android.widgets.WPViewPager +import org.wordpress.gutenberg.GutenbergWebViewPool import org.wordpress.aztec.AztecExceptionHandler import org.wordpress.aztec.exceptions.DynamicLayoutGetBlockIndexOutOfBoundsException import org.wordpress.aztec.util.AztecLog @@ -780,6 +781,9 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm } private fun setupEditor() { + if (isNewGutenbergEditor) { + GutenbergWebViewPool.getPreloadedWebView(getContext()) + } // Check whether to show the visual editor // NOTE: Migrate to 'androidx.preference.PreferenceManager' and 'androidx.preference.Preference' diff --git a/build.gradle b/build.gradle index f675b6c5f5b8..d606c26a8d52 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-160254e86cf227decf31693c1dc608ca1ea70082' + gutenbergKitVersion = '23-60ef352a1ff433cc306158df1e926ce30f88861b' // main androidInstallReferrerVersion = '2.2' diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index ac9d2688bb94..1083b5ee276b 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -94,6 +94,7 @@ import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnSetFeaturedImageListener; import org.wordpress.gutenberg.GutenbergView; import org.wordpress.gutenberg.GutenbergView.TitleAndContentCallback; +import org.wordpress.gutenberg.GutenbergWebViewPool; import java.io.Serializable; import java.util.ArrayList; @@ -275,7 +276,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa } if (mIsNewGutenbergEnabled) { - mGutenbergView = new GutenbergView(requireContext()); + mGutenbergView = GutenbergWebViewPool.getPreloadedWebView(requireContext()); mGutenbergView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT @@ -1488,6 +1489,7 @@ private boolean hideSavingProgressDialog() { @Override public void onDestroy() { if (mIsNewGutenbergEnabled && mGutenbergView != null) { + GutenbergWebViewPool.recycleWebView(mGutenbergView); mGutenbergView.destroy(); } hideSavingProgressDialog(); From 8520cad99730d51cf73b6e8edd1f4bc451130b06 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 23 Sep 2024 13:14:02 +0200 Subject: [PATCH 17/30] Hide some menu options and undo/redo buttons for the new editor until this functionality is added --- .../android/ui/posts/EditPostActivity.kt | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index 66a96493aa03..fee5fcbdf0ca 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -1408,11 +1408,11 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm val helpMenuItem = menu.findItem(R.id.menu_editor_help) if (undoItem != null) { undoItem.setEnabled(menuHasUndo) - undoItem.setVisible(!htmlModeMenuStateOn) + undoItem.setVisible(!htmlModeMenuStateOn && !isNewGutenbergEditor) } if (redoItem != null) { redoItem.setEnabled(menuHasRedo) - redoItem.setVisible(!htmlModeMenuStateOn) + redoItem.setVisible(!htmlModeMenuStateOn && !isNewGutenbergEditor) } if (secondaryAction != null && editPostRepository.hasPost()) { secondaryAction.setVisible(showMenuItems && this.secondaryAction.isVisible) @@ -1422,7 +1422,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm if (viewHtmlModeMenuItem != null) { viewHtmlModeMenuItem.setVisible( (((editorFragment is AztecEditorFragment) - || (editorFragment is GutenbergEditorFragment))) && showMenuItems + || (editorFragment is GutenbergEditorFragment))) && !isNewGutenbergEditor && showMenuItems ) viewHtmlModeMenuItem.setTitle( if (htmlModeMenuStateOn) R.string.menu_visual_mode else R.string.menu_html_mode) @@ -1459,16 +1459,20 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm } val contentInfo = menu.findItem(R.id.menu_content_info) (editorFragment as? GutenbergEditorFragment)?.let { gutenbergEditorFragment -> - contentInfo.setOnMenuItemClickListener { _: MenuItem? -> - try { - gutenbergEditorFragment.showContentInfo() - } catch (e: EditorFragmentNotAddedException) { - ToastUtils.showToast( - getContext(), - R.string.toast_content_info_failed - ) + if (isNewGutenbergEditor) { + contentInfo.isVisible = false + } else { + contentInfo.setOnMenuItemClickListener { _: MenuItem? -> + try { + gutenbergEditorFragment.showContentInfo() + } catch (e: EditorFragmentNotAddedException) { + ToastUtils.showToast( + getContext(), + R.string.toast_content_info_failed + ) + } + true } - true } } ?: run { contentInfo.isVisible = false // only show the menu item for Gutenberg @@ -1480,7 +1484,7 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm val showHelpAndSupport = jetpackFeatureRemovalPhaseHelper.shouldShowHelpAndSupportOnEditor() val helpMenuTitle = if (showHelpAndSupport) R.string.help_and_support else R.string.help helpMenuItem.setTitle(helpMenuTitle) - if (editorFragment is GutenbergEditorFragment && showMenuItems) { + if (editorFragment is GutenbergEditorFragment && showMenuItems && !isNewGutenbergEditor) { helpMenuItem.setVisible(true) } else { helpMenuItem.setVisible(false) From 9c1cc505ebc7bb296445e93a55c05651d66dc758 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 23 Sep 2024 18:16:52 +0200 Subject: [PATCH 18/30] Add onContentChangeListener --- .../wordpress/android/ui/posts/EditPostActivity.kt | 13 +++++++++++-- build.gradle | 2 +- .../android/editor/AztecEditorFragment.java | 4 ++++ .../android/editor/EditorFragmentAbstract.java | 2 ++ .../editor/gutenberg/GutenbergEditorFragment.java | 12 ++++++++++-- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index fee5fcbdf0ca..229c45fe46da 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -252,6 +252,7 @@ import org.wordpress.gutenberg.GutenbergWebViewPool import org.wordpress.aztec.AztecExceptionHandler import org.wordpress.aztec.exceptions.DynamicLayoutGetBlockIndexOutOfBoundsException import org.wordpress.aztec.util.AztecLog +import org.wordpress.gutenberg.GutenbergView import java.io.File import java.util.Locale import java.util.regex.Matcher @@ -2461,8 +2462,16 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm PAGE_CONTENT -> { editorFragment = fragment as EditorFragmentAbstract editorFragment?.setImageLoader(imageLoader) - editorFragment?.titleOrContentChanged?.observe(this@EditPostActivity) { _: Editable? -> - storePostViewModel.savePostWithDelay() + if (isNewGutenbergEditor) { + editorFragment?.onEditorContentChanged(object : GutenbergView.ContentChangeListener { + override fun onContentChanged(title: String, content: String) { + storePostViewModel.savePostWithDelay() + } + }) + } else { + editorFragment?.titleOrContentChanged?.observe(this@EditPostActivity) { _: Editable? -> + storePostViewModel.savePostWithDelay() + } } if (editorFragment is EditorMediaUploadListener) { editorMediaUploadListener = editorFragment as EditorMediaUploadListener? diff --git a/build.gradle b/build.gradle index d606c26a8d52..21f41fba6cf3 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-60ef352a1ff433cc306158df1e926ce30f88861b' + gutenbergKitVersion = '23-fb8df6bd8d527ff1fefbaccadfaceb49aae76c08' // main androidInstallReferrerVersion = '2.2' diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java index 064e07287540..175ed24c9c6f 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java @@ -106,6 +106,7 @@ import org.wordpress.aztec.toolbar.IAztecToolbarClickListener; import org.wordpress.aztec.util.AztecLog; import org.wordpress.aztec.watchers.EndOfBufferMarkerAdder; +import org.wordpress.gutenberg.GutenbergView.ContentChangeListener; import org.xml.sax.Attributes; import java.util.ArrayList; @@ -706,6 +707,9 @@ public Pair getTitleAndContent(CharSequence original return new Pair<>(getTitle(), getContent(originalContent)); } + @Override public void onEditorContentChanged(ContentChangeListener listener) { + } + @Override public void onToolbarCollapseButtonClicked() { mEditorFragmentListener.onTrackableEvent(TrackableEvent.ELLIPSIS_COLLAPSE_BUTTON_TAPPED); diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java b/libs/editor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java index 18255e7f90d3..9255b197f0b3 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java @@ -20,6 +20,7 @@ import org.wordpress.android.editor.gutenberg.DialogVisibilityProvider; import org.wordpress.android.util.helpers.MediaFile; import org.wordpress.android.util.helpers.MediaGallery; +import org.wordpress.gutenberg.GutenbergView.ContentChangeListener; import java.util.ArrayList; import java.util.HashMap; @@ -38,6 +39,7 @@ public class EditorFragmentNotAddedException extends Exception { public abstract void showContentInfo() throws EditorFragmentNotAddedException; public abstract Pair getTitleAndContent(CharSequence originalContent) throws EditorFragmentNotAddedException; + public abstract void onEditorContentChanged(ContentChangeListener listener); public abstract LiveData getTitleOrContentChanged(); public abstract void appendMediaFile(MediaFile mediaFile, String imageUrl, ImageLoader imageLoader); public abstract void appendMediaFiles(Map mediaList); diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 1083b5ee276b..80f4b37a7e90 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -94,6 +94,7 @@ import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnSetFeaturedImageListener; import org.wordpress.gutenberg.GutenbergView; import org.wordpress.gutenberg.GutenbergView.TitleAndContentCallback; +import org.wordpress.gutenberg.GutenbergView.ContentChangeListener; import org.wordpress.gutenberg.GutenbergWebViewPool; import java.io.Serializable; @@ -155,6 +156,7 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private Runnable mInvalidateOptionsRunnable; private LiveTextWatcher mTextWatcher = new LiveTextWatcher(); + private ContentChangeListener contentChangeListener = null; // pointer (to the Gutenberg container fragment) that outlives this fragment's Android lifecycle. The retained // fragment can be alive and accessible even before it gets attached to an activity. @@ -281,10 +283,11 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT )); - mGutenbergView.setOnFileChooserRequested((intent, requestCode) -> { + mGutenbergView.setOnFileChooserRequestedListener((intent, requestCode) -> { startActivityForResult(intent, requestCode); return null; }); + mGutenbergView.setContentChangeListener(contentChangeListener); Integer postId = (Integer) mSettings.get("postId"); if (postId != null && postId == 0) { @@ -1277,7 +1280,7 @@ public void onResult(@Nullable String title, @NonNull String content) { result[0] = new Pair<>(title, content); latch.countDown(); } - }); + }, true); try { latch.await(); @@ -1372,6 +1375,10 @@ public void onContentInfoReceived(HashMap contentInfo) { }); } + public void onEditorContentChanged(@NonNull ContentChangeListener listener) { + contentChangeListener = listener; + } + @Override public LiveData getTitleOrContentChanged() { return mTextWatcher.getAfterTextChanged(); @@ -1491,6 +1498,7 @@ public void onDestroy() { if (mIsNewGutenbergEnabled && mGutenbergView != null) { GutenbergWebViewPool.recycleWebView(mGutenbergView); mGutenbergView.destroy(); + contentChangeListener = null; } hideSavingProgressDialog(); super.onDestroy(); From 25e6ca96bf41e318f8896030366d71742026a95e Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 23 Sep 2024 18:32:46 +0200 Subject: [PATCH 19/30] Fix style issue --- .../android/editor/gutenberg/GutenbergEditorFragment.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 80f4b37a7e90..4b466efe60aa 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -156,7 +156,7 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private Runnable mInvalidateOptionsRunnable; private LiveTextWatcher mTextWatcher = new LiveTextWatcher(); - private ContentChangeListener contentChangeListener = null; + private ContentChangeListener mContentChangeListener = null; // pointer (to the Gutenberg container fragment) that outlives this fragment's Android lifecycle. The retained // fragment can be alive and accessible even before it gets attached to an activity. @@ -287,7 +287,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa startActivityForResult(intent, requestCode); return null; }); - mGutenbergView.setContentChangeListener(contentChangeListener); + mGutenbergView.setContentChangeListener(mContentChangeListener); Integer postId = (Integer) mSettings.get("postId"); if (postId != null && postId == 0) { @@ -1376,7 +1376,7 @@ public void onContentInfoReceived(HashMap contentInfo) { } public void onEditorContentChanged(@NonNull ContentChangeListener listener) { - contentChangeListener = listener; + mContentChangeListener = listener; } @Override From 78a9a360c4567ad93b2b871c4ee4f92a7369a40e Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 23 Sep 2024 18:39:59 +0200 Subject: [PATCH 20/30] fix name --- .../android/editor/gutenberg/GutenbergEditorFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 4b466efe60aa..86bf1a513c78 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -1498,7 +1498,7 @@ public void onDestroy() { if (mIsNewGutenbergEnabled && mGutenbergView != null) { GutenbergWebViewPool.recycleWebView(mGutenbergView); mGutenbergView.destroy(); - contentChangeListener = null; + mContentChangeListener = null; } hideSavingProgressDialog(); super.onDestroy(); From 44407e354892dc8d74e3d0abede275ff9326327c Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 23 Sep 2024 20:52:52 +0200 Subject: [PATCH 21/30] Support setting content after the editor is loaded --- build.gradle | 2 +- .../android/editor/gutenberg/GutenbergEditorFragment.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 21f41fba6cf3..c5311918c2ba 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-fb8df6bd8d527ff1fefbaccadfaceb49aae76c08' + gutenbergKitVersion = '23-b3313a77d8b273b9a40f5fc6dbcd2a6a70d583fd' // main androidInstallReferrerVersion = '2.2' diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 86bf1a513c78..4f0ead3f0a6e 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -288,6 +288,9 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa return null; }); mGutenbergView.setContentChangeListener(mContentChangeListener); + mGutenbergView.setEditorDidBecomeAvailable(view -> { + mEditorFragmentListener.onEditorFragmentContentReady(new ArrayList(), false); + }); Integer postId = (Integer) mSettings.get("postId"); if (postId != null && postId == 0) { @@ -1189,6 +1192,11 @@ public void setContent(CharSequence text) { text = ""; } + if (mIsNewGutenbergEnabled) { + mGutenbergView.setContent((String) text); + return; + } + String postContent = removeVisualEditorProgressTag(text.toString()); getGutenbergContainerFragment().setContent(postContent); } From d1b940def216f11d302830745ac30585bb639b30 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 23 Sep 2024 21:36:40 +0200 Subject: [PATCH 22/30] Update GutenbergKit ref --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c5311918c2ba..1bd20ecd7de1 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-b3313a77d8b273b9a40f5fc6dbcd2a6a70d583fd' + gutenbergKitVersion = '23-de5332d16060f389c9d020fb4490ad5aada1d8fb' // main androidInstallReferrerVersion = '2.2' From c0d2c1eb6b6cea56bd5bf1db80f4fd52d35cc5e7 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 23 Sep 2024 21:47:11 +0200 Subject: [PATCH 23/30] Update GutenbergKit ref --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1bd20ecd7de1..91f7d251a737 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-de5332d16060f389c9d020fb4490ad5aada1d8fb' + gutenbergKitVersion = '23-7f3f9409de9531d7ed8d69e63365dd7dfe9bafcd' // main androidInstallReferrerVersion = '2.2' From 57ed1f5b0dd05583bbe43a1cb3489284cd78019a Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 23 Sep 2024 22:30:30 +0200 Subject: [PATCH 24/30] Fix pages issue --- .../java/org/wordpress/android/ui/posts/EditPostActivity.kt | 3 +++ .../android/editor/gutenberg/GutenbergEditorFragment.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index 229c45fe46da..761d56477fb4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -3568,6 +3568,9 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm } private fun updateVoiceContentIfNeeded() { + if (isNewGutenbergEditor) { + return + } // Check if voice content exists and this is a new post for a Gutenberg editor fragment val content = intent.getStringExtra(EditPostActivityConstants.EXTRA_VOICE_CONTENT) if (isNewPost && content != null && !isVoiceContentSet) { diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 4f0ead3f0a6e..ca3434368d82 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -1589,6 +1589,9 @@ public void onEditorThemeUpdated(Bundle editorTheme) { @Override public void showNotice(String message) { + if (mIsNewGutenbergEnabled) { + return; + } getGutenbergContainerFragment().showNotice(message); } From fa85bbdd421426135d54539fc690f7a8d4789a72 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 1 Oct 2024 19:50:39 +0200 Subject: [PATCH 25/30] Fix syncing issues --- .../org/wordpress/android/ui/posts/EditPostActivity.kt | 8 +++++--- build.gradle | 2 +- .../android/editor/gutenberg/GutenbergEditorFragment.java | 1 - 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt index 761d56477fb4..3c238f596ad7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt @@ -1000,9 +1000,11 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm editorMedia.toastMessage.observe(this) { event: Event -> event.getContentIfNotHandled()?.show(this) } - storePostViewModel.onSavePostTriggered.observe(this) { unitEvent: Event -> - unitEvent.applyIfNotHandled { - updateAndSavePostAsync() + if (!isNewGutenbergEditor) { + storePostViewModel.onSavePostTriggered.observe(this) { unitEvent: Event -> + unitEvent.applyIfNotHandled { + updateAndSavePostAsync() + } } } storePostViewModel.onFinish.observe(this) { finishEvent -> diff --git a/build.gradle b/build.gradle index 91f7d251a737..b9f934aee7f8 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { wordPressUtilsVersion = '3.14.0' indexosMediaForMobileVersion = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' gravatarVersion = '1.0.0' - gutenbergKitVersion = '23-7f3f9409de9531d7ed8d69e63365dd7dfe9bafcd' + gutenbergKitVersion = 'trunk-c31879b834ef3ca5ea6b09040c96093ef627e029' // main androidInstallReferrerVersion = '2.2' diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index ca3434368d82..cee8b6b6ec55 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -1505,7 +1505,6 @@ private boolean hideSavingProgressDialog() { public void onDestroy() { if (mIsNewGutenbergEnabled && mGutenbergView != null) { GutenbergWebViewPool.recycleWebView(mGutenbergView); - mGutenbergView.destroy(); mContentChangeListener = null; } hideSavingProgressDialog(); From ad488784335102c9ee6aec03adbc071d35049d64 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 10 Oct 2024 16:03:13 -0400 Subject: [PATCH 26/30] build: Enable local GutenbergKit development Improve development velocity by building with a local GutenbergKit clone. --- config/gradle/included_builds.gradle | 12 ++++++++++++ local-builds.gradle-example | 1 + 2 files changed, 13 insertions(+) diff --git a/config/gradle/included_builds.gradle b/config/gradle/included_builds.gradle index e7ed11230846..788c0a124016 100644 --- a/config/gradle/included_builds.gradle +++ b/config/gradle/included_builds.gradle @@ -2,6 +2,8 @@ gradle.ext.fluxCBinaryPath = "org.wordpress:fluxc" gradle.ext.wputilsBinaryPath = "org.wordpress:utils" gradle.ext.gutenbergMobileBinaryPath = "org.wordpress.gutenberg-mobile:react-native-gutenberg-bridge" gradle.ext.includedBuildGutenbergMobilePath = null +gradle.ext.gutenbergKitBinaryPath = "org.wordpress.gutenbergkit:android" +gradle.ext.includedBuildGutenbergKitPath = null gradle.ext.loginFlowBinaryPath = "org.wordpress:login" gradle.ext.aztecAndroidAztecPath = "org.wordpress:aztec" gradle.ext.aztecAndroidWordPressShortcodesPath = "org.wordpress.aztec:wordpress-shortcodes" @@ -55,6 +57,16 @@ if (localBuilds.exists()) { } } + if (ext.has("localGutenbergKitPath")) { + gradle.ext.includedBuildGutenbergKitPath = ext.localGutenbergKitPath + includeBuild("$ext.localGutenbergKitPath/Demo-Android") { + dependencySubstitution { + println "Substituting GutenbergKit with the local build" + substitute module("$gradle.ext.gutenbergKitBinaryPath") using project(':Gutenberg') + } + } + } + if (ext.has("localLoginFlowPath")) { includeBuild(ext.localLoginFlowPath) { dependencySubstitution { diff --git a/local-builds.gradle-example b/local-builds.gradle-example index 1a144af244bb..0b1f46133178 100644 --- a/local-builds.gradle-example +++ b/local-builds.gradle-example @@ -18,6 +18,7 @@ ext { //localFluxCPath = "../WordPress-FluxC-Android" //localWPUtilsPath = "../WordPress-Utils-Android" //localGutenbergMobilePath = "../gutenberg-mobile" + //localGutenbergKitPath = "../GutenbergKit" //localLoginFlowPath = "../WordPress-Login-Flow-Android" //localAztecAndroidPath = "../AztecEditor-Android" //localTracksPath = "../Automattic-Tracks-Android" From d99e7e00ecf392b5869e57a3b57d634d0aad459b Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Fri, 11 Oct 2024 09:34:33 -0400 Subject: [PATCH 27/30] refactor: Address null value lint warnings --- .../org/wordpress/android/editor/AztecEditorFragment.java | 2 +- .../android/editor/gutenberg/GutenbergEditorFragment.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java index 175ed24c9c6f..2457a3e82dc2 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java @@ -707,7 +707,7 @@ public Pair getTitleAndContent(CharSequence original return new Pair<>(getTitle(), getContent(originalContent)); } - @Override public void onEditorContentChanged(ContentChangeListener listener) { + @Override public void onEditorContentChanged(@Nullable ContentChangeListener listener) { } @Override diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index cee8b6b6ec55..982836e126e3 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -118,7 +118,7 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements GutenbergDialogPositiveClickInterface, GutenbergDialogNegativeClickInterface, GutenbergNetworkConnectionListener { - private GutenbergView mGutenbergView; + @Nullable private GutenbergView mGutenbergView; private static final String GUTENBERG_EDITOR_NAME = "gutenberg"; private static final String KEY_HTML_MODE_ENABLED = "KEY_HTML_MODE_ENABLED"; private static final String KEY_EDITOR_DID_MOUNT = "KEY_EDITOR_DID_MOUNT"; @@ -156,7 +156,7 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private Runnable mInvalidateOptionsRunnable; private LiveTextWatcher mTextWatcher = new LiveTextWatcher(); - private ContentChangeListener mContentChangeListener = null; + @Nullable private ContentChangeListener mContentChangeListener = null; // pointer (to the Gutenberg container fragment) that outlives this fragment's Android lifecycle. The retained // fragment can be alive and accessible even before it gets attached to an activity. @@ -180,7 +180,7 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private String mUpdatedStoryBlockContent = null; private ProgressDialog mSavingContentProgressDialog; - private static Map mSettings; + @Nullable private static Map mSettings; public static GutenbergEditorFragment newInstance(Context context, boolean isNewPost, @@ -188,7 +188,7 @@ public static GutenbergEditorFragment newInstance(Context context, GutenbergPropsBuilder gutenbergPropsBuilder, boolean jetpackFeaturesEnabled, boolean newGutenbergEnabled, - Map settings) { + @Nullable Map settings) { GutenbergEditorFragment fragment = new GutenbergEditorFragment(); Bundle args = new Bundle(); args.putBoolean(ARG_IS_NEW_POST, isNewPost); From e216b84cfb47374cef0d34c5803ede7bed34f44f Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Mon, 14 Oct 2024 16:49:39 -0400 Subject: [PATCH 28/30] build: Update GutenbergKit ref --- 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 bf6cea14da28..5453e110aec8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -65,7 +65,7 @@ google-play-services-auth = '20.4.1' google-services = '4.4.2' gravatar = '1.0.0' greenrobot-eventbus = '3.3.1' -gutenberg-kit = 'trunk-c31879b834ef3ca5ea6b09040c96093ef627e029' +gutenberg-kit = '29-636dd62534014df2f30ee25b4bfdf0bc398e2951' gutenberg-mobile = 'v1.121.0' indexos-media-for-mobile = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' jackson-databind = '2.12.7.1' From dc27142dd2be0b72521fceb134da2d32812fc5aa Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Mon, 14 Oct 2024 21:15:18 -0400 Subject: [PATCH 29/30] build: Update GutenbergKit ref --- 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 5453e110aec8..54d845d0068e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -65,7 +65,7 @@ google-play-services-auth = '20.4.1' google-services = '4.4.2' gravatar = '1.0.0' greenrobot-eventbus = '3.3.1' -gutenberg-kit = '29-636dd62534014df2f30ee25b4bfdf0bc398e2951' +gutenberg-kit = '29-dcb77f243798ab416d05878179e1f9afe03f6e81' gutenberg-mobile = 'v1.121.0' indexos-media-for-mobile = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' jackson-databind = '2.12.7.1' From 8e5333d9291e759285d639e09d498dccb1ad9925 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 17 Oct 2024 14:25:10 -0400 Subject: [PATCH 30/30] build: Update GutenbergKit ref --- 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 54d845d0068e..5e8a75e13a5f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -65,7 +65,7 @@ google-play-services-auth = '20.4.1' google-services = '4.4.2' gravatar = '1.0.0' greenrobot-eventbus = '3.3.1' -gutenberg-kit = '29-dcb77f243798ab416d05878179e1f9afe03f6e81' +gutenberg-kit = 'trunk-a58a46f3fbb892f311b562e3c122d7ef4ebbfe33' gutenberg-mobile = 'v1.121.0' indexos-media-for-mobile = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' jackson-databind = '2.12.7.1'