Skip to content

Commit d3b914b

Browse files
authored
feat: Enable GutenbergKit asset caching (#22035)
* refactor: Remove redundant private Atomic site check Using `isWPComAtomic` suffices for the need of identifying sites managed by WPCOM. * feat: Cache GutenbergKit assets and improve configuration * fix: Disable WebView preloading causing GutenbergKit load failures The current preloading strategy results in the editor loading twice. The duplicative load results in hidden editor UI for the second load, as the loading sequence is not idempotent currently. We should refactor to ensure the editor UI is only displayed once after the editor fully loads. Currently, The first occurs without blog configuration and always loads the bundled editor. We should ensure preload loads with the proper configuration and the correct editor (bundled/remote). * fix: Avoid unnecessary GutenbergKit starts The editor relies upon a subscription to editor settings within the FluxC store. FluxC can dispatch change events multiple times, leading to unexpected, unnecessary invocations of GutenbergKit's `start` method. This lead to odd outcomes. First, during editor setup, we dispatch an event to request the latest editor settings. FluxC broadcasts two change events: first with the cached settings, and second when the fetched settings resolve. This caused two `start` invocations when opening the editor. Second, the My Site fragment requests the latest settings as a performance optimization. When closing the editor and returning to My Site, the request resulted in a broadcast of updated settings, which attempt to start the editor while it was closing. * build: Update GutenbergKit version * refactor: Address lint errors * build: Update GutenbergKit version
1 parent 509b715 commit d3b914b

File tree

3 files changed

+47
-22
lines changed

3 files changed

+47
-22
lines changed

WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.kt

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ import org.wordpress.android.viewmodel.storage.StorageUtilsViewModel
258258
import org.wordpress.android.widgets.AppReviewManager.incrementInteractions
259259
import org.wordpress.android.widgets.WPSnackbar.Companion.make
260260
import org.wordpress.android.widgets.WPViewPager
261-
import org.wordpress.gutenberg.GutenbergWebViewPool
262261
import org.wordpress.aztec.AztecExceptionHandler
263262
import org.wordpress.aztec.exceptions.DynamicLayoutGetBlockIndexOutOfBoundsException
264263
import org.wordpress.aztec.util.AztecLog
@@ -798,9 +797,6 @@ class EditPostActivity : BaseAppCompatActivity(), EditorFragmentActivity, Editor
798797
}
799798

800799
private fun setupEditor() {
801-
if (isGutenbergKitEditor) {
802-
GutenbergWebViewPool.getPreloadedWebView(this)
803-
}
804800
// Check whether to show the visual editor
805801

806802
// NOTE: Migrate to 'androidx.preference.PreferenceManager' and 'androidx.preference.Preference'
@@ -2503,8 +2499,21 @@ class EditPostActivity : BaseAppCompatActivity(), EditorFragmentActivity, Editor
25032499
onXpostsSettingsCapability(isXpostsCapable)
25042500
}
25052501

2506-
val isWpCom = site.isWPCom || siteModel.isPrivateWPComAtomic || siteModel.isWPComAtomic
2507-
val gutenbergWebViewAuthorizationData = GutenbergWebViewAuthorizationData(
2502+
val isWpCom = site.isWPCom || siteModel.isWPComAtomic
2503+
val gutenbergWebViewAuthorizationData = createGutenbergWebViewAuthorizationData(isWpCom)
2504+
val settings = createGutenbergKitSettings(isWpCom)
2505+
2506+
return GutenbergKitEditorFragment.newInstance(
2507+
getContext(),
2508+
isNewPost,
2509+
gutenbergWebViewAuthorizationData,
2510+
jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(),
2511+
settings
2512+
)
2513+
}
2514+
2515+
private fun createGutenbergWebViewAuthorizationData(isWpCom: Boolean): GutenbergWebViewAuthorizationData {
2516+
return GutenbergWebViewAuthorizationData(
25082517
siteModel.url,
25092518
isWpCom,
25102519
accountStore.account.userId,
@@ -2518,21 +2527,28 @@ class EditPostActivity : BaseAppCompatActivity(), EditorFragmentActivity, Editor
25182527
userAgent.toString(),
25192528
isJetpackSsoEnabled
25202529
)
2530+
}
25212531

