From 09e5079c01fdb404ca8448448ceabee53b27db5e Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Fri, 16 Jan 2026 17:01:42 -0500 Subject: [PATCH 1/6] feat: Send GutenbergKit the latest content when requested Allow GutenbergKit to retrieve the latest content persisted in the host app as needed. This is important for allowing GutenbergKit to display the latest content after the WebView reloads or re-initializes from memory pressure or backgrounding. --- .../android/ui/posts/GutenbergKitActivity.kt | 4 ++++ .../ui/posts/editor/GutenbergKitEditorFragment.kt | 10 ++++++++++ .../posts/editor/GutenbergKitEditorFragmentBase.java | 12 ++++++++++++ 3 files changed, 26 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitActivity.kt index 1ebf3fb74dd4..705b2fe05350 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitActivity.kt @@ -2955,6 +2955,10 @@ class GutenbergKitActivity : BaseAppCompatActivity(), EditorImageSettingsListene Handler(Looper.getMainLooper()).post { invalidateOptionsMenu() } } + override fun getPersistedTitle(): String = editPostRepository.title + + override fun getPersistedContent(): String = editPostRepository.content + // FluxC events @Suppress("unused", "CyclomaticComplexMethod") @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragment.kt index eb865c9803ab..6c4ebcd3f681 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragment.kt @@ -180,6 +180,16 @@ class GutenbergKitEditorFragment : GutenbergKitEditorFragmentBase() { modalDialogStateListener?.let(gutenbergView::setModalDialogStateListener) networkRequestListener?.let(gutenbergView::setNetworkRequestListener) + // Set up content provider for WebView refresh recovery + gutenbergView.setLatestContentProvider(object : GutenbergView.LatestContentProvider { + override fun getLatestContent(): GutenbergView.LatestContent { + return GutenbergView.LatestContent( + mEditorFragmentListener.persistedTitle, + mEditorFragmentListener.persistedContent + ) + } + }) + // Set up autocomplete listener for user mentions and cross-post suggestions gutenbergView.setAutocompleterTriggeredListener(object : GutenbergView.AutocompleterTriggeredListener { override fun onAutocompleterTriggered(type: String) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragmentBase.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragmentBase.java index 1aa193d65885..2f7520dbb76b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragmentBase.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragmentBase.java @@ -151,5 +151,17 @@ public interface EditorFragmentListener extends DialogVisibilityProvider { void onOpenMediaLibraryRequested(org.wordpress.gutenberg.GutenbergView.OpenMediaLibraryConfig config); void onModalDialogOpened(String dialogType); void onModalDialogClosed(String dialogType); + + /** + * Returns the persisted post title for content recovery after WebView refresh. + * @return The most recently persisted title from autosave. + */ + String getPersistedTitle(); + + /** + * Returns the persisted post content for content recovery after WebView refresh. + * @return The most recently persisted content from autosave. + */ + String getPersistedContent(); } } From dc0136a435f14e0ac379cdccb37cda2525a2707f Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Fri, 16 Jan 2026 17:25:11 -0500 Subject: [PATCH 2/6] build: Update GutenbergKit version --- 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 47f08f347f21..bf3ec912a576 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -74,7 +74,7 @@ google-play-services-auth = '20.4.1' google-services = '4.4.4' gravatar = '2.5.0' greenrobot-eventbus = '3.3.1' -gutenberg-kit = 'v0.11.1' +gutenberg-kit = '283-71df4ab18c674781c512a890afac2cf562ea6e75' gutenberg-mobile = 'v1.121.0' indexos-media-for-mobile = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' jackson-databind = '2.12.7.1' From 4fdd5922ea9ef37eb81647d7bb1afc24bd83a9f5 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Tue, 20 Jan 2026 13:41:13 -0500 Subject: [PATCH 3/6] build: Update GutenbergKit version --- 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 bf3ec912a576..6e95f43e3a0d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -74,7 +74,7 @@ google-play-services-auth = '20.4.1' google-services = '4.4.4' gravatar = '2.5.0' greenrobot-eventbus = '3.3.1' -gutenberg-kit = '283-71df4ab18c674781c512a890afac2cf562ea6e75' +gutenberg-kit = '283-e8dd9ff292a949fad9fe696379d5ee5d0355724e' gutenberg-mobile = 'v1.121.0' indexos-media-for-mobile = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' jackson-databind = '2.12.7.1' From 72af70ffc543cefdf63fd80de32b9ff5745c42d1 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Wed, 21 Jan 2026 11:33:26 -0500 Subject: [PATCH 4/6] feat: Set GutenbergKit post status --- .../ui/posts/EditorConfigurationBuilder.kt | 1 + .../ui/posts/GutenbergKitSettingsBuilder.kt | 7 ++-- .../posts/GutenbergKitSettingsBuilderTest.kt | 36 ++++++++++++++++--- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditorConfigurationBuilder.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditorConfigurationBuilder.kt index a1bea3d546b0..af04ef6c99b2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditorConfigurationBuilder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditorConfigurationBuilder.kt @@ -29,6 +29,7 @@ object EditorConfigurationBuilder { setContent(settings.getSetting("postContent") ?: "") setPostId(postId) setPostType(settings.getSetting("postType")) + setStatus(settings.getSetting("status")) // Site settings setSiteURL(siteURL) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilder.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilder.kt index 8e43e1eb2891..c268fff930e7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilder.kt @@ -54,7 +54,8 @@ object GutenbergKitSettingsBuilder { val remotePostId: Long?, val isPage: Boolean, val title: String?, - val content: String? + val content: String?, + val status: String? ) { companion object { fun fromPostModel(postModel: PostImmutableModel?): PostConfig { @@ -62,7 +63,8 @@ object GutenbergKitSettingsBuilder { remotePostId = postModel?.remotePostId, isPage = postModel?.isPage ?: false, title = postModel?.title, - content = postModel?.content + content = postModel?.content, + status = postModel?.status ) } } @@ -127,6 +129,7 @@ object GutenbergKitSettingsBuilder { return mutableMapOf( "postId" to postConfig.remotePostId?.toInt(), "postType" to if (postConfig.isPage) "page" else "post", + "status" to postConfig.status, "postTitle" to postConfig.title, "postContent" to postConfig.content, "siteURL" to siteConfig.url, diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilderTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilderTest.kt index 3f63e25fcfa3..05217a8e858e 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilderTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilderTest.kt @@ -409,7 +409,8 @@ class GutenbergKitSettingsBuilderTest { remotePostId = 456L, isPage = false, title = "Test Post", - content = "Test Content" + content = "Test Content", + status = "publish" ) val settings = GutenbergKitSettingsBuilder.buildSettings( @@ -461,7 +462,8 @@ class GutenbergKitSettingsBuilderTest { remotePostId = 100L, isPage = true, title = "Test Page", - content = "Page Content" + content = "Page Content", + status = "draft" ) val settings = GutenbergKitSettingsBuilder.buildSettings( @@ -579,7 +581,8 @@ class GutenbergKitSettingsBuilderTest { remotePostId = null, isPage = false, title = null, - content = null + content = null, + status = null ) val settings = GutenbergKitSettingsBuilder.buildSettings( @@ -594,9 +597,30 @@ class GutenbergKitSettingsBuilderTest { assertThat(settings["postId"]).isNull() assertThat(settings["postTitle"]).isNull() assertThat(settings["postContent"]).isNull() + assertThat(settings["status"]).isNull() assertThat(settings["postType"]).isEqualTo("post") // Still defaults to post } + @Test + fun `post status is included in settings`() { + val testCases = listOf("draft", "publish", "pending", "private", "future", "trash") + + testCases.forEach { status -> + val postConfig = createPostConfig(status = status) + + val settings = GutenbergKitSettingsBuilder.buildSettings( + siteConfig = createSiteConfig(), + postConfig = postConfig, + appConfig = createAppConfig(), + featureConfig = createFeatureConfig() + ) + + assertThat(settings["status"]) + .withFailMessage("Expected status=$status in settings") + .isEqualTo(status) + } + } + // ===== Helper Methods ===== private fun createFeatureConfig( @@ -651,11 +675,13 @@ class GutenbergKitSettingsBuilderTest { remotePostId: Long? = 1L, isPage: Boolean = false, title: String? = "Test", - content: String? = "Content" + content: String? = "Content", + status: String? = "draft" ) = GutenbergKitSettingsBuilder.PostConfig( remotePostId = remotePostId, isPage = isPage, title = title, - content = content + content = content, + status = status ) } From 07fee63c3c90d7831bb5731d91cb4243598fd152 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Wed, 21 Jan 2026 11:46:59 -0500 Subject: [PATCH 5/6] build: Update GutenbergKit version --- 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 6e95f43e3a0d..ef13cdb52db7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -74,7 +74,7 @@ google-play-services-auth = '20.4.1' google-services = '4.4.4' gravatar = '2.5.0' greenrobot-eventbus = '3.3.1' -gutenberg-kit = '283-e8dd9ff292a949fad9fe696379d5ee5d0355724e' +gutenberg-kit = '283-3110b008df0edceac04a1c6f18724476ce67b3ce' gutenberg-mobile = 'v1.121.0' indexos-media-for-mobile = '43a9026f0973a2f0a74fa813132f6a16f7499c3a' jackson-databind = '2.12.7.1' From 41768bd344e2e43746f8b60c354176a181c1108a Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Wed, 21 Jan 2026 12:25:59 -0500 Subject: [PATCH 6/6] fix: Add missing post status GutenbergKit configuration --- .../org/wordpress/android/ui/posts/GutenbergKitWarmupHelper.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitWarmupHelper.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitWarmupHelper.kt index f84f326fb1f7..90c7c553c4a2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitWarmupHelper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitWarmupHelper.kt @@ -123,7 +123,8 @@ class GutenbergKitWarmupHelper @Inject constructor( remotePostId = null, isPage = false, title = "", - content = "" + content = "", + status = "draft" ) val appConfig = GutenbergKitSettingsBuilder.AppConfig(