From a88a3b587cf203c62c196332d64b33afe164d283 Mon Sep 17 00:00:00 2001 From: Siobhan Bamber Date: Tue, 20 Apr 2021 14:36:17 +0100 Subject: [PATCH] [RNMobile] Add Featured Banner to Image Block (Android Only) (#30806) * Add "set as featured image" button to image block This commit adds a "set as featured image" button to the image block's settings and also styles it. * Add "setFeaturedImage" function in bridge code With this commit, a "setFeaturedImage" function has been added to the React Native bridge code. * Add setFeaturedImage function to MainApplication This commit adds the setFeaturedImage function to the MainApplication file, so that it works as expected with the demo apps. * Add "OnSetFeaturedImageListener" listener This commit sets up a listener called "OnSetFeaturedImageListener" in order to allow communication with the native apps. * Update edit.native.js with small syntax correction This commit updates edit.native.js with small syntax correction, there was a missing comma at the end of a statement. * Set up "OnSetFeaturedImageListener" in WPAndroidGlue.java This commit updates WPAndroidGlue.java in order to set up a "OnSetFeaturedImageListener" function that will communicate with the Android app when a user clicks a "set as featured image" button. * Passing featured image ID from native (Android) to Gutenberg This commit seeks to send information about a post's featured image ID to Gutenberg by utlising functions from Android. * Restore missing curly brace Accidentally removed a curly brace with the last commit, so restoring it with this one. * Updates to featured-banner.native.js This commit including updates to featured-banner.native.js, a component for the "featured" banner that will overlay the image block when an image is featured. "payload.featuredImageId" logs the ID of a featured image after it's updated. * Attempts to select featured image using getEditedPostAttribute() This commit includes attempts to select a post's featured image using getEditedPostAttribute(). * Update featured-banner.native.js With this commit, I'm updating featured-banner.native.js with the latest changes to that component's UI. * Add featured banner to image/index.native.js With this commit, a featured banner is added to the image component. * Update featured image banner and button styles This commit updates the styles for the featured image banner and button that overlay the image compoonent. * Create getFeaturedImageId function and cleanup This commit includes a new getFeaturedImageId function, for grabbing a post's featured image when a component is mounted and also cleans up some unused code. * Tidy up edit.native.js * Update AndroidGlueCode Update AndroidGlueCode to include OnFocalPointPickerTooltipShownEventListener. * retrigger checks * Update setup.js * retrigger checks * Update function name from "featuredImageIdChange" to "featuredImageIdCurrent" With this commit, I'm updating a function's name from "featuredImageIdChange" to "featuredImageIdCurrent" in order to more accurately reflect its purpose. * Rename "featuredImageIdNotifier" to "onRequestFeaturedImageId" This commit renames "featuredImageIdNotifier" to "onRequestFeaturedImageId" in order to clarify the function's purpose. * Create OnSetFeaturedImageListener This commit introduces an "OnSetFeaturedImageListener" and moves new featured image related functions to it from "OnMediaLibraryButtonListener". * Dismiss bottomsheet when "setFeaturedImage" is called * Introduce "onRemoveFeatured" button and tidying up names This commit introduces a "onRemoveFeatured" button that displays in the image block's settings when an image is featured. It also changes the name of the "onGetFeaturedImageId" function to "checkIfFeaturedImage", to better reflect its current functionality. * Updates to function names This commit updates "onRequestFeaturedImageId" to "sendToJSFeaturedImageId" and "getFeaturedImageId" to "checkIfFeaturedImage". In both cases, this has been done to clarify the purpose of the functions. * Convert FeaturedBanner to Badge component This commit converts the FeaturedBanner component to a more generic Badge component. This is to make it more re-usable. There are also some small styling tweaks included in this commit, including changes to the component's border-radius. * Update edit.native.js to correct merge conflict * Correct merge conflict with GutenbergBridgeJS2Parent.java This commit is an attempt to correct this PR's merge conflict with GutenbergBridgeJS2Parent.java. * retrigger checks * retrigger checks * retrigger checks * Update edit.native.js to fix merge conflict * Update edit.native.js to check if an image is featured uppn changes This commit fixes a bug, where the "featured" banner did not update if an image was replaced directly within a block, using the available settings to the upper right. * Update styles.native.scss to add border to the top of featured button This commit also tidies up some of the code around styling to account for dark mode. * Update edit.native.js This commit moves the "checkIfFeaturedImage" check into its own function. * Introduce "featuredMedia" prop for use when editor loads This commit introduces a "featuredMedia" prop that is intended to be used when Gutenberg first loads. The prop is going to be passed over the bridge so that we can get information about a post's featured image ID from the app. * Fetch ID of post's initial featured image This commit introduces some changes in react-native-editor/src/index.js that enable getEditedPostAttribute( 'featured_media' ) to fetch the initial ID of a post's featured image. This is then used in the image block's componentDidMount function to pinpoint a featured image when it's first loaded in the editor. * Updated featured state when image is replaced within block This commit uses "setAttributes" to define a "currentFeaturedImageId" attribute. This attribute is then used in "componentDidUpdate" to check if an image is featured if it's replaced directly within the image block. There are also some smaller tweaks/improvements to the code in this commit, such as changing an if/else statement to use ES6's shorthand. * Remove checkIfFeaturedImage function This function has been replaced with functionality to grab a post's initial ID, as can be seen in the previous couple of commits. * Fix merge conflict * Fix merge conflict * Add "setFeaturedImage" and "featuredImageIdCurrent" functions to Swift files * Simplify this.state.isFeaturedImage by converting to a boolean insider render() This commit simplifies the process of determining whether an image is featured (currently done via by setting an isFeaturedImage state) by converting it to a boolean insider the render() function. * Comment out iOS-specific changes to the bridge This commit comments out iOS-specific changes to the bridge in ordet to test whether these changes are the reason behind a failing performance test. * Add iOS functions to bridge * Flag featured image when editor mounts and comment out iOS methods from bridge This commit adds a check to "componentDidMount" so that a featured image is flagged when the editor first mounts (fixes previous regression). It also comments out iOS methods over the bridge, a temporary change. * Comment out a bridge function for iOS (missing from previous commit). * Add set featured image functionality behind dev flag * Move "set as featured" button behind devOnly and androidOnly flag This commit also changes the "featured" banner so that it's accessible to all. * Remove redundant code This PR branches off #28854 in order to simplify PRs for a new feature that makes it easier for users to set a featured image from the image block. With this commit, I'm removing redundant code that isn't necessary for this specific PR (which will only include code that adds a "featured" banner to the image block). * Remove import of android.util.Log * Update CHANGELOG.md * Update Badge component for re-usability This commit updates the Badge component so that it works by wrapping around another component. This is designed to make the component easier to re-use. * Merge branch 'add-featured-badge' of https://github.com/SiobhyB/gutenberg into add-featured-badge * Correct merge conflict * Lift subscribeFeaturedImageIdCurrent from image/edit.native.js to post-edit/edit.native.js This components lifts the subscribeFeaturedImageIdCurrent function so that the data isn't managed directly from within the image component. * Remove commented out functions from iOS bridge This commit also removes a redundant empty space in a bridge file. * Remove androidOnly const The androidOnly const is not in use and can be removed. * Correct typo in README "add" should have been "adds". This commit corrects that. * Replace call to 'core' with 'coreStore" This commit replaces the direct call to the 'core' store with a call to 'coreStore', in line with preferred patterns followed elsewhere in the project. * Rename featuredMedia to featuredImageId * Destructure props This commit destructures props in the componentDidMount function to improve readability * Rename "featuredImageIdCurrent" to "featuredImageIdNativeUpdated" Following discussion, this commit renames "featuredImageIdCurrent" to "featuredImageIdNativeUpdated" in order to more clearly describe the function's purpose. * Limit subscribeFeaturedImageIdNativeUpdated to Android-only subscribeFeaturedImageIdNativeUpdated is currently only supported in the Android app, so this commit limits its usage to prevent errors on iOS. * Update CHANGELOG.md --- .../block-library/src/image/edit.native.js | 11 +++++-- packages/components/src/index.native.js | 1 + .../components/src/mobile/badge/README.md | 31 +++++++++++++++++++ .../src/mobile/badge/index.native.js | 27 ++++++++++++++++ .../components/src/mobile/badge/style.scss | 15 +++++++++ packages/edit-post/src/editor.native.js | 24 +++++++++++++- .../GutenbergBridgeJS2Parent.java | 4 +++ .../RNReactNativeGutenbergBridgeModule.java | 2 ++ .../WPAndroidGlue/DeferredEventEmitter.java | 12 ++++++- .../mobile/WPAndroidGlue/GutenbergProps.kt | 3 ++ .../WPAndroidGlue/WPAndroidGlueCode.java | 4 +++ packages/react-native-bridge/index.js | 9 ++++++ packages/react-native-editor/CHANGELOG.md | 1 + packages/react-native-editor/src/index.js | 2 ++ test/native/setup.js | 1 + 15 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 packages/components/src/mobile/badge/README.md create mode 100644 packages/components/src/mobile/badge/index.native.js create mode 100644 packages/components/src/mobile/badge/style.scss diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 7c4348270aaa0..285675c1585ab 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -26,6 +26,7 @@ import { LinkSettingsNavigation, BottomSheetTextControl, FooterMessageLink, + Badge, } from '@wordpress/components'; import { BlockCaption, @@ -437,6 +438,7 @@ export class ImageEdit extends Component { image, clientId, imageDefaultSize, + featuredImageId, } = this.props; const { align, url, alt, id, sizeSlug, className } = attributes; @@ -445,6 +447,8 @@ export class ImageEdit extends Component { imageDefaultSize, ] ); + const isFeaturedImage = featuredImageId === attributes.id; + const getToolbarEditButton = ( open ) => ( @@ -507,7 +511,7 @@ export class ImageEdit extends Component { }; const getImageComponent = ( openMediaOptions, getMediaOptions ) => ( - <> + - + ); return ( @@ -591,12 +595,14 @@ export default compose( [ withSelect( ( select, props ) => { const { getMedia } = select( coreStore ); const { getSettings } = select( blockEditorStore ); + const { getEditedPostAttribute } = select( 'core/editor' ); const { attributes: { id, url }, isSelected, } = props; const { imageSizes, imageDefaultSize } = getSettings(); const isNotFileUrl = id && getProtocol( url ) !== 'file:'; + const featuredImageId = getEditedPostAttribute( 'featured_media' ); const shouldGetMedia = ( isSelected && isNotFileUrl ) || @@ -610,6 +616,7 @@ export default compose( [ image: shouldGetMedia ? getMedia( id ) : null, imageSizes, imageDefaultSize, + featuredImageId, }; } ), withPreferredColorScheme, diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index 27ecb9022ef67..e910f3386c7e7 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -89,6 +89,7 @@ export { default as ImageEditingButton } from './mobile/image/image-editing-butt export { default as InserterButton } from './mobile/inserter-button'; export { setClipboard, getClipboard } from './mobile/clipboard'; export { default as AudioPlayer } from './mobile/audio-player'; +export { default as Badge } from './mobile/badge'; // Utils export { colorsUtils } from './mobile/color-settings/utils'; diff --git a/packages/components/src/mobile/badge/README.md b/packages/components/src/mobile/badge/README.md new file mode 100644 index 0000000000000..8e6453935f985 --- /dev/null +++ b/packages/components/src/mobile/badge/README.md @@ -0,0 +1,31 @@ +# Badge + +The Badge component is designed to be wrapped around another component. It adds a "badge" with some text to the child component's upper left. + +An example can be found in the image block. After setting an image as featured, a "featured" badge overlays the block. + +### Usage + +```jsx +return + + +; +``` + +### Props + +#### label + +The text that will be displayed within the Badge component. + +- Type: `String` +- Required: Yes + +#### show + +An optional boolean to determine whether the badge is displayed. + +- Type: `Boolean` +- Required: No +- Default: `true` diff --git a/packages/components/src/mobile/badge/index.native.js b/packages/components/src/mobile/badge/index.native.js new file mode 100644 index 0000000000000..7111257920dc9 --- /dev/null +++ b/packages/components/src/mobile/badge/index.native.js @@ -0,0 +1,27 @@ +/** + * External dependencies + */ +import { View, Text } from 'react-native'; + +/** + * WordPress dependencies + */ +import { withPreferredColorScheme } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import styles from './style.scss'; + +const Badge = ( { label, children, show = true } ) => { + return ( + <> + { children } + + { show && { label } } + + + ); +}; + +export default withPreferredColorScheme( Badge ); diff --git a/packages/components/src/mobile/badge/style.scss b/packages/components/src/mobile/badge/style.scss new file mode 100644 index 0000000000000..beae07d5360d0 --- /dev/null +++ b/packages/components/src/mobile/badge/style.scss @@ -0,0 +1,15 @@ +.badgeContainer { + position: absolute; + top: 0; + left: 0; + z-index: 2; +} + +.badge { + padding: 10px; + margin: 8px; + color: #fff; + border-radius: 3px; + background-color: $gray-70; + border-color: $gray-70; +} diff --git a/packages/edit-post/src/editor.native.js b/packages/edit-post/src/editor.native.js index 01fdca23b2604..cc79e0fb006c3 100644 --- a/packages/edit-post/src/editor.native.js +++ b/packages/edit-post/src/editor.native.js @@ -13,8 +13,12 @@ import { EditorProvider } from '@wordpress/editor'; import { parse, serialize, store as blocksStore } from '@wordpress/blocks'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; -import { subscribeSetFocusOnTitle } from '@wordpress/react-native-bridge'; +import { + subscribeSetFocusOnTitle, + subscribeFeaturedImageIdNativeUpdated, +} from '@wordpress/react-native-bridge'; import { SlotFillProvider } from '@wordpress/components'; +import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies @@ -77,6 +81,8 @@ class Editor extends Component { } componentDidMount() { + const { editEntityRecord, postType, postId } = this.props; + this.subscriptionParentSetFocusOnTitle = subscribeSetFocusOnTitle( () => { if ( this.postTitleRef ) { @@ -84,12 +90,24 @@ class Editor extends Component { } } ); + + this.subscriptionParentFeaturedImageIdNativeUpdated = subscribeFeaturedImageIdNativeUpdated( + ( payload ) => { + editEntityRecord( 'postType', postType, postId, { + featured_media: payload.featuredImageId, + } ); + } + ); } componentWillUnmount() { if ( this.subscriptionParentSetFocusOnTitle ) { this.subscriptionParentSetFocusOnTitle.remove(); } + + if ( this.subscribeFeaturedImageIdNativeUpdated ) { + this.subscribeFeaturedImageIdNativeUpdated.remove(); + } } setTitleRef( titleRef ) { @@ -107,6 +125,7 @@ class Editor extends Component { post, postId, postType, + featuredImageId, initialHtml, ...props } = this.props; @@ -124,6 +143,7 @@ class Editor extends Component { title: { raw: props.initialTitle || '', }, + featured_media: featuredImageId, content: { // make sure the post content is in sync with gutenberg store // to avoid marking the post as modified when simply loaded @@ -173,8 +193,10 @@ export default compose( [ } ), withDispatch( ( dispatch ) => { const { switchEditorMode } = dispatch( editPostStore ); + const { editEntityRecord } = dispatch( coreStore ); return { switchEditorMode, + editEntityRecord, }; } ), ] )( Editor ); diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java index ed3490932c592..01ba63621525d 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java @@ -44,6 +44,10 @@ interface MediaSaveEventEmitter { void onReplaceMediaFilesEditedBlock(final String mediaFiles, final String blockId); } + interface FeaturedImageEmitter { + void sendToJSFeaturedImageId(int mediaId); + } + interface ReplaceUnsupportedBlockCallback { void replaceUnsupportedBlock(String content, String blockId); } diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java index 5c440f4d4cde7..7cdd5d9c33cee 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java @@ -68,6 +68,8 @@ public class RNReactNativeGutenbergBridgeModule extends ReactContextBaseJavaModu private static final String MAP_KEY_REPLACE_BLOCK_HTML = "html"; private static final String MAP_KEY_REPLACE_BLOCK_BLOCK_ID = "clientId"; + public static final String MAP_KEY_FEATURED_IMAGE_ID = "featuredImageId"; + private boolean mIsDarkMode; public RNReactNativeGutenbergBridgeModule(ReactApplicationContext reactContext, diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java index 8643d4ca37b0b..0755ff3c68a92 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java @@ -10,6 +10,7 @@ import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaUploadEventEmitter; import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaSaveEventEmitter; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.FeaturedImageEmitter; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; @@ -18,8 +19,9 @@ import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_NEW_ID; import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL; import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FINAL_SAVE_RESULT_SUCCESS_VALUE; +import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_FEATURED_IMAGE_ID; -public class DeferredEventEmitter implements MediaUploadEventEmitter, MediaSaveEventEmitter { +public class DeferredEventEmitter implements MediaUploadEventEmitter, MediaSaveEventEmitter, FeaturedImageEmitter { public interface JSEventEmitter { void emitToJS(String eventName, @Nullable WritableMap data); } @@ -40,6 +42,8 @@ public interface JSEventEmitter { private static final String EVENT_NAME_MEDIA_SAVE = "mediaSave"; private static final String EVENT_NAME_MEDIA_REPLACE_BLOCK = "replaceBlock"; + private static final String EVENT_FEATURED_IMAGE_ID_NATIVE_UPDATED = "featuredImageIdNativeUpdated"; + private static final String MAP_KEY_MEDIA_FILE_STATE = "state"; private static final String MAP_KEY_MEDIA_FILE_MEDIA_ACTION_PROGRESS = "progress"; private static final String MAP_KEY_MEDIA_FILE_MEDIA_SERVER_ID = "mediaServerId"; @@ -205,6 +209,12 @@ public void onMediaCollectionSaveResult(String firstMediaIdInCollection, boolean } } + public void sendToJSFeaturedImageId(int mediaId) { + WritableMap writableMap = new WritableNativeMap(); + writableMap.putInt(MAP_KEY_FEATURED_IMAGE_ID, mediaId); + queueActionToJS(EVENT_FEATURED_IMAGE_ID_NATIVE_UPDATED, writableMap); + } + @Override public void onReplaceMediaFilesEditedBlock(String mediaFiles, String blockId) { WritableMap writableMap = new WritableNativeMap(); writableMap.putString(MAP_KEY_REPLACE_BLOCK_HTML, mediaFiles); diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt index 93e32a1da6a64..5e1e712cb414a 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt @@ -12,6 +12,7 @@ data class GutenbergProps @JvmOverloads constructor( val enableAudioBlock: Boolean, val localeSlug: String, val postType: String, + val featuredImageId: Int, val editorTheme: Bundle?, val translations: Bundle, val isDarkMode: Boolean, @@ -23,6 +24,7 @@ data class GutenbergProps @JvmOverloads constructor( putString(PROP_INITIAL_TITLE, "") putString(PROP_LOCALE, localeSlug) putString(PROP_POST_TYPE, postType) + putInt(PROP_INITIAL_FEATURED_IMAGE_ID, featuredImageId) putBundle(PROP_TRANSLATIONS, translations) putBoolean(PROP_INITIAL_HTML_MODE_ENABLED, htmlModeEnabled) @@ -56,6 +58,7 @@ data class GutenbergProps @JvmOverloads constructor( private const val PROP_INITIAL_TITLE = "initialTitle" private const val PROP_INITIAL_HTML_MODE_ENABLED = "initialHtmlModeEnabled" private const val PROP_POST_TYPE = "postType" + private const val PROP_INITIAL_FEATURED_IMAGE_ID = "featuredImageId" private const val PROP_LOCALE = "locale" private const val PROP_TRANSLATIONS = "translations" private const val PROP_COLORS = "colors" diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java index 5a8adc32b49f7..ba2ecc8aca706 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java @@ -956,6 +956,10 @@ public void mediaIdChanged(final String oldId, final String newId, final String mDeferredEventEmitter.onMediaIdChanged(oldId, newId, oldUrl); } + public void sendToJSFeaturedImageId(int mediaId) { + mDeferredEventEmitter.sendToJSFeaturedImageId(mediaId); + } + public void replaceUnsupportedBlock(String content, String blockId) { if (mReplaceUnsupportedBlockCallback != null) { mReplaceUnsupportedBlockCallback.replaceUnsupportedBlock(content, blockId); diff --git a/packages/react-native-bridge/index.js b/packages/react-native-bridge/index.js index 431b4936f63df..73099bd1eff3d 100644 --- a/packages/react-native-bridge/index.js +++ b/packages/react-native-bridge/index.js @@ -62,6 +62,15 @@ export function subscribeUpdateHtml( callback ) { return gutenbergBridgeEvents.addListener( 'updateHtml', callback ); } +export function subscribeFeaturedImageIdNativeUpdated( callback ) { + return isAndroid + ? gutenbergBridgeEvents.addListener( + 'featuredImageIdNativeUpdated', + callback + ) + : undefined; +} + /** * Request to subscribe to mediaUpload events * diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 04ee026e69469..35c22aabbdadb 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -12,6 +12,7 @@ For each user feature we should also add a importance categorization label to i ## Unreleased - [*] Image block: Improve text entry for long alt text. [#29670] +- [*] Image block: Add a "featured" banner. (Android only) [#30806] ## 1.50.0 diff --git a/packages/react-native-editor/src/index.js b/packages/react-native-editor/src/index.js index 5887201b6d10f..81abf5bd7eb9c 100644 --- a/packages/react-native-editor/src/index.js +++ b/packages/react-native-editor/src/index.js @@ -70,6 +70,7 @@ const setupInitHooks = () => { initialData, initialTitle, postType, + featuredImageId, colors, gradients, } = props; @@ -93,6 +94,7 @@ const setupInitHooks = () => { initialHtmlModeEnabled: props.initialHtmlModeEnabled, initialTitle, postType, + featuredImageId, capabilities, colors, gradients, diff --git a/test/native/setup.js b/test/native/setup.js index abc27aacf1f1a..9c89c8845d999 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -31,6 +31,7 @@ jest.mock( '@wordpress/react-native-bridge', () => { subscribeSetTitle: jest.fn(), subscribeSetFocusOnTitle: jest.fn(), subscribeUpdateHtml: jest.fn(), + subscribeFeaturedImageIdNativeUpdated: jest.fn(), subscribeMediaAppend: jest.fn(), subscribeAndroidModalClosed: jest.fn(), subscribeUpdateTheme: jest.fn(),