From bf40053838a2bf61a774af33ebda6da09dad92ba 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 81f8f74852bd127dffaf76cf057e751750788239 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 ee85122aed3e..0d28295bedfd 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 3a38e04277a1bd8c482a0237b6e17d95a99cd766 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 0d28295bedfd..d1c38ab86673 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 16c0105eaac1c9349a6610d9384038e8f736f8f1 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 ceebe72d8d8f755181f5ad59993c674e90e30652 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 d1c38ab86673..8461c3979f13 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 5b4967c138dd34bf521367a4a14fed41fee152a7 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(