From 71cdff1d0d8776bc98bac436a23e11eca1a67921 Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Tue, 24 Oct 2023 18:20:34 +0200 Subject: [PATCH 1/5] feat: migrate js code of components --- docs/Images.md | 9 ------ docs/docs.json | 7 ----- src/components/Image.tsx | 18 +++--------- src/components/Images.tsx | 28 ++++++------------- src/components/Light.tsx | 18 ++++-------- src/components/NativeUserLocation.tsx | 10 ++----- src/components/Terrain.tsx | 14 ++-------- src/specs/RNMBXImageNativeComponent.ts | 18 ++++++++++++ src/specs/RNMBXImagesNativeComponent.ts | 18 ++++++++++++ src/specs/RNMBXLightNativeComponent.ts | 12 ++++++++ .../RNMBXNativeUserLocationNativeComponent.ts | 13 +++++++++ src/specs/RNMBXTerrainNativeComponent.ts | 13 +++++++++ 12 files changed, 97 insertions(+), 81 deletions(-) create mode 100644 src/specs/RNMBXImageNativeComponent.ts create mode 100644 src/specs/RNMBXImagesNativeComponent.ts create mode 100644 src/specs/RNMBXLightNativeComponent.ts create mode 100644 src/specs/RNMBXNativeUserLocationNativeComponent.ts create mode 100644 src/specs/RNMBXTerrainNativeComponent.ts diff --git a/docs/Images.md b/docs/Images.md index 1659fb88e..1fdff3a4f 100644 --- a/docs/Images.md +++ b/docs/Images.md @@ -48,15 +48,6 @@ any of the `Images` component of the Map. [Shape Source Icons](../examples/SymbolCircleLayer/ShapeSourceIcon) -### id - -```tsx -string -``` -FIX ME NO DESCRIPTION - - - ### children ```tsx diff --git a/docs/docs.json b/docs/docs.json index f0961a366..49bb7f469 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -2379,13 +2379,6 @@ "default": "none", "description": "Gets called when a Layer is trying to render an image whose key is not present in\nany of the `Images` component of the Map.\n*signature:*`(imageKey:string) => void`" }, - { - "name": "id", - "required": false, - "type": "string", - "default": "none", - "description": "FIX ME NO DESCRIPTION" - }, { "name": "children", "required": false, diff --git a/src/components/Image.tsx b/src/components/Image.tsx index 328e26a45..4961b4306 100644 --- a/src/components/Image.tsx +++ b/src/components/Image.tsx @@ -1,5 +1,6 @@ import React, { memo, forwardRef, ReactElement } from 'react'; -import { requireNativeComponent } from 'react-native'; + +import RNMBXImageNativeComponent from '../specs/RNMBXImageNativeComponent'; interface Props { /** ID of the image */ @@ -42,22 +43,11 @@ const Image = memo( stretchY, children, }; - return ; + // @ts-expect-error just codegen stuff + return ; }), ); -interface NativeProps { - name: string; - children: ReactElement; - sdf?: boolean; - stretchX?: [number, number][]; - stretchY?: [number, number][]; -} - -export const NATIVE_MODULE_NAME = 'RNMBXImage'; - -const RNMBXImage = requireNativeComponent(NATIVE_MODULE_NAME); - Image.displayName = 'Image'; export default Image; diff --git a/src/components/Images.tsx b/src/components/Images.tsx index 804796f33..352d793c6 100644 --- a/src/components/Images.tsx +++ b/src/components/Images.tsx @@ -1,11 +1,9 @@ import React, { ReactNode, ReactElement } from 'react'; -import { - requireNativeComponent, - Image as RNImage, - ImageURISource, -} from 'react-native'; +import { Image as RNImage, ImageURISource } from 'react-native'; import { ImageSourcePropType, ImageResolvedAssetSource } from 'react-native'; +import RNMBXImagesNativeComponent from '../specs/RNMBXImagesNativeComponent'; + import { ShapeSource } from './ShapeSource'; import Image from './Image'; @@ -101,7 +99,6 @@ interface Props { */ onImageMissing?: (imageKey: string) => void; - id?: string; children?: TypedReactNode; } @@ -184,25 +181,18 @@ class Images extends React.PureComponent { render() { const props = { - id: this.props.id, hasOnImageMissing: !!this.props.onImageMissing, onImageMissing: this._onImageMissing.bind(this), ...this._getImages(), }; - return {this.props.children}; + return ( + // @ts-expect-error just codegen stuff + + {this.props.children} + + ); } } -type NativeProps = { - hasOnImageMissing: boolean; - onImageMissing?: (event: React.SyntheticEvent) => void; - images?: { - [key: string]: string | ImageResolvedAssetSource | ResolvedImageEntryData; - }; - nativeImages?: NativeImage[]; -}; - -const RNMBXImages = requireNativeComponent(NATIVE_MODULE_NAME); - export default Images; diff --git a/src/components/Light.tsx b/src/components/Light.tsx index a71cbcf93..dd91f6b1c 100644 --- a/src/components/Light.tsx +++ b/src/components/Light.tsx @@ -1,14 +1,11 @@ import React, { forwardRef, memo, useImperativeHandle, useRef } from 'react'; -import { requireNativeComponent } from 'react-native'; +import RNMBXLightNativeComponent from '../specs/RNMBXLightNativeComponent'; import { LightLayerStyleProps } from '../utils/MapboxStyles'; -import { StyleValue } from '../utils/StyleValue'; import { type BaseProps } from '../types/BaseProps'; import { transformStyle } from '../utils/StyleValue'; import nativeRef from '../utils/nativeRef'; -export const NATIVE_MODULE_NAME = 'RNMBXLight'; - type Props = BaseProps & { /** * Customizable style attributes @@ -16,10 +13,6 @@ type Props = BaseProps & { style: LightLayerStyleProps; }; -type NativeProps = Omit & { - reactStyle?: { [key: string]: StyleValue }; -}; - interface LightMethods { setNativeProps(props: { [key: string]: unknown }): void; } @@ -30,7 +23,7 @@ interface LightMethods { function Light(props: Props, ref: React.ForwardedRef) { const { style, ...propWithoutStyle } = props; - const nativeLightRef = nativeRef(useRef(null)); + const nativeLightRef = nativeRef(useRef(null)); useImperativeHandle(ref, () => ({ setNativeProps(_props: { [key: string]: unknown }) { @@ -46,15 +39,14 @@ function Light(props: Props, ref: React.ForwardedRef) { })); return ( - ); } -const RNMBXLight = requireNativeComponent(NATIVE_MODULE_NAME); - export default memo(forwardRef(Light)); diff --git a/src/components/NativeUserLocation.tsx b/src/components/NativeUserLocation.tsx index f873a6e24..7f9cd2c96 100644 --- a/src/components/NativeUserLocation.tsx +++ b/src/components/NativeUserLocation.tsx @@ -1,7 +1,6 @@ import React, { memo } from 'react'; -import { requireNativeComponent } from 'react-native'; -const NATIVE_MODULE_NAME = 'RNMBXNativeUserLocation'; +import RNMBXNativeUserLocationNativeComponent from '../specs/RNMBXNativeUserLocationNativeComponent'; export type Props = { /** @@ -23,13 +22,8 @@ export type Props = { iosShowsUserHeadingIndicator?: boolean; }; -type NativeProps = Props; - -const RNMBXNativeUserLocation = - requireNativeComponent(NATIVE_MODULE_NAME); - const NativeUserLocation = memo((props: Props) => { - return ; + return ; }); export default NativeUserLocation; diff --git a/src/components/Terrain.tsx b/src/components/Terrain.tsx index bfa864de3..c1dddc4cd 100644 --- a/src/components/Terrain.tsx +++ b/src/components/Terrain.tsx @@ -1,11 +1,9 @@ import React, { memo, useMemo } from 'react'; -import { requireNativeComponent } from 'react-native'; import type { TerrainLayerStyleProps, Value } from '../utils/MapboxStyles'; -import { StyleValue, transformStyle } from '../utils/StyleValue'; +import { transformStyle } from '../utils/StyleValue'; import type { BaseProps } from '../types/BaseProps'; - -export const NATIVE_MODULE_NAME = 'RNMBXTerrain'; +import RNMBXATerrainNativeComponent from '../specs/RNMBXTerrainNativeComponent'; type Props = BaseProps & { /** @@ -24,10 +22,6 @@ type Props = BaseProps & { style?: TerrainLayerStyleProps; }; -type NativeProps = Omit & { - reactStyle?: { [key: string]: StyleValue }; -}; - export const Terrain = memo((props: Props) => { let { style = {} } = props; @@ -46,7 +40,5 @@ export const Terrain = memo((props: Props) => { }; }, [props, style]); - return ; + return ; }); - -const RNMBXTerrain = requireNativeComponent(NATIVE_MODULE_NAME); diff --git a/src/specs/RNMBXImageNativeComponent.ts b/src/specs/RNMBXImageNativeComponent.ts new file mode 100644 index 000000000..db177ed3a --- /dev/null +++ b/src/specs/RNMBXImageNativeComponent.ts @@ -0,0 +1,18 @@ +import type { HostComponent, ViewProps } from 'react-native'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; +import type { Double } from 'react-native/Libraries/Types/CodegenTypes'; + +import type { UnsafeMixed } from './codegenUtils'; + +export interface NativeProps extends ViewProps { + stretchX: UnsafeMixed>; // Array inside UnsafeMixed + stretchY: UnsafeMixed>; // Array inside UnsafeMixed + content: UnsafeMixed>; + sdf: UnsafeMixed; + name: UnsafeMixed; + scale?: UnsafeMixed; +} + +export default codegenNativeComponent( + 'RNMBXImage', +) as HostComponent; diff --git a/src/specs/RNMBXImagesNativeComponent.ts b/src/specs/RNMBXImagesNativeComponent.ts new file mode 100644 index 000000000..4c34484e4 --- /dev/null +++ b/src/specs/RNMBXImagesNativeComponent.ts @@ -0,0 +1,18 @@ +import type { HostComponent, ViewProps } from 'react-native'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; +import type { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes'; + +import type { UnsafeMixed } from './codegenUtils'; + +type OnImageMissingEventType = { type: string; payload: { imageKey: string } }; + +export interface NativeProps extends ViewProps { + images: UnsafeMixed; + nativeImages: UnsafeMixed>; + hasOnImageMissing: UnsafeMixed; + onImageMissing: DirectEventHandler; +} + +export default codegenNativeComponent( + 'RNMBXImages', +) as HostComponent; diff --git a/src/specs/RNMBXLightNativeComponent.ts b/src/specs/RNMBXLightNativeComponent.ts new file mode 100644 index 000000000..d33358ada --- /dev/null +++ b/src/specs/RNMBXLightNativeComponent.ts @@ -0,0 +1,12 @@ +import type { HostComponent, ViewProps } from 'react-native'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; + +import type { UnsafeMixed } from './codegenUtils'; + +export interface NativeProps extends ViewProps { + reactStyle: UnsafeMixed; +} + +export default codegenNativeComponent( + 'RNMBXLight', +) as HostComponent; diff --git a/src/specs/RNMBXNativeUserLocationNativeComponent.ts b/src/specs/RNMBXNativeUserLocationNativeComponent.ts new file mode 100644 index 000000000..15731f1a2 --- /dev/null +++ b/src/specs/RNMBXNativeUserLocationNativeComponent.ts @@ -0,0 +1,13 @@ +import type { HostComponent, ViewProps } from 'react-native'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; + +import { UnsafeMixed } from './codegenUtils'; + +export interface NativeProps extends ViewProps { + androidRenderMode?: UnsafeMixed; + iosShowsUserHeadingIndicator?: UnsafeMixed; +} + +export default codegenNativeComponent( + 'RNMBXNativeUserLocation', +) as HostComponent; diff --git a/src/specs/RNMBXTerrainNativeComponent.ts b/src/specs/RNMBXTerrainNativeComponent.ts new file mode 100644 index 000000000..0ffd33c05 --- /dev/null +++ b/src/specs/RNMBXTerrainNativeComponent.ts @@ -0,0 +1,13 @@ +import type { HostComponent, ViewProps } from 'react-native'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; + +import type { UnsafeMixed } from './codegenUtils'; + +export interface NativeProps extends ViewProps { + sourceID?: UnsafeMixed; + reactStyle: UnsafeMixed; +} + +export default codegenNativeComponent( + 'RNMBXTerrain', +) as HostComponent; From 446fe2636b1e24eea817a0d74db3cd556ecc3ce3 Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Tue, 24 Oct 2023 18:21:28 +0200 Subject: [PATCH 2/5] feat: migrate Android code of components --- .../components/images/RNMBXImageManager.kt | 24 +++++----- .../components/images/RNMBXImagesManager.kt | 17 +++---- .../RNMBXNativeUserLocationManager.kt | 15 ++++-- .../styles/light/RNMBXLightManager.java | 25 ---------- .../styles/light/RNMBXLightManager.kt | 27 +++++++++++ .../styles/terrain/RNMBXTerrainManager.kt | 23 +++++---- .../RNMBXImageManagerDelegate.java | 47 +++++++++++++++++++ .../RNMBXImageManagerInterface.java | 22 +++++++++ .../RNMBXImagesManagerDelegate.java | 38 +++++++++++++++ .../RNMBXImagesManagerInterface.java | 19 ++++++++ .../RNMBXLightManagerDelegate.java | 32 +++++++++++++ .../RNMBXLightManagerInterface.java | 17 +++++++ ...NMBXNativeUserLocationManagerDelegate.java | 35 ++++++++++++++ ...MBXNativeUserLocationManagerInterface.java | 18 +++++++ .../RNMBXTerrainManagerDelegate.java | 35 ++++++++++++++ .../RNMBXTerrainManagerInterface.java | 18 +++++++ 16 files changed, 352 insertions(+), 60 deletions(-) delete mode 100644 android/src/main/java/com/rnmapbox/rnmbx/components/styles/light/RNMBXLightManager.java create mode 100644 android/src/main/java/com/rnmapbox/rnmbx/components/styles/light/RNMBXLightManager.kt create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImageManagerDelegate.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImageManagerInterface.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImagesManagerDelegate.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImagesManagerInterface.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXLightManagerDelegate.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXLightManagerInterface.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXNativeUserLocationManagerDelegate.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXNativeUserLocationManagerInterface.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXTerrainManagerDelegate.java create mode 100644 android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXTerrainManagerInterface.java diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageManager.kt index 99be80d93..fda0a1abb 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageManager.kt @@ -1,18 +1,16 @@ package com.rnmapbox.rnmbx.components.images import com.facebook.react.bridge.Dynamic -import com.facebook.react.bridge.DynamicFromArray import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReadableArray -import com.facebook.react.common.MapBuilder import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.RNMBXImageManagerInterface import com.rnmapbox.rnmbx.components.AbstractEventEmitter -import com.rnmapbox.rnmbx.events.constants.EventKeys class RNMBXImageManager(private val mContext: ReactApplicationContext) : AbstractEventEmitter( mContext -) { +), RNMBXImageManagerInterface { override fun getName(): String { return "RNMBXImage" } @@ -27,33 +25,33 @@ mContext // region React properties @ReactProp(name="name") - fun setName(image: RNMBXImage, value: String) { - image.name = value + override fun setName(image: RNMBXImage, value: Dynamic) { + image.name = value.asString() } @ReactProp(name="sdf") - fun setSdf(image: RNMBXImage, value: Boolean) { - image.sdf = value + override fun setSdf(image: RNMBXImage, value: Dynamic) { + image.sdf = value.asBoolean() } @ReactProp(name="stretchX") - fun setStretchX(image: RNMBXImage, value: Dynamic) { + override fun setStretchX(image: RNMBXImage, value: Dynamic) { image.stretchX = RNMBXImagesManager.convertStretch(value) ?: listOf() } @ReactProp(name="stretchY") - fun setStretchY(image: RNMBXImage, value: Dynamic) { + override fun setStretchY(image: RNMBXImage, value: Dynamic) { image.stretchY = RNMBXImagesManager.convertStretch(value) ?: listOf() } @ReactProp(name="content") - fun setContent(image: RNMBXImage, value: Dynamic) { + override fun setContent(image: RNMBXImage, value: Dynamic) { image.content = RNMBXImagesManager.convertContent(value) } @ReactProp(name="scale") - fun setScale(image: RNMBXImage, value: Double) { - image.scale = value + override fun setScale(image: RNMBXImage, value: Dynamic) { + image.scale = value.asDouble() } // endregion diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImagesManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImagesManager.kt index d85c012bf..777d74fad 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImagesManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImagesManager.kt @@ -6,6 +6,7 @@ import com.facebook.react.bridge.* import com.facebook.react.common.MapBuilder import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.RNMBXImagesManagerInterface import com.mapbox.maps.ImageContent import com.mapbox.maps.ImageStretches import com.rnmapbox.rnmbx.components.AbstractEventEmitter @@ -20,7 +21,7 @@ import java.util.* class RNMBXImagesManager(private val mContext: ReactApplicationContext) : AbstractEventEmitter( mContext - ) { + ), RNMBXImagesManagerInterface { override fun getName(): String { return "RNMBXImages" } @@ -67,9 +68,9 @@ class RNMBXImagesManager(private val mContext: ReactApplicationContext) : } @ReactProp(name = "images") - fun setImages(images: RNMBXImages, map: ReadableMap) { + override fun setImages(images: RNMBXImages, map: Dynamic) { val imagesList = mutableListOf>() - map.forEach { imageName, imageInfo -> + map.asMap().forEach { imageName, imageInfo -> when (imageInfo) { is ReadableMap -> { val uri = imageInfo.getString("uri") @@ -128,8 +129,8 @@ class RNMBXImagesManager(private val mContext: ReactApplicationContext) : } @ReactProp(name = "hasOnImageMissing") - fun setHasOnImageMissing(images: RNMBXImages, value: Boolean?) { - images.setHasOnImageMissing(value!!) + override fun setHasOnImageMissing(images: RNMBXImages, value: Dynamic) { + images.setHasOnImageMissing(value.asBoolean()) } fun toNativeImage(dynamic: Dynamic): NativeImage? { @@ -165,10 +166,10 @@ class RNMBXImagesManager(private val mContext: ReactApplicationContext) : } @ReactProp(name = "nativeImages") - fun setNativeImages(images: RNMBXImages, arr: ReadableArray) { + override fun setNativeImages(images: RNMBXImages, arr: Dynamic) { val nativeImages = mutableListOf(); - for (i in 0 until arr.size()) { - val nativeImage = toNativeImage(arr.getDynamic(i)) + for (i in 0 until arr.asArray().size()) { + val nativeImage = toNativeImage(arr.asArray().getDynamic(i)) if (nativeImage != null) { nativeImages.add(nativeImage) } diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/location/RNMBXNativeUserLocationManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/location/RNMBXNativeUserLocationManager.kt index 37fff342b..35de87a6c 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/location/RNMBXNativeUserLocationManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/location/RNMBXNativeUserLocationManager.kt @@ -1,26 +1,33 @@ package com.rnmapbox.rnmbx.components.location +import com.facebook.react.bridge.Dynamic import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.annotations.ReactProp -import com.rnmapbox.rnmbx.utils.Logger +import com.facebook.react.viewmanagers.RNMBXNativeUserLocationManagerInterface import javax.annotation.Nonnull -class RNMBXNativeUserLocationManager : ViewGroupManager() { +class RNMBXNativeUserLocationManager : ViewGroupManager(), + RNMBXNativeUserLocationManagerInterface { @Nonnull override fun getName(): String { return REACT_CLASS } @ReactProp(name = "androidRenderMode") - fun setAndroidRenderMode(userLocation: RNMBXNativeUserLocation, mode: String) { - when (mode) { + override fun setAndroidRenderMode(userLocation: RNMBXNativeUserLocation, mode: Dynamic) { + when (mode.asString()) { "compass" -> userLocation.setAndroidRenderMode(RenderMode.COMPASS); "gps" -> userLocation.setAndroidRenderMode(RenderMode.GPS); "normal" -> userLocation.setAndroidRenderMode(RenderMode.NORMAL); } } + @ReactProp(name = "iosShowsUserHeadingIndicator") + override fun setIosShowsUserHeadingIndicator(view: RNMBXNativeUserLocation, value: Dynamic) { + // iOS only + } + @Nonnull override fun createViewInstance(@Nonnull reactContext: ThemedReactContext): RNMBXNativeUserLocation { return RNMBXNativeUserLocation(reactContext) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/light/RNMBXLightManager.java b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/light/RNMBXLightManager.java deleted file mode 100644 index a4eb86a20..000000000 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/light/RNMBXLightManager.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.rnmapbox.rnmbx.components.styles.light; - -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.ViewGroupManager; -import com.facebook.react.uimanager.annotations.ReactProp; - -public class RNMBXLightManager extends ViewGroupManager { - public static final String REACT_CLASS = "RNMBXLight"; - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - protected RNMBXLight createViewInstance(ThemedReactContext reactContext) { - return new RNMBXLight(reactContext); - } - - @ReactProp(name="reactStyle") - public void setReactStyle(RNMBXLight light, ReadableMap reactStyle) { - light.setReactStyle(reactStyle); - } -} diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/light/RNMBXLightManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/light/RNMBXLightManager.kt new file mode 100644 index 000000000..8f2227c36 --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/light/RNMBXLightManager.kt @@ -0,0 +1,27 @@ +package com.rnmapbox.rnmbx.components.styles.light + +import com.facebook.react.bridge.Dynamic +import com.facebook.react.uimanager.ThemedReactContext +import com.facebook.react.uimanager.ViewGroupManager +import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.RNMBXLightManagerInterface + +class RNMBXLightManager : ViewGroupManager(), + RNMBXLightManagerInterface { + override fun getName(): String { + return REACT_CLASS + } + + override fun createViewInstance(reactContext: ThemedReactContext): RNMBXLight { + return RNMBXLight(reactContext) + } + + @ReactProp(name = "reactStyle") + override fun setReactStyle(light: RNMBXLight, reactStyle: Dynamic) { + light.setReactStyle(reactStyle.asMap()) + } + + companion object { + const val REACT_CLASS = "RNMBXLight" + } +} \ No newline at end of file diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/terrain/RNMBXTerrainManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/terrain/RNMBXTerrainManager.kt index ccffa377e..79d1da82b 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/terrain/RNMBXTerrainManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/terrain/RNMBXTerrainManager.kt @@ -1,11 +1,13 @@ package com.rnmapbox.rnmbx.components.styles.terrain -import com.facebook.react.bridge.ReadableMap +import com.facebook.react.bridge.Dynamic import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.RNMBXTerrainManagerInterface -class RNMBXTerrainManager : ViewGroupManager() { +class RNMBXTerrainManager : ViewGroupManager(), + RNMBXTerrainManagerInterface { override fun getName(): String { return REACT_CLASS } @@ -14,19 +16,20 @@ class RNMBXTerrainManager : ViewGroupManager() { return RNMBXTerrain(reactContext) } - @ReactProp(name = "id") - fun setId(layer: RNMBXTerrain, id: String?) { - layer.iD = id - } + // TODO: it is not present in props so should we add it? +// @ReactProp(name = "id") +// override fun setId(layer: RNMBXTerrain, id: Dynamic) { +// layer.iD = id.asString() +// } @ReactProp(name = "sourceID") - fun setSourceID(layer: RNMBXTerrain, sourceID: String?) { - layer.setSourceID(sourceID) + override fun setSourceID(layer: RNMBXTerrain, sourceID: Dynamic) { + layer.setSourceID(sourceID.asString()) } @ReactProp(name = "reactStyle") - fun setReactStyle(terrain: RNMBXTerrain, reactStyle: ReadableMap?) { - terrain.setReactStyle(reactStyle) + override fun setReactStyle(terrain: RNMBXTerrain, reactStyle: Dynamic) { + terrain.setReactStyle(reactStyle.asMap()) } companion object { diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImageManagerDelegate.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImageManagerDelegate.java new file mode 100644 index 000000000..0857a077e --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImageManagerDelegate.java @@ -0,0 +1,47 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.DynamicFromObject; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; + +public class RNMBXImageManagerDelegate & RNMBXImageManagerInterface> extends BaseViewManagerDelegate { + public RNMBXImageManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "stretchX": + mViewManager.setStretchX(view, new DynamicFromObject(value)); + break; + case "stretchY": + mViewManager.setStretchY(view, new DynamicFromObject(value)); + break; + case "content": + mViewManager.setContent(view, new DynamicFromObject(value)); + break; + case "sdf": + mViewManager.setSdf(view, new DynamicFromObject(value)); + break; + case "name": + mViewManager.setName(view, new DynamicFromObject(value)); + break; + case "scale": + mViewManager.setScale(view, new DynamicFromObject(value)); + break; + default: + super.setProperty(view, propName, value); + } + } +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImageManagerInterface.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImageManagerInterface.java new file mode 100644 index 000000000..c32b38792 --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImageManagerInterface.java @@ -0,0 +1,22 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import com.facebook.react.bridge.Dynamic; + +public interface RNMBXImageManagerInterface { + void setStretchX(T view, Dynamic value); + void setStretchY(T view, Dynamic value); + void setContent(T view, Dynamic value); + void setSdf(T view, Dynamic value); + void setName(T view, Dynamic value); + void setScale(T view, Dynamic value); +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImagesManagerDelegate.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImagesManagerDelegate.java new file mode 100644 index 000000000..59a80b2b7 --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImagesManagerDelegate.java @@ -0,0 +1,38 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.DynamicFromObject; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; + +public class RNMBXImagesManagerDelegate & RNMBXImagesManagerInterface> extends BaseViewManagerDelegate { + public RNMBXImagesManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "images": + mViewManager.setImages(view, new DynamicFromObject(value)); + break; + case "nativeImages": + mViewManager.setNativeImages(view, new DynamicFromObject(value)); + break; + case "hasOnImageMissing": + mViewManager.setHasOnImageMissing(view, new DynamicFromObject(value)); + break; + default: + super.setProperty(view, propName, value); + } + } +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImagesManagerInterface.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImagesManagerInterface.java new file mode 100644 index 000000000..3feb308b6 --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXImagesManagerInterface.java @@ -0,0 +1,19 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import com.facebook.react.bridge.Dynamic; + +public interface RNMBXImagesManagerInterface { + void setImages(T view, Dynamic value); + void setNativeImages(T view, Dynamic value); + void setHasOnImageMissing(T view, Dynamic value); +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXLightManagerDelegate.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXLightManagerDelegate.java new file mode 100644 index 000000000..90cd3628f --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXLightManagerDelegate.java @@ -0,0 +1,32 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.DynamicFromObject; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; + +public class RNMBXLightManagerDelegate & RNMBXLightManagerInterface> extends BaseViewManagerDelegate { + public RNMBXLightManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "reactStyle": + mViewManager.setReactStyle(view, new DynamicFromObject(value)); + break; + default: + super.setProperty(view, propName, value); + } + } +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXLightManagerInterface.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXLightManagerInterface.java new file mode 100644 index 000000000..4bbb1c442 --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXLightManagerInterface.java @@ -0,0 +1,17 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import com.facebook.react.bridge.Dynamic; + +public interface RNMBXLightManagerInterface { + void setReactStyle(T view, Dynamic value); +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXNativeUserLocationManagerDelegate.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXNativeUserLocationManagerDelegate.java new file mode 100644 index 000000000..0ffcbc2a7 --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXNativeUserLocationManagerDelegate.java @@ -0,0 +1,35 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.DynamicFromObject; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; + +public class RNMBXNativeUserLocationManagerDelegate & RNMBXNativeUserLocationManagerInterface> extends BaseViewManagerDelegate { + public RNMBXNativeUserLocationManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "androidRenderMode": + mViewManager.setAndroidRenderMode(view, new DynamicFromObject(value)); + break; + case "iosShowsUserHeadingIndicator": + mViewManager.setIosShowsUserHeadingIndicator(view, new DynamicFromObject(value)); + break; + default: + super.setProperty(view, propName, value); + } + } +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXNativeUserLocationManagerInterface.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXNativeUserLocationManagerInterface.java new file mode 100644 index 000000000..c42498ed7 --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXNativeUserLocationManagerInterface.java @@ -0,0 +1,18 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import com.facebook.react.bridge.Dynamic; + +public interface RNMBXNativeUserLocationManagerInterface { + void setAndroidRenderMode(T view, Dynamic value); + void setIosShowsUserHeadingIndicator(T view, Dynamic value); +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXTerrainManagerDelegate.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXTerrainManagerDelegate.java new file mode 100644 index 000000000..54a428c0c --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXTerrainManagerDelegate.java @@ -0,0 +1,35 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.DynamicFromObject; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; + +public class RNMBXTerrainManagerDelegate & RNMBXTerrainManagerInterface> extends BaseViewManagerDelegate { + public RNMBXTerrainManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "sourceID": + mViewManager.setSourceID(view, new DynamicFromObject(value)); + break; + case "reactStyle": + mViewManager.setReactStyle(view, new DynamicFromObject(value)); + break; + default: + super.setProperty(view, propName, value); + } + } +} diff --git a/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXTerrainManagerInterface.java b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXTerrainManagerInterface.java new file mode 100644 index 000000000..9964c5ff6 --- /dev/null +++ b/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXTerrainManagerInterface.java @@ -0,0 +1,18 @@ +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import com.facebook.react.bridge.Dynamic; + +public interface RNMBXTerrainManagerInterface { + void setSourceID(T view, Dynamic value); + void setReactStyle(T view, Dynamic value); +} From 32fba23c1f5c6156fe2b3d8416b9c936f5053afb Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Tue, 24 Oct 2023 18:22:31 +0200 Subject: [PATCH 3/5] feat: migrate iOS code of components --- fabricexample/ios/Podfile.lock | 36 ++++--- ios/RNMBX/RNMBXImage.swift | 52 +++++---- ios/RNMBX/RNMBXImageComponentView.h | 15 +++ ios/RNMBX/RNMBXImageComponentView.mm | 100 ++++++++++++++++++ ios/RNMBX/RNMBXImageManager.swift | 1 - ios/RNMBX/RNMBXImages.swift | 26 ++--- ios/RNMBX/RNMBXImagesComponentView.h | 15 +++ ios/RNMBX/RNMBXImagesComponentView.mm | 91 ++++++++++++++++ ...agesManager.m => RNMBXImagesViewManager.m} | 3 +- ...ger.swift => RNMBXImagesViewManager.swift} | 4 +- ios/RNMBX/RNMBXLight.swift | 24 ++--- ios/RNMBX/RNMBXLightComponentView.h | 15 +++ ios/RNMBX/RNMBXLightComponentView.mm | 68 ++++++++++++ ...LightManager.m => RNMBXLightViewManager.m} | 2 +- ...ager.swift => RNMBXLightViewManager.swift} | 4 +- ios/RNMBX/RNMBXNativeUserLocation.swift | 8 +- .../RNMBXNativeUserLocationComponentView.h | 15 +++ .../RNMBXNativeUserLocationComponentView.mm | 72 +++++++++++++ ...m => RNMBXNativeUserLocationViewManager.m} | 2 +- ... RNMBXNativeUserLocationViewManager.swift} | 4 +- ios/RNMBX/RNMBXSingletonLayer.swift | 2 +- ios/RNMBX/RNMBXTerrain.swift | 4 +- ios/RNMBX/RNMBXTerrainComponentView.h | 15 +++ ios/RNMBX/RNMBXTerrainComponentView.mm | 78 ++++++++++++++ ...ainManager.m => RNMBXTerrainViewManager.m} | 2 +- ...er.swift => RNMBXTerrainViewManager.swift} | 4 +- 26 files changed, 565 insertions(+), 97 deletions(-) create mode 100644 ios/RNMBX/RNMBXImageComponentView.h create mode 100644 ios/RNMBX/RNMBXImageComponentView.mm create mode 100644 ios/RNMBX/RNMBXImagesComponentView.h create mode 100644 ios/RNMBX/RNMBXImagesComponentView.mm rename ios/RNMBX/{RNMBXImagesManager.m => RNMBXImagesViewManager.m} (70%) rename ios/RNMBX/{RNMBXImagesManager.swift => RNMBXImagesViewManager.swift} (72%) create mode 100644 ios/RNMBX/RNMBXLightComponentView.h create mode 100644 ios/RNMBX/RNMBXLightComponentView.mm rename ios/RNMBX/{RNMBXLightManager.m => RNMBXLightViewManager.m} (62%) rename ios/RNMBX/{RNMBXLightManager.swift => RNMBXLightViewManager.swift} (75%) create mode 100644 ios/RNMBX/RNMBXNativeUserLocationComponentView.h create mode 100644 ios/RNMBX/RNMBXNativeUserLocationComponentView.mm rename ios/RNMBX/{RNMBXNativeUserLocationManager.m => RNMBXNativeUserLocationViewManager.m} (55%) rename ios/RNMBX/{RNMBXNativeUserLocationManager.swift => RNMBXNativeUserLocationViewManager.swift} (62%) create mode 100644 ios/RNMBX/RNMBXTerrainComponentView.h create mode 100644 ios/RNMBX/RNMBXTerrainComponentView.mm rename ios/RNMBX/{RNMBXTerrainManager.m => RNMBXTerrainViewManager.m} (74%) rename ios/RNMBX/{RNMBXTerrainManager.swift => RNMBXTerrainViewManager.swift} (74%) diff --git a/fabricexample/ios/Podfile.lock b/fabricexample/ios/Podfile.lock index 26be5ba9e..e431d8e4e 100644 --- a/fabricexample/ios/Podfile.lock +++ b/fabricexample/ios/Podfile.lock @@ -8,12 +8,12 @@ PODS: - hermes-engine/Pre-built (= 0.72.4) - hermes-engine/Pre-built (0.72.4) - libevent (2.1.12) - - MapboxCommon (23.8.0) - - MapboxCoreMaps (10.16.0): + - MapboxCommon (23.8.3) + - MapboxCoreMaps (10.16.1): - MapboxCommon (~> 23.8) - - MapboxMaps (10.16.0): - - MapboxCommon (= 23.8.0) - - MapboxCoreMaps (= 10.16.0) + - MapboxMaps (10.16.1): + - MapboxCommon (= 23.8.3) + - MapboxCoreMaps (= 10.16.1) - MapboxMobileEvents (= 1.0.10) - Turf (~> 2.0) - MapboxMobileEvents (1.0.10) @@ -1074,23 +1074,27 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - rnmapbox-maps (10.1.0-beta.9): - - MapboxMaps (~> 10.16.0) + - rnmapbox-maps (10.1.0-beta.14): + - MapboxMaps (~> 10.16.1) - React - React-Core - - rnmapbox-maps/DynamicLibrary (= 10.1.0-beta.9) + - rnmapbox-maps/DynamicLibrary (= 10.1.0-beta.14) - Turf - - rnmapbox-maps/DynamicLibrary (10.1.0-beta.9): - - MapboxMaps (~> 10.16.0) + - rnmapbox-maps/DynamicLibrary (10.1.0-beta.14): + - hermes-engine + - MapboxMaps (~> 10.16.1) - RCT-Folly - RCTRequired - RCTTypeSafety - React - React-Codegen - React-Core + - React-NativeModulesApple - React-RCTFabric + - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Turf + - Yoga - RNScreens (3.25.0): - RCT-Folly - RCTRequired @@ -1158,7 +1162,7 @@ PODS: - ReactCommon/turbomodule/core - Yoga - SocketRocket (0.6.1) - - Turf (2.6.1) + - Turf (2.7.0) - Yoga (1.14.0) DEPENDENCIES: @@ -1332,9 +1336,9 @@ SPEC CHECKSUMS: glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 81191603c4eaa01f5e4ae5737a9efcf64756c7b2 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 - MapboxCommon: 8592a003eae487508461d452d62cfc5906a9682a - MapboxCoreMaps: faa14a797417dc32088c98019a3ce72e46cda5cd - MapboxMaps: f10aecadbfb7cf96368852ca313101eb4171da53 + MapboxCommon: b2c348867dfed7d7a23545e6c2024d712bfda10f + MapboxCoreMaps: c66f482b5ea983cf873122853c4ee94c159bec43 + MapboxMaps: fdbe05e3899abd24f31a7f91789586e44e57f7fc MapboxMobileEvents: de50b3a4de180dd129c326e09cd12c8adaaa46d6 RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: c0569ecc035894e4a68baecb30fe6a7ea6e399f9 @@ -1374,12 +1378,12 @@ SPEC CHECKSUMS: React-utils: b79f2411931f9d3ea5781404dcbb2fa8a837e13a ReactCommon: 4b2bdcb50a3543e1c2b2849ad44533686610826d RNCAsyncStorage: 2b77010cff31de7199eb7f65c59ae35abf9970b1 - rnmapbox-maps: efdc7b17ad07f7e077f56b1ad06e474ea6293db2 + rnmapbox-maps: 04deea8b9ece57dc06b7f31acf9085c47f65d06a RNScreens: cba72a26a6c967765a8388fe85f78e7771012ca1 RNSVG: df9aaada196f6a61c8e30dc55d41e6c108a954e7 RNVectorIcons: 61c44830bebe662f0bcb40aad2e6a31a34c8d8ba SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - Turf: 469ce2c3d22e5e8e4818d5a3b254699a5c89efa4 + Turf: 13d1a92d969ca0311bbc26e8356cca178ce95da2 Yoga: 3efc43e0d48686ce2e8c60f99d4e6bd349aff981 PODFILE CHECKSUM: ddac4d16bae15c3a589d18f707074a66b448710a diff --git a/ios/RNMBX/RNMBXImage.swift b/ios/RNMBX/RNMBXImage.swift index 1f091b908..637f336ed 100644 --- a/ios/RNMBX/RNMBXImage.swift +++ b/ios/RNMBX/RNMBXImage.swift @@ -1,38 +1,38 @@ import MapboxMaps -class RNMBXImage : UIView { +public class RNMBXImage : UIView { @objc - var name: String = "" { + public var name: String = "" { didSet { _addImageToStyle() } } - var image: UIImage? = nil + @objc public var image: UIImage? = nil @objc - var sdf: Bool = false { + public var sdf: Bool = false { didSet { _addImageToStyle() } } @objc - var stretchX: [[NSNumber]] = [] { + public var stretchX: [[NSNumber]] = [] { didSet { _addImageToStyle() } } @objc - var stretchY: [[NSNumber]] = [] { + public var stretchY: [[NSNumber]] = [] { didSet { _addImageToStyle() } } @objc - var content: [NSNumber]? = nil { + public var content: [NSNumber]? = nil { didSet { _addImageToStyle() } @@ -43,28 +43,36 @@ class RNMBXImage : UIView { DispatchQueue.main.async { self.setImage() } } } - weak var bridge : RCTBridge! = nil - var reactSubviews : [UIView] = [] + var reactSubviews : [UIView] = [] // MARK: - subview management - @objc open override func insertReactSubview(_ subview: UIView!, at atIndex: Int) { - reactSubviews.insert(subview, at: atIndex) - if reactSubviews.count > 1 { - Logger.log(level: .error, message: "Image supports max 1 subview") - } - if image == nil { - DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(10)) { - self.setImage() + public override func insertReactSubview(_ subview: UIView!, at atIndex: Int) { + insertReactSubviewInternal(subview, at: atIndex) + } + + @objc public func insertReactSubviewInternal(_ subview: UIView!, at atIndex: Int) { + reactSubviews.insert(subview, at: atIndex) + if reactSubviews.count > 1 { + Logger.log(level: .error, message: "Image supports max 1 subview") + } + if image == nil { + DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(10)) { + self.setImage() + } } } - } - @objc - open override func removeReactSubview(_ subview: UIView!) { - reactSubviews.removeAll(where: { $0 == subview }) + + public override func removeReactSubview(_ subview: UIView!) { + removeReactSubviewInternal(subview) } + + @objc + open func removeReactSubviewInternal(_ subview: UIView!) { + reactSubviews.removeAll(where: { $0 == subview }) + } // MARK: - view shnapshot @@ -79,7 +87,7 @@ class RNMBXImage : UIView { _addImageToStyle() } - func setImage() { + @objc public func setImage() { if let image = _createViewSnapshot() { changeImage(image, name: name) } diff --git a/ios/RNMBX/RNMBXImageComponentView.h b/ios/RNMBX/RNMBXImageComponentView.h new file mode 100644 index 000000000..1df136363 --- /dev/null +++ b/ios/RNMBX/RNMBXImageComponentView.h @@ -0,0 +1,15 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNMBXImageComponentView : RCTViewComponentView +@end + +NS_ASSUME_NONNULL_END + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXImageComponentView.mm b/ios/RNMBX/RNMBXImageComponentView.mm new file mode 100644 index 000000000..83b0f73b5 --- /dev/null +++ b/ios/RNMBX/RNMBXImageComponentView.mm @@ -0,0 +1,100 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import "RNMBXImageComponentView.h" +#import "RNMBXFabricHelpers.h" + +#import +#import + +#import +#import +#import +#import + +using namespace facebook::react; + +@interface RNMBXImageComponentView () +@end + +@implementation RNMBXImageComponentView { + RNMBXImage *_view; +} + + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + [self prepareView]; + } + + return self; + } + +- (void)prepareView +{ + _view = [[RNMBXImage alloc] init]; + self.contentView = _view; +} + +- (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + if ([childComponentView isKindOfClass:[RCTViewComponentView class]] && ((RCTViewComponentView *)childComponentView).contentView != nil) { + [_view insertReactSubviewInternal:((RCTViewComponentView *)childComponentView).contentView at:index]; + } else { + [_view insertReactSubviewInternal:childComponentView at:index]; + } +} + +- (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + if ([childComponentView isKindOfClass:[RCTViewComponentView class]] && ((RCTViewComponentView *)childComponentView).contentView != nil) { + [_view removeReactSubviewInternal:((RCTViewComponentView *)childComponentView).contentView]; + } else { + [_view removeReactSubviewInternal:childComponentView]; + } +} + +#pragma mark - RCTComponentViewProtocol + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps +{ + const auto &newProps = *std::static_pointer_cast(props); + id stretchX = RNMBXConvertFollyDynamicToId(newProps.stretchX); + if (stretchX != nil) { + _view.stretchX = stretchX; + } + id stretchY = RNMBXConvertFollyDynamicToId(newProps.stretchY); + if (stretchY != nil) { + _view.stretchY = stretchY; + } + id content = RNMBXConvertFollyDynamicToId(newProps.content); + if (content != nil) { + _view.content = content; + } + id sdf = RNMBXConvertFollyDynamicToId(newProps.sdf); + if (sdf != nil) { + _view.sdf = sdf; + } + id name = RNMBXConvertFollyDynamicToId(newProps.name); + if (name != nil) { + _view.name = name; + } + + [super updateProps:props oldProps:oldProps]; +} + +@end + +Class RNMBXImageCls(void) +{ + return RNMBXImageComponentView.class; +} + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXImageManager.swift b/ios/RNMBX/RNMBXImageManager.swift index beee9396f..6917e1262 100644 --- a/ios/RNMBX/RNMBXImageManager.swift +++ b/ios/RNMBX/RNMBXImageManager.swift @@ -8,7 +8,6 @@ class RNMBXImageManager : RCTViewManager { override func view() -> UIView! { let layer = RNMBXImage() - layer.bridge = self.bridge return layer } } diff --git a/ios/RNMBX/RNMBXImages.swift b/ios/RNMBX/RNMBXImages.swift index a3779c5c6..04aeb69af 100644 --- a/ios/RNMBX/RNMBXImages.swift +++ b/ios/RNMBX/RNMBXImages.swift @@ -4,29 +4,17 @@ protocol RNMBXImageSetter : AnyObject { func addImage(name: String, image: UIImage, sdf: Bool?, stretchX: [[NSNumber]], stretchY: [[NSNumber]], content: [NSNumber]?, log: String) -> Bool } -func hasImage(style: Style, name: String) -> Bool { - #if RNMBX_11 - return style.imageExists(withId: name) - #else - return (style.styleManager.getStyleImage(forImageId: name) != nil) - #endif -} - -#if RNMBX_11 -typealias StyleImageMissingPayload = StyleImageMissing -#endif - -class RNMBXImages : UIView, RNMBXMapComponent { +open class RNMBXImages : UIView, RNMBXMapComponent { - weak var bridge : RCTBridge! = nil + @objc public weak var bridge : RCTBridge! = nil weak var style: Style? = nil @objc - var onImageMissing: RCTBubblingEventBlock? = nil + public var onImageMissing: RCTBubblingEventBlock? = nil @objc - var images : [String:Any] = [:] { + public var images : [String:Any] = [:] { didSet { updateImages(images: images, oldImages: oldValue) } @@ -37,7 +25,7 @@ class RNMBXImages : UIView, RNMBXMapComponent { var imageViews: [RNMBXImage] = [] @objc - var nativeImages: [Any] = [] { + public var nativeImages: [Any] = [] { didSet { nativeImageInfos = nativeImages.compactMap { decodeImage($0) } } @@ -116,7 +104,7 @@ class RNMBXImages : UIView, RNMBXMapComponent { if !sameImage(oldValue: oldImages[name], newValue: images[name]) { missingImages[name] = images[name] } else { - if !hasImage(style: style, name: name) { + if style.styleManager.getStyleImage(forImageId: name) == nil { logged("RNMBXImages.addImagePlaceholder") { try? style.addImage(placeholderImage, id: name, stretchX: [], stretchY: []) missingImages[name] = images[name] @@ -243,7 +231,7 @@ class RNMBXImages : UIView, RNMBXMapComponent { func addNativeImages(style: Style, nativeImages: [NativeImageInfo]) { for imageInfo in nativeImages { let imageName = imageInfo.name - if !hasImage(style: style, name: imageInfo.name) { + if style.styleManager.getStyleImage(forImageId: imageInfo.name) == nil { if let image = UIImage(named: imageName) { logged("RNMBXImage.addNativeImage: \(imageName)") { try style.addImage(image, id: imageName, sdf: imageInfo.sdf, diff --git a/ios/RNMBX/RNMBXImagesComponentView.h b/ios/RNMBX/RNMBXImagesComponentView.h new file mode 100644 index 000000000..5e3a9e820 --- /dev/null +++ b/ios/RNMBX/RNMBXImagesComponentView.h @@ -0,0 +1,15 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNMBXImagesComponentView : RCTViewComponentView +@end + +NS_ASSUME_NONNULL_END + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXImagesComponentView.mm b/ios/RNMBX/RNMBXImagesComponentView.mm new file mode 100644 index 000000000..6a3fe5e5c --- /dev/null +++ b/ios/RNMBX/RNMBXImagesComponentView.mm @@ -0,0 +1,91 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import "RNMBXImagesComponentView.h" +#import "RNMBXFabricHelpers.h" + +#import +#import +#import + +#import +#import +#import +#import + +using namespace facebook::react; + +@interface RNMBXImagesComponentView () +@end + +@implementation RNMBXImagesComponentView { + RNMBXImages *_view; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + [self prepareView]; + } + + return self; +} + +- (void)prepareView +{ + _view = [[RNMBXImages alloc] init]; + _view.bridge = [RCTBridge currentBridge]; + + // capture weak self reference to prevent retain cycle + __weak __typeof__(self) weakSelf = self; + + [_view setOnImageMissing:^(NSDictionary* event) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf != nullptr && strongSelf->_eventEmitter != nullptr) { + std::string type = [event valueForKey:@"type"] == nil ? "" : std::string([[event valueForKey:@"type"] UTF8String]); + std::string imageKey = (![[event valueForKey:@"payload"] isKindOfClass:[NSDictionary class]] || ![[[event valueForKey:@"payload"] valueForKey:@"imageKey"] isKindOfClass:[NSString class]]) ? "" : std::string([((NSDictionary *)event[@"payload"])[@"imageKey"] UTF8String]); + facebook::react::RNMBXImagesEventEmitter::OnImageMissingPayload payload = {.imageKey = imageKey}; + std::dynamic_pointer_cast(strongSelf->_eventEmitter)->onImageMissing({type, payload}); + } + }]; + self.contentView = _view; +} + +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + [self prepareView]; +} + +#pragma mark - RCTComponentViewProtocol + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps +{ + const auto &newProps = *std::static_pointer_cast(props); + id images = RNMBXConvertFollyDynamicToId(newProps.images); + if (images != nil) { + _view.images = images; + } + id nativeImages = RNMBXConvertFollyDynamicToId(newProps.nativeImages); + if (nativeImages != nil) { + _view.nativeImages = nativeImages; + } + + [super updateProps:props oldProps:oldProps]; +} + +@end + +Class RNMBXImagesCls(void) +{ + return RNMBXImagesComponentView.class; +} + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXImagesManager.m b/ios/RNMBX/RNMBXImagesViewManager.m similarity index 70% rename from ios/RNMBX/RNMBXImagesManager.m rename to ios/RNMBX/RNMBXImagesViewManager.m index 382153afc..e6034b4d2 100644 --- a/ios/RNMBX/RNMBXImagesManager.m +++ b/ios/RNMBX/RNMBXImagesViewManager.m @@ -1,9 +1,8 @@ #import #import -@interface RCT_EXTERN_MODULE(RNMBXImagesManager, RCTViewManager) +@interface RCT_EXTERN_REMAP_MODULE(RNMBXImages, RNMBXImagesViewManager, RCTViewManager) -RCT_EXPORT_VIEW_PROPERTY(id, NSString) RCT_EXPORT_VIEW_PROPERTY(images, NSDictionary) RCT_EXPORT_VIEW_PROPERTY(nativeImages, NSArray) RCT_REMAP_VIEW_PROPERTY(onImageMissing, onImageMissing, RCTBubblingEventBlock) diff --git a/ios/RNMBX/RNMBXImagesManager.swift b/ios/RNMBX/RNMBXImagesViewManager.swift similarity index 72% rename from ios/RNMBX/RNMBXImagesManager.swift rename to ios/RNMBX/RNMBXImagesViewManager.swift index ac97c6ca1..611c9f2ed 100644 --- a/ios/RNMBX/RNMBXImagesManager.swift +++ b/ios/RNMBX/RNMBXImagesViewManager.swift @@ -1,6 +1,6 @@ -@objc(RNMBXImagesManager) -class RNMBXImagesManager : RCTViewManager { +@objc(RNMBXImagesViewManager) +class RNMBXImagesViewManager : RCTViewManager { @objc override static func requiresMainQueueSetup() -> Bool { return true diff --git a/ios/RNMBX/RNMBXLight.swift b/ios/RNMBX/RNMBXLight.swift index 01a11ee6a..a18e672ab 100644 --- a/ios/RNMBX/RNMBXLight.swift +++ b/ios/RNMBX/RNMBXLight.swift @@ -1,15 +1,11 @@ -@_spi(Experimental) import MapboxMaps - -#if RNMBX_11 -typealias Light = FlatLight -#endif +import MapboxMaps @objc(RNMBXLight) -class RNMBXLight: UIView, RNMBXMapComponent { - weak var bridge : RCTBridge! = nil +public class RNMBXLight: UIView, RNMBXMapComponent { + @objc public weak var bridge : RCTBridge! = nil weak var map: MapboxMap! = nil var oldReactStyle: [String:Any]? - @objc var reactStyle : [String:Any]! = nil { + @objc public var reactStyle : [String:Any]! = nil { willSet { oldReactStyle = reactStyle } @@ -21,15 +17,9 @@ class RNMBXLight: UIView, RNMBXMapComponent { } func apply(light: Light) { - logged("RNMBXLight.apply") { -#if RNMBX_11 - try self.map.setLights(light) -#else - let lightData = try JSONEncoder().encode(light) - let lightDictionary = try JSONSerialization.jsonObject(with: lightData) - try self.map.style.setLight(properties: lightDictionary as! [String:Any]) -#endif - } + let lightData = try! JSONEncoder().encode(light) + let lightDictionary = try! JSONSerialization.jsonObject(with: lightData) + try! self.map.style.setLight(properties: lightDictionary as! [String:Any]) } func addStyles() { diff --git a/ios/RNMBX/RNMBXLightComponentView.h b/ios/RNMBX/RNMBXLightComponentView.h new file mode 100644 index 000000000..f8551fba5 --- /dev/null +++ b/ios/RNMBX/RNMBXLightComponentView.h @@ -0,0 +1,15 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNMBXLightComponentView : RCTViewComponentView +@end + +NS_ASSUME_NONNULL_END + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXLightComponentView.mm b/ios/RNMBX/RNMBXLightComponentView.mm new file mode 100644 index 000000000..b0cec9cb5 --- /dev/null +++ b/ios/RNMBX/RNMBXLightComponentView.mm @@ -0,0 +1,68 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import "RNMBXLightComponentView.h" +#import "RNMBXFabricHelpers.h" + +#import +#import +#import + +#import +#import +#import +#import + +using namespace facebook::react; + +@interface RNMBXLightComponentView () +@end + +@implementation RNMBXLightComponentView { + RNMBXLight *_view; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + [self prepareView]; + } + + return self; + } + +- (void)prepareView +{ + _view = [[RNMBXLight alloc] init]; + _view.bridge = [RCTBridge currentBridge]; + self.contentView = _view; +} + +#pragma mark - RCTComponentViewProtocol + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + + +- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps +{ + const auto &newProps = *std::static_pointer_cast(props); + id reactStyle = RNMBXConvertFollyDynamicToId(newProps.reactStyle); + if (reactStyle != nil) { + _view.reactStyle = reactStyle; + } + + [super updateProps:props oldProps:oldProps]; +} + +@end + +Class RNMBXLightCls(void) +{ + return RNMBXLightComponentView.class; +} + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXLightManager.m b/ios/RNMBX/RNMBXLightViewManager.m similarity index 62% rename from ios/RNMBX/RNMBXLightManager.m rename to ios/RNMBX/RNMBXLightViewManager.m index d7f3536ec..0e76abe43 100644 --- a/ios/RNMBX/RNMBXLightManager.m +++ b/ios/RNMBX/RNMBXLightViewManager.m @@ -1,7 +1,7 @@ #import #import -@interface RCT_EXTERN_MODULE(RNMBXLightManager, RCTViewManager) +@interface RCT_EXTERN_REMAP_MODULE(RNMBXLight, RNMBXLightViewManager, RCTViewManager) // light props RCT_EXPORT_VIEW_PROPERTY(reactStyle, NSDictionary); diff --git a/ios/RNMBX/RNMBXLightManager.swift b/ios/RNMBX/RNMBXLightViewManager.swift similarity index 75% rename from ios/RNMBX/RNMBXLightManager.swift rename to ios/RNMBX/RNMBXLightViewManager.swift index 75674af9b..3c3242f07 100644 --- a/ios/RNMBX/RNMBXLightManager.swift +++ b/ios/RNMBX/RNMBXLightViewManager.swift @@ -1,5 +1,5 @@ -@objc(RNMBXLightManager) -class RNMBXLightManager: RCTViewManager { +@objc(RNMBXLightViewManager) +class RNMBXLightViewManager: RCTViewManager { @objc override static func requiresMainQueueSetup() -> Bool { return true diff --git a/ios/RNMBX/RNMBXNativeUserLocation.swift b/ios/RNMBX/RNMBXNativeUserLocation.swift index 74870abaa..0e052b24f 100644 --- a/ios/RNMBX/RNMBXNativeUserLocation.swift +++ b/ios/RNMBX/RNMBXNativeUserLocation.swift @@ -1,7 +1,7 @@ import MapboxMaps @objc -class RNMBXNativeUserLocation : UIView, RNMBXMapComponent { +public class RNMBXNativeUserLocation : UIView, RNMBXMapComponent { weak var map : RNMBXMapView! = nil let locationLayerId = "location-layer" @@ -9,7 +9,7 @@ class RNMBXNativeUserLocation : UIView, RNMBXMapComponent { var locationLayer : LocationIndicatorLayer? = nil @objc - var iosShowsUserHeadingIndicator : Bool = false { + public var iosShowsUserHeadingIndicator : Bool = false { didSet { if let map = self.map { _applySettings(map) } } @@ -18,11 +18,7 @@ class RNMBXNativeUserLocation : UIView, RNMBXMapComponent { func _applySettings(_ map: RNMBXMapView) { map.location.options.puckType = .puck2D(.makeDefault(showBearing: iosShowsUserHeadingIndicator)) if (iosShowsUserHeadingIndicator) { - #if RNMBX_11 - map.location.options.puckBearing = .heading - #else map.location.options.puckBearingSource = .heading - #endif map.location.options.puckBearingEnabled = true } else { map.location.options.puckBearingEnabled = false diff --git a/ios/RNMBX/RNMBXNativeUserLocationComponentView.h b/ios/RNMBX/RNMBXNativeUserLocationComponentView.h new file mode 100644 index 000000000..5cf697993 --- /dev/null +++ b/ios/RNMBX/RNMBXNativeUserLocationComponentView.h @@ -0,0 +1,15 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNMBXNativeUserLocationComponentView : RCTViewComponentView +@end + +NS_ASSUME_NONNULL_END + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXNativeUserLocationComponentView.mm b/ios/RNMBX/RNMBXNativeUserLocationComponentView.mm new file mode 100644 index 000000000..daa5f7979 --- /dev/null +++ b/ios/RNMBX/RNMBXNativeUserLocationComponentView.mm @@ -0,0 +1,72 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import "RNMBXNativeUserLocationComponentView.h" +#import "RNMBXFabricHelpers.h" + +#import +#import + +#import +#import +#import +#import + +using namespace facebook::react; + +@interface RNMBXNativeUserLocationComponentView () +@end + +@implementation RNMBXNativeUserLocationComponentView { + RNMBXNativeUserLocation *_view; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + [self prepareView]; + } + + return self; + } + +- (void)prepareView +{ + _view = [[RNMBXNativeUserLocation alloc] init]; + self.contentView = _view; +} + + +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + [self prepareView]; +} + +#pragma mark - RCTComponentViewProtocol + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps +{ + const auto &newProps = *std::static_pointer_cast(props); + id iosShowsUserHeadingIndicator = RNMBXConvertFollyDynamicToId(newProps.iosShowsUserHeadingIndicator); + if (iosShowsUserHeadingIndicator != nil) { + _view.iosShowsUserHeadingIndicator = iosShowsUserHeadingIndicator; + } + + [super updateProps:props oldProps:oldProps]; +} + +@end + +Class RNMBXNativeUserLocationCls(void) +{ + return RNMBXNativeUserLocationComponentView.class; +} + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXNativeUserLocationManager.m b/ios/RNMBX/RNMBXNativeUserLocationViewManager.m similarity index 55% rename from ios/RNMBX/RNMBXNativeUserLocationManager.m rename to ios/RNMBX/RNMBXNativeUserLocationViewManager.m index dd5f2d42a..8dc6c6711 100644 --- a/ios/RNMBX/RNMBXNativeUserLocationManager.m +++ b/ios/RNMBX/RNMBXNativeUserLocationViewManager.m @@ -1,7 +1,7 @@ #import #import -@interface RCT_EXTERN_MODULE(RNMBXNativeUserLocationManager, RCTViewManager) +@interface RCT_EXTERN_REMAP_MODULE(RNMBXNativeUserLocation, RNMBXNativeUserLocationViewManager, RCTViewManager) RCT_EXPORT_VIEW_PROPERTY(iosShowsUserHeadingIndicator, BOOL); diff --git a/ios/RNMBX/RNMBXNativeUserLocationManager.swift b/ios/RNMBX/RNMBXNativeUserLocationViewManager.swift similarity index 62% rename from ios/RNMBX/RNMBXNativeUserLocationManager.swift rename to ios/RNMBX/RNMBXNativeUserLocationViewManager.swift index b6dd9b603..f67f1eb67 100644 --- a/ios/RNMBX/RNMBXNativeUserLocationManager.swift +++ b/ios/RNMBX/RNMBXNativeUserLocationViewManager.swift @@ -1,5 +1,5 @@ -@objc(RNMBXNativeUserLocationManager) -class RNMBXNativeUserLocationManager : RCTViewManager { +@objc(RNMBXNativeUserLocationViewManager) +class RNMBXNativeUserLocationViewManager : RCTViewManager { @objc override static func requiresMainQueueSetup() -> Bool { return true diff --git a/ios/RNMBX/RNMBXSingletonLayer.swift b/ios/RNMBX/RNMBXSingletonLayer.swift index 61103adc4..f34015764 100644 --- a/ios/RNMBX/RNMBXSingletonLayer.swift +++ b/ios/RNMBX/RNMBXSingletonLayer.swift @@ -3,7 +3,7 @@ import MapboxMaps /// RNMBXSingletonLayer is absract superclass for Light, Atmosphere, Terrain @objc public class RNMBXSingletonLayer : UIView { - weak var bridge : RCTBridge? = nil + @objc public weak var bridge : RCTBridge? = nil weak var map : RNMBXMapView? = nil var style: Style? = nil diff --git a/ios/RNMBX/RNMBXTerrain.swift b/ios/RNMBX/RNMBXTerrain.swift index 03bebd53f..a05e26f68 100644 --- a/ios/RNMBX/RNMBXTerrain.swift +++ b/ios/RNMBX/RNMBXTerrain.swift @@ -1,7 +1,7 @@ import MapboxMaps @objc -class RNMBXTerrain : RNMBXSingletonLayer, RNMBXMapComponent, RNMBXSourceConsumer { +public class RNMBXTerrain : RNMBXSingletonLayer, RNMBXMapComponent, RNMBXSourceConsumer { var terrain : Terrain? = nil func makeTerrain() -> Terrain { @@ -44,7 +44,7 @@ class RNMBXTerrain : RNMBXSingletonLayer, RNMBXMapComponent, RNMBXSourceConsumer } } - @objc var sourceID: String? = nil { + @objc public var sourceID: String? = nil { didSet { guard let sourceID = sourceID else { Logger.log(level: .error, message: "RNMBXTerrain cannot set source to nil") diff --git a/ios/RNMBX/RNMBXTerrainComponentView.h b/ios/RNMBX/RNMBXTerrainComponentView.h new file mode 100644 index 000000000..f2602ed33 --- /dev/null +++ b/ios/RNMBX/RNMBXTerrainComponentView.h @@ -0,0 +1,15 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNMBXTerrainComponentView : RCTViewComponentView +@end + +NS_ASSUME_NONNULL_END + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXTerrainComponentView.mm b/ios/RNMBX/RNMBXTerrainComponentView.mm new file mode 100644 index 000000000..3b2330195 --- /dev/null +++ b/ios/RNMBX/RNMBXTerrainComponentView.mm @@ -0,0 +1,78 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#import "RNMBXTerrainComponentView.h" +#import "RNMBXFabricHelpers.h" + +#import +#import +#import + +#import +#import +#import +#import + +using namespace facebook::react; + +@interface RNMBXTerrainComponentView () +@end + +@implementation RNMBXTerrainComponentView { + RNMBXTerrain *_view; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + [self prepareView]; + } + + return self; + } + +- (void)prepareView +{ + _view = [[RNMBXTerrain alloc] init]; + _view.bridge = [RCTBridge currentBridge]; + self.contentView = _view; +} + +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + [self prepareView]; +} + +#pragma mark - RCTComponentViewProtocol + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps +{ + const auto &newProps = *std::static_pointer_cast(props); + + id sourceID = RNMBXConvertFollyDynamicToId(newProps.sourceID); + if (sourceID != nil) { + _view.sourceID = sourceID; + } + id reactStyle = RNMBXConvertFollyDynamicToId(newProps.reactStyle); + if (reactStyle != nil) { + _view.reactStyle = reactStyle; + } + + [super updateProps:props oldProps:oldProps]; +} + +@end + +Class RNMBXTerrainCls(void) +{ + return RNMBXTerrainComponentView.class; +} + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/RNMBX/RNMBXTerrainManager.m b/ios/RNMBX/RNMBXTerrainViewManager.m similarity index 74% rename from ios/RNMBX/RNMBXTerrainManager.m rename to ios/RNMBX/RNMBXTerrainViewManager.m index aece5b067..359ed8423 100644 --- a/ios/RNMBX/RNMBXTerrainManager.m +++ b/ios/RNMBX/RNMBXTerrainViewManager.m @@ -6,7 +6,7 @@ @interface RNMBXTerrain : UIView @property (nonatomic) NSObject* exaggeration; @end -@interface RCT_EXTERN_MODULE(RNMBXTerrainManager, RCTViewManager) +@interface RCT_EXTERN_REMAP_MODULE(RNMBXTerrain, RNMBXTerrainViewManager, RCTViewManager) RCT_EXPORT_VIEW_PROPERTY(sourceID, NSString); diff --git a/ios/RNMBX/RNMBXTerrainManager.swift b/ios/RNMBX/RNMBXTerrainViewManager.swift similarity index 74% rename from ios/RNMBX/RNMBXTerrainManager.swift rename to ios/RNMBX/RNMBXTerrainViewManager.swift index 946ca19dc..8c589086d 100644 --- a/ios/RNMBX/RNMBXTerrainManager.swift +++ b/ios/RNMBX/RNMBXTerrainViewManager.swift @@ -1,5 +1,5 @@ -@objc(RNMBXTerrainManager) -class RNMBXTerrainManager: RCTViewManager { +@objc(RNMBXTerrainViewManager) +class RNMBXTerrainViewManager: RCTViewManager { @objc override static func requiresMainQueueSetup() -> Bool { return true From d1aadf089f8d6e7691a8fd6c3fcc57dd949120d8 Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Tue, 24 Oct 2023 18:22:56 +0200 Subject: [PATCH 4/5] fix: remove mapFeature and duplicate manager --- ios/RNMBX/RNMBXCircleLayerManager.m | 12 ------------ ios/RNMBX/RNMBXCircleLayerManager.swift | 13 ------------- ios/RNMBX/RNMBXMapFeatureView.h | 7 ------- ios/RNMBX/RNMBXRasterDemSourceComponentView.h | 4 +--- ios/RNMBX/RNMBXRasterDemSourceComponentView.mm | 2 -- ios/RNMBX/RNMBXRasterSourceComponentView.h | 4 +--- ios/RNMBX/RNMBXRasterSourceComponentView.mm | 2 -- ios/RNMBX/RNMBXShapeSourceComponentView.h | 4 +--- ios/RNMBX/RNMBXShapeSourceComponentView.mm | 10 ++++------ ios/RNMBX/RNMBXVectorSourceComponentView.h | 4 +--- ios/RNMBX/RNMBXVectorSourceComponentView.mm | 2 -- 11 files changed, 8 insertions(+), 56 deletions(-) delete mode 100644 ios/RNMBX/RNMBXCircleLayerManager.m delete mode 100644 ios/RNMBX/RNMBXCircleLayerManager.swift delete mode 100644 ios/RNMBX/RNMBXMapFeatureView.h diff --git a/ios/RNMBX/RNMBXCircleLayerManager.m b/ios/RNMBX/RNMBXCircleLayerManager.m deleted file mode 100644 index 1710e07c5..000000000 --- a/ios/RNMBX/RNMBXCircleLayerManager.m +++ /dev/null @@ -1,12 +0,0 @@ -#import -#import - -@interface RCT_EXTERN_MODULE(RNMBXCircleLayerManager, RCTViewManager) - -// circle layer props -RCT_EXPORT_VIEW_PROPERTY(sourceLayerID, NSString) - -// standard layer props -#include "CommonLayerProperties.H" - -@end diff --git a/ios/RNMBX/RNMBXCircleLayerManager.swift b/ios/RNMBX/RNMBXCircleLayerManager.swift deleted file mode 100644 index 759a71880..000000000 --- a/ios/RNMBX/RNMBXCircleLayerManager.swift +++ /dev/null @@ -1,13 +0,0 @@ -@objc(RNMBXCircleLayerManager) -class RNMBXCircleLayerManager: RCTViewManager { - @objc - override static func requiresMainQueueSetup() -> Bool { - return true - } - - override func view() -> UIView! { - let layer = RNMBXCircleLayer() - layer.bridge = self.bridge - return layer - } -} diff --git a/ios/RNMBX/RNMBXMapFeatureView.h b/ios/RNMBX/RNMBXMapFeatureView.h deleted file mode 100644 index 7557faae5..000000000 --- a/ios/RNMBX/RNMBXMapFeatureView.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -@protocol RNMBXMapFeatureView - -@property (strong, nonatomic) UIView* mapFeature; - -@end diff --git a/ios/RNMBX/RNMBXRasterDemSourceComponentView.h b/ios/RNMBX/RNMBXRasterDemSourceComponentView.h index f1507163e..0d66f525c 100644 --- a/ios/RNMBX/RNMBXRasterDemSourceComponentView.h +++ b/ios/RNMBX/RNMBXRasterDemSourceComponentView.h @@ -5,11 +5,9 @@ #import #import -#import "RNMBXMapFeatureView.h" - NS_ASSUME_NONNULL_BEGIN -@interface RNMBXRasterDemSourceComponentView : RCTViewComponentView +@interface RNMBXRasterDemSourceComponentView : RCTViewComponentView @end NS_ASSUME_NONNULL_END diff --git a/ios/RNMBX/RNMBXRasterDemSourceComponentView.mm b/ios/RNMBX/RNMBXRasterDemSourceComponentView.mm index e76c8fe00..6469f7d0c 100644 --- a/ios/RNMBX/RNMBXRasterDemSourceComponentView.mm +++ b/ios/RNMBX/RNMBXRasterDemSourceComponentView.mm @@ -20,7 +20,6 @@ @implementation RNMBXRasterDemSourceComponentView { RNMBXRasterDemSource *_view; } -@synthesize mapFeature; - (instancetype)initWithFrame:(CGRect)frame { @@ -37,7 +36,6 @@ - (void)prepareView { _view = [[RNMBXRasterDemSource alloc] init]; self.contentView = _view; - self.mapFeature = _view; } - (void)prepareForRecycle diff --git a/ios/RNMBX/RNMBXRasterSourceComponentView.h b/ios/RNMBX/RNMBXRasterSourceComponentView.h index 4f5c370c0..0a482952b 100644 --- a/ios/RNMBX/RNMBXRasterSourceComponentView.h +++ b/ios/RNMBX/RNMBXRasterSourceComponentView.h @@ -5,11 +5,9 @@ #import #import -#import "RNMBXMapFeatureView.h" - NS_ASSUME_NONNULL_BEGIN -@interface RNMBXRasterSourceComponentView : RCTViewComponentView +@interface RNMBXRasterSourceComponentView : RCTViewComponentView @end NS_ASSUME_NONNULL_END diff --git a/ios/RNMBX/RNMBXRasterSourceComponentView.mm b/ios/RNMBX/RNMBXRasterSourceComponentView.mm index 6d180fba3..3fdba0e9f 100644 --- a/ios/RNMBX/RNMBXRasterSourceComponentView.mm +++ b/ios/RNMBX/RNMBXRasterSourceComponentView.mm @@ -20,7 +20,6 @@ @implementation RNMBXRasterSourceComponentView { RNMBXRasterSource *_view; } -@synthesize mapFeature; - (instancetype)initWithFrame:(CGRect)frame { @@ -37,7 +36,6 @@ - (void)prepareView { _view = [[RNMBXRasterSource alloc] init]; self.contentView = _view; - self.mapFeature = _view; } - (void)prepareForRecycle diff --git a/ios/RNMBX/RNMBXShapeSourceComponentView.h b/ios/RNMBX/RNMBXShapeSourceComponentView.h index 12535595a..fe2b39f9f 100644 --- a/ios/RNMBX/RNMBXShapeSourceComponentView.h +++ b/ios/RNMBX/RNMBXShapeSourceComponentView.h @@ -5,11 +5,9 @@ #import #import -#import "RNMBXMapFeatureView.h" - NS_ASSUME_NONNULL_BEGIN -@interface RNMBXShapeSourceComponentView : RCTViewComponentView +@interface RNMBXShapeSourceComponentView : RCTViewComponentView @end NS_ASSUME_NONNULL_END diff --git a/ios/RNMBX/RNMBXShapeSourceComponentView.mm b/ios/RNMBX/RNMBXShapeSourceComponentView.mm index 243229e2d..660f9ef7c 100644 --- a/ios/RNMBX/RNMBXShapeSourceComponentView.mm +++ b/ios/RNMBX/RNMBXShapeSourceComponentView.mm @@ -20,7 +20,6 @@ @implementation RNMBXShapeSourceComponentView { RNMBXShapeSource *_view; } -@synthesize mapFeature; - (instancetype)initWithFrame:(CGRect)frame { @@ -51,7 +50,6 @@ - (void)prepareView }]; self.contentView = _view; - self.mapFeature = _view; } - (void)prepareForRecycle @@ -62,19 +60,19 @@ - (void)prepareForRecycle - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - if ([childComponentView isKindOfClass:[RCTViewComponentView class]]) { + if ([childComponentView isKindOfClass:[RCTViewComponentView class]] && ((RCTViewComponentView *)childComponentView).contentView != nil) { [_view insertReactSubviewInternal:((RCTViewComponentView *)childComponentView).contentView at:index]; } else { - RCTLogError(@"Tried to add view that is not RCTViewComponentView: %@", childComponentView); + [_view insertReactSubviewInternal:childComponentView at:index]; } } - (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - if ([childComponentView isKindOfClass:[RCTViewComponentView class]]) { + if ([childComponentView isKindOfClass:[RCTViewComponentView class]] && ((RCTViewComponentView *)childComponentView).contentView != nil) { [_view removeReactSubviewInternal:((RCTViewComponentView *)childComponentView).contentView]; } else { - RCTLogError(@"Tried to remove view that is not RCTViewComponentView: %@", childComponentView); + [_view removeReactSubviewInternal:childComponentView]; } } diff --git a/ios/RNMBX/RNMBXVectorSourceComponentView.h b/ios/RNMBX/RNMBXVectorSourceComponentView.h index bb65b4dec..288256e97 100644 --- a/ios/RNMBX/RNMBXVectorSourceComponentView.h +++ b/ios/RNMBX/RNMBXVectorSourceComponentView.h @@ -5,11 +5,9 @@ #import #import -#import "RNMBXMapFeatureView.h" - NS_ASSUME_NONNULL_BEGIN -@interface RNMBXVectorSourceComponentView : RCTViewComponentView +@interface RNMBXVectorSourceComponentView : RCTViewComponentView @end NS_ASSUME_NONNULL_END diff --git a/ios/RNMBX/RNMBXVectorSourceComponentView.mm b/ios/RNMBX/RNMBXVectorSourceComponentView.mm index df70fb11a..8f6dfe4f7 100644 --- a/ios/RNMBX/RNMBXVectorSourceComponentView.mm +++ b/ios/RNMBX/RNMBXVectorSourceComponentView.mm @@ -20,7 +20,6 @@ @implementation RNMBXVectorSourceComponentView { RNMBXVectorSource *_view; } -@synthesize mapFeature; - (instancetype)initWithFrame:(CGRect)frame { @@ -50,7 +49,6 @@ - (void)prepareView }]; self.contentView = _view; - self.mapFeature = _view; } - (void)prepareForRecycle From 86ba47f89fb914ff26594db4e35d581140fa6468 Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Wed, 25 Oct 2023 15:26:24 +0200 Subject: [PATCH 5/5] feat: add Image module and fix tests --- .../java/com/rnmapbox/rnmbx/RNMBXPackage.kt | 11 +++ .../components/images/RNMBXImageManager.kt | 8 -- .../components/images/RNMBXImageModule.kt | 33 ++++++++ .../styles/terrain/RNMBXTerrainManager.kt | 6 -- .../rnmbx/NativeRNMBXImageModuleSpec.java | 40 ++++++++++ docs/Image.md | 11 +++ docs/docs.json | 10 ++- ios/RNMBX/RNMBXImageModule.h | 17 +++++ ios/RNMBX/RNMBXImageModule.mm | 75 +++++++++++++++++++ setup-jest.js | 4 + src/components/Image.tsx | 16 +++- src/components/Light.tsx | 2 +- src/specs/NativeRNMBXImageModule.ts | 10 +++ 13 files changed, 226 insertions(+), 17 deletions(-) create mode 100644 android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageModule.kt create mode 100644 android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXImageModuleSpec.java create mode 100644 ios/RNMBX/RNMBXImageModule.h create mode 100644 ios/RNMBX/RNMBXImageModule.mm create mode 100644 src/specs/NativeRNMBXImageModule.ts diff --git a/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt b/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt index 0506e169a..235fa22f1 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt @@ -12,6 +12,7 @@ import com.rnmapbox.rnmbx.components.annotation.RNMBXMarkerViewManager import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationManager import com.rnmapbox.rnmbx.components.camera.RNMBXCameraManager import com.rnmapbox.rnmbx.components.images.RNMBXImageManager +import com.rnmapbox.rnmbx.components.images.RNMBXImageModule import com.rnmapbox.rnmbx.components.images.RNMBXImagesManager import com.rnmapbox.rnmbx.components.location.RNMBXNativeUserLocationManager import com.rnmapbox.rnmbx.components.mapview.NativeMapViewModule @@ -69,6 +70,7 @@ class RNMBXPackage : TurboReactPackage() { RNMBXLogging.REACT_CLASS -> return RNMBXLogging(reactApplicationContext) NativeMapViewModule.NAME -> return NativeMapViewModule(reactApplicationContext, getViewTagResolver(reactApplicationContext)) RNMBXShapeSourceModule.NAME -> return RNMBXShapeSourceModule(reactApplicationContext, getViewTagResolver(reactApplicationContext)) + RNMBXImageModule.NAME -> return RNMBXImageModule(reactApplicationContext, getViewTagResolver(reactApplicationContext)) } return null } @@ -187,6 +189,15 @@ class RNMBXPackage : TurboReactPackage() { false, // isCxxModule isTurboModule // isTurboModule ) + moduleInfos[RNMBXImageModule.NAME] = ReactModuleInfo( + RNMBXImageModule.NAME, + RNMBXImageModule.NAME, + false, // canOverrideExistingModule + false, // needsEagerInit + false, // hasConstants + false, // isCxxModule + isTurboModule // isTurboModule + ) moduleInfos } } diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageManager.kt index fda0a1abb..e940b4472 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageManager.kt @@ -54,12 +54,4 @@ mContext image.scale = value.asDouble() } // endregion - - // region React methods - override fun receiveCommand(root: RNMBXImage, commandId: String?, args: ReadableArray?) { - if (commandId == "refresh") { - root.refresh() - } - } - // endregion } \ No newline at end of file diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageModule.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageModule.kt new file mode 100644 index 000000000..a9bcd6638 --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/images/RNMBXImageModule.kt @@ -0,0 +1,33 @@ +package com.rnmapbox.rnmbx.components.images + +import com.facebook.react.bridge.Promise +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactMethod +import com.facebook.react.module.annotations.ReactModule +import com.rnmapbox.rnmbx.NativeRNMBXImageModuleSpec +import com.rnmapbox.rnmbx.utils.ViewTagResolver + +@ReactModule(name = RNMBXImageModule.NAME) +class RNMBXImageModule(reactContext: ReactApplicationContext?, private val viewTagResolver: ViewTagResolver) : + NativeRNMBXImageModuleSpec(reactContext) { + + companion object { + const val NAME = "RNMBXImageModule" + } + + private fun withImageOnUIThread(viewRef: Double?, reject: Promise, fn: (RNMBXImage) -> Unit) { + if (viewRef == null) { + reject.reject(Exception("viewRef is null for RNMBXImage")) + } else { + viewTagResolver.withViewResolved(viewRef.toInt(), reject, fn) + } + } + + @ReactMethod + override fun refresh(viewRef: Double?, promise: Promise) { + withImageOnUIThread(viewRef, promise) { + it.refresh() + promise.resolve(null) + } + } +} \ No newline at end of file diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/terrain/RNMBXTerrainManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/terrain/RNMBXTerrainManager.kt index 79d1da82b..02a436f8a 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/terrain/RNMBXTerrainManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/terrain/RNMBXTerrainManager.kt @@ -16,12 +16,6 @@ class RNMBXTerrainManager : ViewGroupManager(), return RNMBXTerrain(reactContext) } - // TODO: it is not present in props so should we add it? -// @ReactProp(name = "id") -// override fun setId(layer: RNMBXTerrain, id: Dynamic) { -// layer.iD = id.asString() -// } - @ReactProp(name = "sourceID") override fun setSourceID(layer: RNMBXTerrain, sourceID: Dynamic) { layer.setSourceID(sourceID.asString()) diff --git a/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXImageModuleSpec.java b/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXImageModuleSpec.java new file mode 100644 index 000000000..756e43661 --- /dev/null +++ b/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXImageModuleSpec.java @@ -0,0 +1,40 @@ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJavaSpec.js + * + * @nolint + */ + +package com.rnmapbox.rnmbx; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReactModuleWithSpec; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public abstract class NativeRNMBXImageModuleSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule { + public static final String NAME = "RNMBXImageModule"; + + public NativeRNMBXImageModuleSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public @Nonnull String getName() { + return NAME; + } + + @ReactMethod + @DoNotStrip + public abstract void refresh(@Nullable Double viewRef, Promise promise); +} diff --git a/docs/Image.md b/docs/Image.md index 0d321c14c..64fab69d8 100644 --- a/docs/Image.md +++ b/docs/Image.md @@ -85,4 +85,15 @@ Single react native view rendering the image +## methods +### refresh() + + + +#### arguments +| Name | Type | Required | Description | +| ---- | :--: | :------: | :----------: | + + + diff --git a/docs/docs.json b/docs/docs.json index 49bb7f469..b8ab4a1c6 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -2236,7 +2236,15 @@ "Image": { "description": "", "displayName": "Image", - "methods": [], + "methods": [ + { + "name": "refresh", + "docblock": null, + "modifiers": [], + "params": [], + "returns": null + } + ], "props": [ { "name": "name", diff --git a/ios/RNMBX/RNMBXImageModule.h b/ios/RNMBX/RNMBXImageModule.h new file mode 100644 index 000000000..af3b2a81e --- /dev/null +++ b/ios/RNMBX/RNMBXImageModule.h @@ -0,0 +1,17 @@ +#import +#import + +#ifdef RCT_NEW_ARCH_ENABLED +#import "rnmapbox_maps_specs.h" +#else +#import +#endif + +@interface RNMBXImageModule : NSObject +#ifdef RCT_NEW_ARCH_ENABLED + +#else + +#endif + +@end diff --git a/ios/RNMBX/RNMBXImageModule.mm b/ios/RNMBX/RNMBXImageModule.mm new file mode 100644 index 000000000..83e7dcbe3 --- /dev/null +++ b/ios/RNMBX/RNMBXImageModule.mm @@ -0,0 +1,75 @@ +#import +#import +#import + +#import "RNMBXImageModule.h" +#ifdef RCT_NEW_ARCH_ENABLED +#import "RNMBXImageComponentView.h" +#endif // RCT_NEW_ARCH_ENABLED + +// needed for compilation for some reason +#import +#import + +@interface MapView : UIView +@end + +#import + + +@implementation RNMBXImageModule + +RCT_EXPORT_MODULE(); + +#ifdef RCT_NEW_ARCH_ENABLED +@synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED; +#endif // RCT_NEW_ARCH_ENABLED +@synthesize bridge = _bridge; + +- (dispatch_queue_t)methodQueue +{ + // It seems that due to how UIBlocks work with uiManager, we need to call the methods there + // for the blocks to be dispatched before the batch is completed + return RCTGetUIManagerQueue(); +} + +- (void)withImage:(NSNumber*)viewRef block:(void (^)(RNMBXImage *))block reject:(RCTPromiseRejectBlock)reject methodName:(NSString *)methodName +{ +#ifdef RCT_NEW_ARCH_ENABLED + [self.viewRegistry_DEPRECATED addUIBlock:^(RCTViewRegistry *viewRegistry) { + RNMBXImageComponentView *componentView = [self.viewRegistry_DEPRECATED viewForReactTag:viewRef]; + RNMBXImage *view = componentView.contentView; + +#else + [self.bridge.uiManager + addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RNMBXImage *view = [uiManager viewForReactTag:viewRef]; +#endif // RCT_NEW_ARCH_ENABLED + if (view != nil) { + block(view); + } else { + reject(methodName, [NSString stringWithFormat:@"Unknown reactTag: %@", viewRef], nil); + } + }]; +} + + +RCT_EXPORT_METHOD(refresh:(NSNumber*)viewRef resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) +{ + [self withImage:viewRef block:^(RNMBXImage *view) { + // TODO: implement refresh on iOS +// [view refresh]; + } reject:reject methodName:@"refresh"]; +} + + +// Thanks to this guard, we won't compile this code when we build for the old architecture. +#ifdef RCT_NEW_ARCH_ENABLED +- (std::shared_ptr)getTurboModule: + (const facebook::react::ObjCTurboModule::InitParams &)params +{ + return std::make_shared(params); +} +#endif // RCT_NEW_ARCH_ENABLED + +@end diff --git a/setup-jest.js b/setup-jest.js index c95768141..0079aaf49 100644 --- a/setup-jest.js +++ b/setup-jest.js @@ -155,6 +155,10 @@ NativeModules.RNMBXShapeSourceModule = { getClusterChildren: jest.fn(), }; +NativeModules.RNMBXImageModule = { + refresh: jest.fn(), +}; + NativeModules.RNMBXLogging = nativeModule({}); // Mock for global AbortController diff --git a/src/components/Image.tsx b/src/components/Image.tsx index 4961b4306..adc84ea76 100644 --- a/src/components/Image.tsx +++ b/src/components/Image.tsx @@ -1,6 +1,8 @@ import React, { memo, forwardRef, ReactElement } from 'react'; +import { findNodeHandle } from 'react-native'; import RNMBXImageNativeComponent from '../specs/RNMBXImageNativeComponent'; +import NativeRNMBXImageModule from '../specs/NativeRNMBXImageModule'; interface Props { /** ID of the image */ @@ -43,8 +45,20 @@ const Image = memo( stretchY, children, }; + + const imageRef = React.useRef(null); + + const refresh = () => { + const handle = findNodeHandle(imageRef.current as any); + NativeRNMBXImageModule.refresh(handle); + }; + + React.useImperativeHandle(ref, () => { + return { refresh }; + }); + // @ts-expect-error just codegen stuff - return ; + return ; }), ); diff --git a/src/components/Light.tsx b/src/components/Light.tsx index dd91f6b1c..5b2694ef8 100644 --- a/src/components/Light.tsx +++ b/src/components/Light.tsx @@ -42,7 +42,7 @@ function Light(props: Props, ref: React.ForwardedRef) { diff --git a/src/specs/NativeRNMBXImageModule.ts b/src/specs/NativeRNMBXImageModule.ts new file mode 100644 index 000000000..19e0ddc4f --- /dev/null +++ b/src/specs/NativeRNMBXImageModule.ts @@ -0,0 +1,10 @@ +/* eslint-disable @typescript-eslint/ban-types */ +import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport'; +import { Int32 } from 'react-native/Libraries/Types/CodegenTypes'; +import { TurboModuleRegistry } from 'react-native'; + +export interface Spec extends TurboModule { + refresh: (viewRef: Int32 | null) => Promise; +} + +export default TurboModuleRegistry.getEnforcing('RNMBXImageModule');