From c6f9ceca7e76a2b729f9c8d397183ea00f30d64d Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Wed, 3 Apr 2019 09:49:22 +0200 Subject: [PATCH 1/6] Listen on fontSize changes in EditPostActivity and restart RN context in case of changes --- WordPress/src/main/AndroidManifest.xml | 1 + .../android/ui/posts/EditPostActivity.java | 14 ++++++++++++++ .../android/editor/GutenbergContainerFragment.java | 4 ++++ .../android/editor/GutenbergEditorFragment.java | 4 ++++ 4 files changed, 23 insertions(+) diff --git a/WordPress/src/main/AndroidManifest.xml b/WordPress/src/main/AndroidManifest.xml index 1d9499c1dc32..ec7a77db9191 100644 --- a/WordPress/src/main/AndroidManifest.xml +++ b/WordPress/src/main/AndroidManifest.xml @@ -205,6 +205,7 @@ android:windowSoftInputMode="stateVisible" /> mDroppedMediaUris; + private float mConfigurationFontSize; + private boolean isModernEditor() { return mShowNewEditor || mShowAztecEditor || mShowGutenbergEditor; } @@ -587,6 +589,8 @@ public void run() { } }); + mConfigurationFontSize = getResources().getConfiguration().fontScale; + ActivityId.trackLastActivity(ActivityId.POST_EDITOR); } @@ -801,6 +805,7 @@ protected void onSaveInstanceState(Bundle outState) { outState.putBoolean(STATE_KEY_HTML_MODE_ON, mHtmlModeMenuStateOn); outState.putSerializable(WordPress.SITE, mSite); outState.putParcelable(STATE_KEY_REVISION, mRevision); + outState.putFloat("mConfigurationFontSize", mConfigurationFontSize); outState.putSerializable(STATE_KEY_EDITOR_SESSION_DATA, mPostEditorAnalyticsSession); mIsConfigChange = true; // don't call sessionData.end() in onDestroy() if this is an Android config change @@ -822,12 +827,21 @@ protected void onRestoreInstanceState(Bundle savedInstanceState) { if (savedInstanceState.getBoolean(STATE_KEY_IS_PHOTO_PICKER_VISIBLE, false)) { showPhotoPicker(); } + + mConfigurationFontSize = savedInstanceState.getFloat("mConfigurationFontSize", 0f); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); + + if (newConfig.fontScale != mConfigurationFontSize && (mEditorFragment instanceof GutenbergEditorFragment)) { + GutenbergEditorFragment gbFragment = (GutenbergEditorFragment) mEditorFragment; + mConfigurationFontSize = newConfig.fontScale; + gbFragment.recreateReactContextInBackground(); + } + // resize the photo picker if the user rotated the device int orientation = newConfig.orientation; if (orientation != mPhotoPickerOrientation) { diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java index a382fe54c0d7..589a4ce008f1 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java @@ -145,4 +145,8 @@ public void mediaFileUploadSucceeded(final int mediaId, final String mediaUrl, f public void clearMediaFileURL(final int mediaId) { mWPAndroidGlueCode.clearMediaFileURL(mediaId); } + + public void recreateReactContextInBackground() { + mWPAndroidGlueCode.recreateReactContextInBackground(); + } } diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java index 91f9ef8380df..3b4079998a89 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java @@ -774,4 +774,8 @@ public void run() { return true; } + + public void recreateReactContextInBackground() { + mRetainedGutenbergContainerFragment.recreateReactContextInBackground(); + } } From d8d7f9e69c89c363fc36fa993789adc2fdef0fbb Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Wed, 3 Apr 2019 11:57:50 +0200 Subject: [PATCH 2/6] Restore Title and Content after a config changed event --- .../android/ui/posts/EditPostActivity.java | 14 ++++++++++++- .../editor/GutenbergContainerFragment.java | 4 ++++ .../editor/GutenbergEditorFragment.java | 20 ++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 78cc8596d3fd..34eaa0e557c1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -837,9 +837,21 @@ public void onConfigurationChanged(Configuration newConfig) { if (newConfig.fontScale != mConfigurationFontSize && (mEditorFragment instanceof GutenbergEditorFragment)) { + // Configuration has changed: Save the new fontScale and update the GB editor fragment(s). + // We can't rely on the Android and RN font scaling system, since we're using GB mobile in a retained fragment, + // and the configuration changed code is not called automatically. + // `setRetainInstance(true)` was set here + // https://github.com/wordpress-mobile/WordPress-Android/pull/9030/files#diff-02f567e707c1df878dfea548cfec3da7R111 + // in order to fix a couple of issues: history lost, and device rotation issues. GutenbergEditorFragment gbFragment = (GutenbergEditorFragment) mEditorFragment; + try { + updatePostObject(true); + } catch (EditorFragmentNotAddedException e) { + AppLog.e(T.EDITOR, "Impossible to save the post, we weren't able to update it."); + return; + } mConfigurationFontSize = newConfig.fontScale; - gbFragment.recreateReactContextInBackground(); + gbFragment.updateEditorContentAndReload(mPost.getTitle(), mPost.getContent()); } // resize the photo picker if the user rotated the device diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java index 589a4ce008f1..a5e0551ce0bb 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java @@ -146,6 +146,10 @@ public void clearMediaFileURL(final int mediaId) { mWPAndroidGlueCode.clearMediaFileURL(mediaId); } + /** + * Recreate the react application and context. + * See: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java#L350 + */ public void recreateReactContextInBackground() { mWPAndroidGlueCode.recreateReactContextInBackground(); } diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java index 3b4079998a89..4cc5ce4fc3a6 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java @@ -85,6 +85,9 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private ProgressDialog mSavingContentProgressDialog; + private String titleAfterConfigChanged = null; + private String contentAfterConfigChanged = null; + public static GutenbergEditorFragment newInstance(String title, String content, boolean isNewPost, @@ -260,6 +263,14 @@ public void onEditorDidMount(boolean hasUnsupportedBlocks) { @Override public void run() { setEditorProgressBarVisibility(!mEditorDidMount); + if (titleAfterConfigChanged != null) { + setTitle(titleAfterConfigChanged); + titleAfterConfigChanged = null; + } + if (contentAfterConfigChanged != null) { + setContent(contentAfterConfigChanged); + contentAfterConfigChanged = null; + } } }); } @@ -775,7 +786,14 @@ public void run() { return true; } - public void recreateReactContextInBackground() { + // Save a temporary copy of the content in GB mobile, and restore it when the editor is refreshed + // Note: History, block focused, and caret position is lost after this call! + public void updateEditorContentAndReload(String title, String content) { + contentAfterConfigChanged = content; + titleAfterConfigChanged = title; + // set this to false otherwise the spinning dialog is not shown + mEditorDidMount = false; + setEditorProgressBarVisibility(mEditorDidMount); mRetainedGutenbergContainerFragment.recreateReactContextInBackground(); } } From 2360b008294e31aa7fdd666d673958e8a64c0404 Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Wed, 3 Apr 2019 12:01:07 +0200 Subject: [PATCH 3/6] update GB hash --- libs/gutenberg-mobile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index e01cc75187d6..1baf6c90170a 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit e01cc75187d63768dde61ea2f9e8da9f8935e5e7 +Subproject commit 1baf6c90170a0802bf18a0319fb29787ef45bbc5 From a13d4622349f31a07f71d596b1c9dd89d92aa46d Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Wed, 3 Apr 2019 12:24:49 +0200 Subject: [PATCH 4/6] Fix lint --- .../android/ui/posts/EditPostActivity.java | 6 +++--- .../editor/GutenbergContainerFragment.java | 3 ++- .../editor/GutenbergEditorFragment.java | 20 +++++++++---------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 34eaa0e557c1..ed16753e162f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -838,10 +838,10 @@ public void onConfigurationChanged(Configuration newConfig) { if (newConfig.fontScale != mConfigurationFontSize && (mEditorFragment instanceof GutenbergEditorFragment)) { // Configuration has changed: Save the new fontScale and update the GB editor fragment(s). - // We can't rely on the Android and RN font scaling system, since we're using GB mobile in a retained fragment, - // and the configuration changed code is not called automatically. + // We can't rely on the Android and RN font scaling system, since we're using GB mobile + // in a retained fragment, and the configuration changed code is not called automatically. // `setRetainInstance(true)` was set here - // https://github.com/wordpress-mobile/WordPress-Android/pull/9030/files#diff-02f567e707c1df878dfea548cfec3da7R111 + // https://github.com/wordpress-mobile/WordPress-Android/pull/9030 // in order to fix a couple of issues: history lost, and device rotation issues. GutenbergEditorFragment gbFragment = (GutenbergEditorFragment) mEditorFragment; try { diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java index a5e0551ce0bb..f1c8648c437d 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java @@ -148,7 +148,8 @@ public void clearMediaFileURL(final int mediaId) { /** * Recreate the react application and context. - * See: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java#L350 + * See: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/ + * react/ReactInstanceManager.java#L350 */ public void recreateReactContextInBackground() { mWPAndroidGlueCode.recreateReactContextInBackground(); diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java index 4cc5ce4fc3a6..2792b8c85a0c 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java @@ -85,8 +85,8 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private ProgressDialog mSavingContentProgressDialog; - private String titleAfterConfigChanged = null; - private String contentAfterConfigChanged = null; + private String mTitleAfterConfigChanged = null; + private String mContentAfterConfigChanged = null; public static GutenbergEditorFragment newInstance(String title, String content, @@ -263,13 +263,13 @@ public void onEditorDidMount(boolean hasUnsupportedBlocks) { @Override public void run() { setEditorProgressBarVisibility(!mEditorDidMount); - if (titleAfterConfigChanged != null) { - setTitle(titleAfterConfigChanged); - titleAfterConfigChanged = null; + if (mTitleAfterConfigChanged != null) { + setTitle(mTitleAfterConfigChanged); + mTitleAfterConfigChanged = null; } - if (contentAfterConfigChanged != null) { - setContent(contentAfterConfigChanged); - contentAfterConfigChanged = null; + if (mContentAfterConfigChanged != null) { + setContent(mContentAfterConfigChanged); + mContentAfterConfigChanged = null; } } }); @@ -789,8 +789,8 @@ public void run() { // Save a temporary copy of the content in GB mobile, and restore it when the editor is refreshed // Note: History, block focused, and caret position is lost after this call! public void updateEditorContentAndReload(String title, String content) { - contentAfterConfigChanged = content; - titleAfterConfigChanged = title; + mContentAfterConfigChanged = content; + mTitleAfterConfigChanged = title; // set this to false otherwise the spinning dialog is not shown mEditorDidMount = false; setEditorProgressBarVisibility(mEditorDidMount); From 46a60b807235121f5447d0a3e735fd6a2ffede8a Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Wed, 3 Apr 2019 15:12:42 +0200 Subject: [PATCH 5/6] Make sure title and content are preserved on device rotation while reloading the editor during a configChanged event. Basically when the fontSize is changed in Settings, and the editor is being reloaded, the user can rotate the device, and the editor will then initialized with empty editor. --- .../editor/GutenbergEditorFragment.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java index 2792b8c85a0c..9ed6f1e6d519 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java @@ -59,6 +59,8 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements IHistoryListener { private static final String KEY_HTML_MODE_ENABLED = "KEY_HTML_MODE_ENABLED"; private static final String KEY_EDITOR_DID_MOUNT = "KEY_EDITOR_DID_MOUNT"; + private static final String KEY_TITLE_BEFORE_CONFIG_CHANGES = "KEY_TITLE_BEFORE_CONFIG_CHANGES"; + private static final String KEY_CONTENT_BEFORE_CONFIG_CHANGES = "KEY_CONTENT_BEFORE_CONFIG_CHANGES"; private static final String ARG_IS_NEW_POST = "param_is_new_post"; private static final String ARG_LOCALE_SLUG = "param_locale_slug"; @@ -85,8 +87,8 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private ProgressDialog mSavingContentProgressDialog; - private String mTitleAfterConfigChanged = null; - private String mContentAfterConfigChanged = null; + private String mTitleBeforeConfigChanged = null; + private String mContentBeforeConfigChanged = null; public static GutenbergEditorFragment newInstance(String title, String content, @@ -205,6 +207,8 @@ public void onCreate(Bundle savedInstanceState) { if (savedInstanceState != null) { mHtmlModeEnabled = savedInstanceState.getBoolean(KEY_HTML_MODE_ENABLED); mEditorDidMount = savedInstanceState.getBoolean(KEY_EDITOR_DID_MOUNT); + mTitleBeforeConfigChanged = savedInstanceState.getString(KEY_TITLE_BEFORE_CONFIG_CHANGES, null); + mContentBeforeConfigChanged = savedInstanceState.getString(KEY_CONTENT_BEFORE_CONFIG_CHANGES, null); } } @@ -263,13 +267,13 @@ public void onEditorDidMount(boolean hasUnsupportedBlocks) { @Override public void run() { setEditorProgressBarVisibility(!mEditorDidMount); - if (mTitleAfterConfigChanged != null) { - setTitle(mTitleAfterConfigChanged); - mTitleAfterConfigChanged = null; + if (mTitleBeforeConfigChanged != null) { + setTitle(mTitleBeforeConfigChanged); + mTitleBeforeConfigChanged = null; } - if (mContentAfterConfigChanged != null) { - setContent(mContentAfterConfigChanged); - mContentAfterConfigChanged = null; + if (mContentBeforeConfigChanged != null) { + setContent(mContentBeforeConfigChanged); + mContentBeforeConfigChanged = null; } } }); @@ -463,6 +467,8 @@ public void onAttach(Activity activity) { public void onSaveInstanceState(Bundle outState) { outState.putBoolean(KEY_HTML_MODE_ENABLED, mHtmlModeEnabled); outState.putBoolean(KEY_EDITOR_DID_MOUNT, mEditorDidMount); + outState.putString(KEY_TITLE_BEFORE_CONFIG_CHANGES, mTitleBeforeConfigChanged); + outState.putString(KEY_CONTENT_BEFORE_CONFIG_CHANGES, mContentBeforeConfigChanged); } @Override @@ -787,10 +793,10 @@ public void run() { } // Save a temporary copy of the content in GB mobile, and restore it when the editor is refreshed - // Note: History, block focused, and caret position is lost after this call! + // Note: History, block focused, scroll and caret position are lost after this call! public void updateEditorContentAndReload(String title, String content) { - mContentAfterConfigChanged = content; - mTitleAfterConfigChanged = title; + mContentBeforeConfigChanged = content; + mTitleBeforeConfigChanged = title; // set this to false otherwise the spinning dialog is not shown mEditorDidMount = false; setEditorProgressBarVisibility(mEditorDidMount); From 3015c5c86415e3f14377acf23d2de8e62403125b Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Wed, 3 Apr 2019 17:01:56 +0200 Subject: [PATCH 6/6] Make sure to retain `mHtmlModeEnabled` in GBContainerFragment, and fix a problem with the editor is re-started in Visual instead on HTML mode when the activity is killed by system. Ref: https://github.com/wordpress-mobile/WordPress-Android/pull/9509#issuecomment-479521662 --- .../android/editor/GutenbergContainerFragment.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java index f1c8648c437d..ef939fae7019 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergContainerFragment.java @@ -18,6 +18,8 @@ public class GutenbergContainerFragment extends Fragment { private static final String ARG_LOCALE = "param_locale"; private static final String ARG_TRANSLATIONS = "param_translations"; + private static final String KEY_HTML_MODE_ENABLED = "KEY_HTML_MODE_ENABLED"; + private boolean mHtmlModeEnabled; private boolean mHasReceivedAnyContent; @@ -53,6 +55,10 @@ public void onCreate(Bundle savedInstanceState) { String localeString = getArguments().getString(ARG_LOCALE); Bundle translations = getArguments().getBundle(ARG_TRANSLATIONS); + if (savedInstanceState != null) { + mHtmlModeEnabled = savedInstanceState.getBoolean(KEY_HTML_MODE_ENABLED); + } + mWPAndroidGlueCode = new WPAndroidGlueCode(); mWPAndroidGlueCode.onCreate(getContext()); mWPAndroidGlueCode.onCreateView( @@ -90,6 +96,11 @@ public void onDestroy() { mWPAndroidGlueCode.onDestroy(getActivity()); } + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putBoolean(KEY_HTML_MODE_ENABLED, mHtmlModeEnabled); + } + public void setTitle(String title) { mWPAndroidGlueCode.setTitle(title); mHasReceivedAnyContent = mWPAndroidGlueCode.hasReceivedInitialTitleAndContent();