2532+
private fun createGutenbergKitSettings(isWpCom: Boolean): MutableMap<String, Any?> {
25222533
val postType = if (editPostRepository.isPage) "page" else "post"
2523-
val siteApiRoot = if (isWpCom) "https://public-api.wordpress.com/" else ""
2524-
val authToken = accountStore.accessToken
2525-
val authHeader = "Bearer $authToken"
2526-
val siteApiNamespace = arrayOf("sites/${site.siteId}", "sites/${UrlUtils.removeScheme(siteModel.url)}")
2534+
val siteURL = siteModel.url
2535+
val siteApiRoot = if (isWpCom) "https://public-api.wordpress.com/"
2536+
else siteModel.wpApiRestUrl ?: "$siteURL/wp-json/"
2537+
// Use the application password for self-hosted sites when available
2538+
val authHeader = if (isWpCom) "Bearer ${accountStore.accessToken}" else "Basic "
2539+
val siteApiNamespace = if (isWpCom)
2540+
arrayOf("sites/${site.siteId}/", "sites/${UrlUtils.removeScheme(siteURL)}/")
2541+
else arrayOf()
25272542

25282543
val languageString = perAppLocaleManager.getCurrentLocaleLanguageCode()
25292544
val wpcomLocaleSlug = languageString.replace("_", "-").lowercase()
25302545

2531-
val settings = mutableMapOf<String, Any?>(
2546+
return mutableMapOf(
25322547
"postId" to editPostRepository.getPost()?.remotePostId?.toInt(),
25332548
"postType" to postType,
25342549
"postTitle" to editPostRepository.getPost()?.title,
25352550
"postContent" to editPostRepository.getPost()?.content,
2551+
"siteURL" to siteURL,
25362552
"siteApiRoot" to siteApiRoot,
25372553
"namespaceExcludedPaths" to arrayOf("/wpcom/v2/following/recommendations", "/wpcom/v2/following/mine"),
25382554
"authHeader" to authHeader,
@@ -2552,14 +2568,6 @@ class EditPostActivity : BaseAppCompatActivity(), EditorFragmentActivity, Editor
25522568
)
25532569
)
25542570
)
2555-
2556-
return GutenbergKitEditorFragment.newInstance(
2557-
getContext(),
2558-
isNewPost,
2559-
gutenbergWebViewAuthorizationData,
2560-
jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(),
2561-
settings
2562-
)
25632571
}
25642572

