diff --git a/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt b/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt index 0ed69c322..84d8e3ac9 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt @@ -13,6 +13,7 @@ import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationManager import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationModule 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)) RNMBXPointAnnotationModule.NAME -> return RNMBXPointAnnotationModule(reactApplicationContext, getViewTagResolver(reactApplicationContext)) } return null @@ -188,6 +190,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[RNMBXPointAnnotationModule.NAME] = ReactModuleInfo( RNMBXPointAnnotationModule.NAME, RNMBXPointAnnotationModule.NAME, 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..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 @@ -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,41 +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 - } - // endregion - - // region React methods - override fun receiveCommand(root: RNMBXImage, commandId: String?, args: ReadableArray?) { - if (commandId == "refresh") { - root.refresh() - } + override fun setScale(image: RNMBXImage, value: Dynamic) { + image.scale = value.asDouble() } // 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/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..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 @@ -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,14 @@ class RNMBXTerrainManager : ViewGroupManager() { return RNMBXTerrain(reactContext) } - @ReactProp(name = "id") - fun setId(layer: RNMBXTerrain, id: String?) { - layer.iD = id - } - @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); +} 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/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..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", @@ -2379,13 +2387,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/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/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/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/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/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/RNMBXMarkerViewComponentView.h b/ios/RNMBX/RNMBXMarkerViewComponentView.h index a4bdc896e..f9213df7c 100644 --- a/ios/RNMBX/RNMBXMarkerViewComponentView.h +++ b/ios/RNMBX/RNMBXMarkerViewComponentView.h @@ -5,11 +5,9 @@ #import #import -#import "RNMBXMapFeatureView.h" - NS_ASSUME_NONNULL_BEGIN -@interface RNMBXMarkerViewComponentView : RCTViewComponentView +@interface RNMBXMarkerViewComponentView : RCTViewComponentView @end NS_ASSUME_NONNULL_END 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/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/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 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 diff --git a/setup-jest.js b/setup-jest.js index 0c094ccbe..bfa7d191e 100644 --- a/setup-jest.js +++ b/setup-jest.js @@ -155,6 +155,10 @@ NativeModules.RNMBXShapeSourceModule = { getClusterChildren: jest.fn(), }; +NativeModules.RNMBXImageModule = { + refresh: jest.fn(), +}; + NativeModules.RNMBXPointAnnotationModule = { refresh: jest.fn(), }; diff --git a/src/components/Image.tsx b/src/components/Image.tsx index 328e26a45..adc84ea76 100644 --- a/src/components/Image.tsx +++ b/src/components/Image.tsx @@ -1,5 +1,8 @@ import React, { memo, forwardRef, ReactElement } from 'react'; -import { requireNativeComponent } from 'react-native'; +import { findNodeHandle } from 'react-native'; + +import RNMBXImageNativeComponent from '../specs/RNMBXImageNativeComponent'; +import NativeRNMBXImageModule from '../specs/NativeRNMBXImageModule'; interface Props { /** ID of the image */ @@ -42,21 +45,22 @@ const Image = memo( stretchY, children, }; - return ; - }), -); -interface NativeProps { - name: string; - children: ReactElement; - sdf?: boolean; - stretchX?: [number, number][]; - stretchY?: [number, number][]; -} + const imageRef = React.useRef(null); + + const refresh = () => { + const handle = findNodeHandle(imageRef.current as any); + NativeRNMBXImageModule.refresh(handle); + }; -export const NATIVE_MODULE_NAME = 'RNMBXImage'; + React.useImperativeHandle(ref, () => { + return { refresh }; + }); -const RNMBXImage = requireNativeComponent(NATIVE_MODULE_NAME); + // @ts-expect-error just codegen stuff + return ; + }), +); Image.displayName = '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..5b2694ef8 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,7 +39,8 @@ 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/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'); 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;