25652573
private fun createGutenbergEditorFragment(): GutenbergEditorFragment {

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ google-play-services-auth = '20.4.1'
7272
google-services = '4.4.3'
7373
gravatar = '2.5.0'
7474
greenrobot-eventbus = '3.3.1'
75-
gutenberg-kit = 'v0.4.1'
75+
gutenberg-kit = 'v0.5.0'
7676
gutenberg-mobile = 'v1.121.0'
7777
indexos-media-for-mobile = '43a9026f0973a2f0a74fa813132f6a16f7499c3a'
7878
jackson-databind = '2.12.7.1'

libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergKitEditorFragment.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.wordpress.android.util.AppLog.T;
4242
import org.wordpress.android.util.PermissionUtils;
4343
import org.wordpress.android.util.ProfilingUtils;
44+
import org.wordpress.android.util.UrlUtils;
4445
import org.wordpress.android.util.helpers.MediaFile;
4546
import org.wordpress.android.util.helpers.MediaGallery;
4647
import org.wordpress.aztec.IHistoryListener;
@@ -58,6 +59,7 @@
5859
import java.util.ArrayList;
5960
import java.util.List;
6061
import java.util.Map;
62+
import java.util.Set;
6163
import java.util.concurrent.CountDownLatch;
6264

6365
import static org.wordpress.gutenberg.Media.createMediaUsingMimeType;
@@ -72,6 +74,7 @@ public class GutenbergKitEditorFragment extends EditorFragmentAbstract implement
7274
@Nullable private GutenbergView mGutenbergView;
7375
private static final String GUTENBERG_EDITOR_NAME = "gutenberg";
7476
private static final String KEY_HTML_MODE_ENABLED = "KEY_HTML_MODE_ENABLED";
77+
private static final String KEY_EDITOR_STARTED = "KEY_EDITOR_STARTED";
7578
private static final String KEY_EDITOR_DID_MOUNT = "KEY_EDITOR_DID_MOUNT";
7679
private static final String ARG_IS_NEW_POST = "param_is_new_post";
7780
private static final String ARG_GUTENBERG_WEB_VIEW_AUTH_DATA = "param_gutenberg_web_view_auth_data";
@@ -90,6 +93,7 @@ public class GutenbergKitEditorFragment extends EditorFragmentAbstract implement
9093
@Nullable private OpenMediaLibraryListener mOpenMediaLibraryListener = null;
9194
@Nullable private LogJsExceptionListener mOnLogJsExceptionListener = null;
9295

96+
private boolean mEditorStarted;
9397
private boolean mEditorDidMount;
9498
@Nullable
9599
private View mRootView;
@@ -124,6 +128,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
124128

125129
if (savedInstanceState != null) {
126130
mHtmlModeEnabled = savedInstanceState.getBoolean(KEY_HTML_MODE_ENABLED);
131+
mEditorStarted = savedInstanceState.getBoolean(KEY_EDITOR_STARTED);
127132
mEditorDidMount = savedInstanceState.getBoolean(KEY_EDITOR_DID_MOUNT);
128133
mFeaturedImageId = savedInstanceState.getLong(ARG_FEATURED_IMAGE_ID);
129134
}
@@ -260,6 +265,7 @@ public void onAttach(Activity activity) {
260265
@Override
261266
public void onSaveInstanceState(Bundle outState) {
262267
outState.putBoolean(KEY_HTML_MODE_ENABLED, mHtmlModeEnabled);
268+
outState.putBoolean(KEY_EDITOR_STARTED, mEditorStarted);
263269
outState.putBoolean(KEY_EDITOR_DID_MOUNT, mEditorDidMount);
264270
outState.putLong(ARG_FEATURED_IMAGE_ID, mFeaturedImageId);
265271
}
@@ -508,6 +514,7 @@ public void onDestroy() {
508514
mHistoryChangeListener = null;
509515
mFeaturedImageChangeListener = null;
510516
}
517+
mEditorStarted = false;
511518
super.onDestroy();
512519
}
513520

@@ -556,7 +563,7 @@ public void onEditorThemeUpdated(Bundle editorTheme) {
556563
}
557564

558565
public void startWithEditorSettings(@NonNull String editorSettings) {
559-
if (mGutenbergView == null) {
566+
if (mGutenbergView == null || mEditorStarted) {
560567
return;
561568
}
562569

@@ -565,6 +572,12 @@ public void startWithEditorSettings(@NonNull String editorSettings) {
565572
postId = -1;
566573
}
567574

575+
var siteURL = (String) mSettings.get("siteURL");
576+
var siteApiRoot = (String) mSettings.get("siteApiRoot");
577+
var siteApiNamespace = (String[]) mSettings.get("siteApiNamespace");
578+
var firstNamespace = siteApiNamespace != null && siteApiNamespace.length > 0 ? siteApiNamespace[0] : "";
579+
var editorAssetsEndpoint = siteApiRoot + "wpcom/v2/" + firstNamespace + "editor-assets";
580+
568581
EditorConfiguration config = new EditorConfiguration.Builder()
569582
.setTitle((String) mSettings.get("postTitle"))
570583
.setContent((String) mSettings.get("postContent"))
@@ -573,14 +586,18 @@ public void startWithEditorSettings(@NonNull String editorSettings) {
573586
.setThemeStyles((Boolean) mSettings.get("themeStyles"))
574587
.setPlugins((Boolean) mSettings.get("plugins"))
575588
.setSiteApiRoot((String) mSettings.get("siteApiRoot"))
576-
.setSiteApiNamespace((String[]) mSettings.get("siteApiNamespace"))
589+
.setSiteApiNamespace((String[]) siteApiNamespace)
577590
.setNamespaceExcludedPaths((String[]) mSettings.get("namespaceExcludedPaths"))
578591
.setAuthHeader((String) mSettings.get("authHeader"))
579592
.setWebViewGlobals((List<WebViewGlobal>) mSettings.get("webViewGlobals"))
580593
.setEditorSettings(editorSettings)
581594
.setLocale((String) mSettings.get("locale"))
595+
.setEditorAssetsEndpoint(editorAssetsEndpoint)
596+
.setCachedAssetHosts(Set.of("s0.wp.com", UrlUtils.getHost(siteURL)))
597+
.setEnableAssetCaching(true)
582598
.build();
583599

600+
mEditorStarted = true;
584601
mGutenbergView.start(config);
585602
}
586603

0 commit comments

Comments
 (0)