diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index d2dc978bc7..e1de15dc33 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -10,35 +10,19 @@ body: --- - ⚠️ **Deprecation Notice** ⚠️ - - **v10.x and old architecture (Paper/bridge) issues are deprecated and will not receive attention.** - - Please upgrade to v11+ with new architecture (Fabric/TurboModules) for active support. + **Requirements:** This library requires Mapbox Maps SDK v11 and React Native 0.79+ with New Architecture (Fabric/TurboModules). **For sponsors-only support and resources:** https://github.com/rnmapbox/maps/wiki/SponsorsRepo **Become a sponsor for special support:** https://github.com/sponsors/rnmapbox --- -- type: dropdown - id: mapbox-implementation - attributes: - label: Mapbox Implementation - description: |- - Check `RNMapboxMapsImpl` in your Podfile/gradle files. Defaults to `Maplibre`. - options: - - Mapbox - - Mapbox GL - - Maplibre - validations: - required: true - type: input id: mapbox-version attributes: label: Mapbox Version description: |- - Check `RNMapboxMapsVersion` in your Podfile/gradle files, set to `default` if you don't cusomize the version - placeholder: 10.7.0 + Check `RNMapboxMapsVersion` in your Podfile/gradle files, set to `default` if you don't customize the version + placeholder: 11.16.2 validations: required: true - type: input @@ -47,18 +31,7 @@ body: label: React Native Version description: |- The React Native version - placeholder: 0.73.2 - validations: - required: true -- type: dropdown - id: react-native-architecture - attributes: - label: React Native Architecture - description: |- - Select the React Native architecture you're using - options: - - New Architecture (Fabric/TurboModules) - - Old Architecture (Paper/bridge) + placeholder: 0.79.0 validations: required: true - type: dropdown @@ -78,8 +51,8 @@ body: attributes: label: "`@rnmapbox/maps` version" description: |- - The version of `@rnmapbox/maps`, such as `#main`, `10.0.0-beta.32` - value: 10.0.0-beta.11 + The version of `@rnmapbox/maps` + placeholder: 10.3.0 validations: required: true - type: textarea diff --git a/.github/ISSUE_TEMPLATE/bug_setup.md b/.github/ISSUE_TEMPLATE/bug_setup.md index a6115b2dad..2ecba992b4 100644 --- a/.github/ISSUE_TEMPLATE/bug_setup.md +++ b/.github/ISSUE_TEMPLATE/bug_setup.md @@ -5,11 +5,7 @@ labels: 'bug-setup 🪲' assignees: '' --- -⚠️ **Deprecation Notice** ⚠️ - -**v10.x and old architecture (Paper/bridge) issues are deprecated and will not receive attention.** - -Please upgrade to v11+ with new architecture (Fabric/TurboModules) for active support. +**Requirements:** This library requires Mapbox Maps SDK v11 and React Native 0.79+ with New Architecture (Fabric/TurboModules). **For sponsors-only support and resources:** https://github.com/rnmapbox/maps/wiki/SponsorsRepo **Become a sponsor for special support:** https://github.com/sponsors/rnmapbox @@ -18,10 +14,9 @@ Please upgrade to v11+ with new architecture (Fabric/TurboModules) for active su ## Environment - Dev OS: [e.g. OSX 11.0.1, Win10] -- @rnmapbox/maps version: [eg. 10.0.15] -- React Native version: [eg. 0.72.6] -- React Native Architecture: [New Architecture (Fabric/TurboModules) / Old Architecture (Paper/bridge)] -- Expo version: [eg. 49.0.0] +- @rnmapbox/maps version: [eg. 10.3.0] +- React Native version: [eg. 0.79.0] +- Expo version: [eg. 54.0.0] ## Steps to reproduce @@ -29,10 +24,9 @@ Please upgrade to v11+ with new architecture (Fabric/TurboModules) for active su ```sh -react-native init sample --version react-native@0.60.5 +npx @react-native-community/cli init sample cd sample -npm install rnmapbox/maps#main --save -# or released version `npm install @rnmapbox/maps@8.0.0-rc1 --save` -react-native run-android +npm install @rnmapbox/maps --save +npx react-native run-android ``` diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index c9da9d0e86..046efbd7d9 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -14,10 +14,11 @@ on: # Input has to be provided for the workflow to run required: true type: choice - options: + options: - patch - minor - major + - preminor --preid=beta - prerelease --preid=beta - prerelease --preid=rc @@ -35,14 +36,14 @@ jobs: # run that runs on: tag. (Using the GitHub token would # not run the workflow to prevent infinite recursion.) - name: Check out source - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ssh-key: ${{ secrets.DEPLOY_KEY }} - name: Setup Node.js - uses: actions/setup-node@v3.5.1 + uses: actions/setup-node@v4 with: - node-version: '16' + node-version: '22' - name: Setup Git run: | diff --git a/AGENTS.md b/AGENTS.md index 9d7b4686b8..4b0319332d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,25 +61,7 @@ yarn generate ### Building for Different Configurations -#### Mapbox v10 - deprecated -```bash -# iOS -cd example/ios -RNMBX10=1 pod update MapboxMaps - -# Android -# Edit example/android/gradle.properties: RNMBX10=true -``` - -#### New Architecture/Fabric -```bash -# iOS -cd example/ios -RCT_NEW_ARCH_ENABLED=1 pod update MapboxMaps - -# Android -# Edit example/android/gradle.properties: newArchEnabled=true -``` +The project uses Mapbox Maps SDK v11 and React Native's New Architecture (Fabric/TurboModules) exclusively. ## Architecture Overview @@ -91,7 +73,7 @@ RCT_NEW_ARCH_ENABLED=1 pod update MapboxMaps - Each component extends either `AbstractLayer` or `AbstractSource` for common functionality ### Native Bridge -- **Specs** (`src/specs/`): TurboModule/Fabric component specs for new architecture +- **Specs** (`src/specs/`): TurboModule/Fabric component specs - **Native Components**: Each component has corresponding native implementations: - iOS: `ios/RNMBX/RNMBX*.swift` and `RNMBX*ComponentView.mm` - Android: `android/src/main/java/` (generated from specs) @@ -127,6 +109,11 @@ RCT_NEW_ARCH_ENABLED=1 pod update MapboxMaps - Example app serves as integration testing ground - Use `yarn test` before committing +### E2E / Doc Screenshots (Detox) +- Detox tests in `example/e2e/docScreenshots.e2e.js` capture screenshots of every example for documentation +- Examples with JS timers or animations that block Detox sync should set `disableSync: true` in their metadata +- See CONTRIBUTING.md for build and run instructions + ### Documentation - Component docs are auto-generated from JSDoc comments - Don't edit `.md` files in `docs/` directly - edit source files and run `yarn generate` @@ -138,4 +125,4 @@ RCT_NEW_ARCH_ENABLED=1 pod update MapboxMaps - The example app is the primary way to test changes - Native changes require rebuilding the app - Web support is experimental and may have limited functionality -- Support both old and new React Native architectures +- Requires React Native 0.79+ with New Architecture (Fabric/TurboModules) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea5aba2300..0fbd2e2a49 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,18 +16,7 @@ Some notes about example app: ### Example app configurations: -- V10: this build with V10 of mapbox - To build example in this mode on ios run: - ``` - cd example/ios ; RNMBX10=1 pod update MapboxMaps - ``` - To build example in this mode on android: - Change `RNMBX10=true` in `example/android/gradle.properties` -- NewArchitecture/Fabric: - ``` - cd example/ios ; RCT_NEW_ARCH_ENABLED=1 pod update MapboxMaps - ``` - On android change `newArchEnabled=true` in `example/android/gradle.properties` +The project uses Mapbox Maps SDK v11 and React Native's New Architecture (Fabric/TurboModules) exclusively. ### Running example app for Web @@ -49,7 +38,7 @@ Run `yarn generate` to update generated code/documentation. We use the following code generators, but check yarn generate for more: - `style-spec/v8.json` download from mapbox.com describes properties of layers/sources etc. We generate the following files from it: - `MapboxStyles.d.ts` - typescript definitions for different Layer styles - - `RNMBXStyle.swift.ejs`/`RNMBXStyleFactoryV10.kt` - ios/android native style setters + - `RNMBXStyle.swift.ejs`/`RNMBXStyleFactory.kt` - ios/android native style setters - `docs.json` is generated both from style-spec and documentation in our typescript files - Document generation: - `docs/MapView.md` is generated from `src/components/MapView.tsx` with `react-docgen` diff --git a/README.md b/README.md index 61d1a4d419..218ab41afc 100644 --- a/README.md +++ b/README.md @@ -56,11 +56,8 @@ _A community-supported, open-source React Native library for building maps with --- -### Supported Implementations -At the moment we support Mapbox (v10) and Mapbox (v11) beta. -We default to Mapbox (v10). - -_See [iOS](ios/install.md) & [Android](android/install.md) setup guide for using v11 beta_ +### Supported Implementations +We support Mapbox Maps SDK v11. See [iOS](ios/install.md) & [Android](android/install.md) setup guides. @@ -74,7 +71,7 @@ _See [iOS](ios/install.md) & [Android](android/install.md) setup guide for using - [node](https://nodejs.org) - [npm](https://www.npmjs.com/) -- [React Native](https://facebook.github.io/react-native/) (0.70+, older versions from 0.64+ might or might not work) +- [React Native](https://facebook.github.io/react-native/) (0.79+) ## Installation diff --git a/__tests__/interface.test.js b/__tests__/interface.test.js index 693f5d9eea..d7e7299680 100644 --- a/__tests__/interface.test.js +++ b/__tests__/interface.test.js @@ -40,9 +40,12 @@ describe('Public Interface', () => { 'BackgroundLayer', 'RasterLayer', 'RasterParticleLayer', + 'HillshadeLayer', 'SkyLayer', 'Terrain', 'Atmosphere', + 'Snow', + 'Rain', // sources 'VectorSource', diff --git a/android/install.md b/android/install.md index 30648edda3..2025ca35ea 100644 --- a/android/install.md +++ b/android/install.md @@ -2,8 +2,7 @@ ## Supported mapbox libraries -We're only supporting mapbox 10.16* and 11.*. The default is 10.16*. -Next release will be 11.* only so we recommend updatign to 11.* +We support Mapbox Maps SDK v11. ### Adding mapbox maven repo @@ -27,39 +26,14 @@ allprojects { ### Using non default mapbox version -*Warning*: If you set a custom version, make sure you revisit, any time you update @rnmapbox/maps. Setting it to earlier version than what we exepect will likely result in a build error. +*Warning*: If you set a custom version, make sure you revisit any time you update @rnmapbox/maps. Setting it to an earlier version than what we expect will likely result in a build error. Set `RNMapboxMapsVersion` in `android/build.gradle > buildscript > ext` section - -```groovy -buildscript { - ext { - RNMapboxMapsVersion = '11.4.1' - } -} -``` - -you can also customize all the libraries, should it be neccesary - -```groovy -buildscript { - ext { - // ... - RNMapboxMapsLibs = { // optional - only required if you want to customize it - implementation 'com.mapbox.maps:android:10.6.0' - implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:5.4.1' - } - } -} -``` - -### Using v11 - ```groovy buildscript { ext { - RNMapboxMapsVersion = '11.4.1' + RNMapboxMapsVersion = '11.16.2' } } ``` diff --git a/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt b/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt index 57c8cc6cff..f82fadd32d 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt @@ -26,11 +26,14 @@ import com.rnmapbox.rnmbx.components.mapview.NativeMapViewModule import com.rnmapbox.rnmbx.components.mapview.RNMBXMapViewManager import com.rnmapbox.rnmbx.components.styles.RNMBXStyleImportManager import com.rnmapbox.rnmbx.components.styles.atmosphere.RNMBXAtmosphereManager +import com.rnmapbox.rnmbx.components.styles.snow.RNMBXSnowManager +import com.rnmapbox.rnmbx.components.styles.rain.RNMBXRainManager import com.rnmapbox.rnmbx.components.styles.layers.RNMBXBackgroundLayerManager import com.rnmapbox.rnmbx.components.styles.layers.RNMBXCircleLayerManager import com.rnmapbox.rnmbx.components.styles.layers.RNMBXFillExtrusionLayerManager import com.rnmapbox.rnmbx.components.styles.layers.RNMBXFillLayerManager import com.rnmapbox.rnmbx.components.styles.layers.RNMBXHeatmapLayerManager +import com.rnmapbox.rnmbx.components.styles.layers.RNMBXHillshadeLayerManager import com.rnmapbox.rnmbx.components.styles.layers.RNMBXLineLayerManager import com.rnmapbox.rnmbx.components.styles.layers.RNMBXModelLayerManager import com.rnmapbox.rnmbx.components.styles.layers.RNMBXRasterLayerManager @@ -161,12 +164,15 @@ class RNMBXPackage : TurboReactPackage() { managers.add(RNMBXCircleLayerManager()) managers.add(RNMBXSymbolLayerManager()) managers.add(RNMBXRasterLayerManager()) + managers.add(RNMBXHillshadeLayerManager()) if (RNMBXRasterParticleLayerManager.isImplemented) { managers.add(RNMBXRasterParticleLayerManager()) } managers.add(RNMBXSkyLayerManager()) managers.add(RNMBXTerrainManager()) managers.add(RNMBXAtmosphereManager()) + managers.add(RNMBXSnowManager()) + managers.add(RNMBXRainManager()) managers.add(RNMBXBackgroundLayerManager()) managers.add(RNMBXLightManager()) managers.add(RNMBXModelLayerManager()) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt index d6b8fff82e..561eed1020 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt @@ -1,13 +1,24 @@ package com.rnmapbox.rnmbx.components.annotation import android.content.Context +import android.view.MotionEvent import android.view.View.MeasureSpec import android.view.ViewGroup +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.ReactContext +import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.views.view.ReactViewGroup +import com.rnmapbox.rnmbx.components.camera.BaseEvent class RNMBXMarkerViewContent(context: Context): ReactViewGroup(context) { var inAdd: Boolean = false + // Track last reported translation to avoid feedback loop: + // Mapbox sets setTranslationX(512) → we fire event → JS sets transform:[{translateX:512}] + // → Fabric calls setTranslationX(512) again → same value → no re-fire. + private var lastReportedTx = Float.NaN + private var lastReportedTy = Float.NaN + init { allowRenderingOutside() } @@ -17,6 +28,50 @@ class RNMBXMarkerViewContent(context: Context): ReactViewGroup(context) { configureParentClipping() } + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + // On ACTION_DOWN, tell the parent MapView not to intercept subsequent MOVE/UP + // events for pan/zoom recognition — that would send CANCEL to child Pressables + // and suppress onPress. Android resets the disallow flag on each new DOWN, so + // calling this once per gesture is sufficient. See maplibre-react-native#1289. + if (ev.actionMasked == MotionEvent.ACTION_DOWN) { + parent?.requestDisallowInterceptTouchEvent(true) + } + return super.dispatchTouchEvent(ev) + } + + override fun setTranslationX(translationX: Float) { + super.setTranslationX(translationX) + maybeFireAnnotationPositionEvent() + } + + override fun setTranslationY(translationY: Float) { + super.setTranslationY(translationY) + maybeFireAnnotationPositionEvent() + } + + private fun maybeFireAnnotationPositionEvent() { + val tx = translationX + val ty = translationY + // Dedup: skip if value unchanged (prevents feedback loop when Fabric + // re-applies the same transform prop back to setTranslationX/Y). + if (tx == lastReportedTx && ty == lastReportedTy) return + lastReportedTx = tx + lastReportedTy = ty + + val reactContext = context as? ReactContext ?: return + val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id) ?: return + // Use getSurfaceId(view) — more reliable for Fabric than getSurfaceId(context) + val surfaceId = UIManagerHelper.getSurfaceId(this) + dispatcher.dispatchEvent( + BaseEvent(surfaceId, id, "topAnnotationPosition", + Arguments.createMap().apply { + putDouble("x", tx.toDouble()) + putDouble("y", ty.toDouble()) + }, + canCoalesce = true) + ) + } + private fun configureParentClipping() { val parent = parent if (parent is android.view.ViewGroup) { diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContentManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContentManager.kt index bbf271fe88..64a7ffd5e1 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContentManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContentManager.kt @@ -2,13 +2,14 @@ package com.rnmapbox.rnmbx.components.annotation import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.uimanager.ThemedReactContext -import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.viewmanagers.RNMBXMarkerViewContentManagerInterface +import com.rnmapbox.rnmbx.components.AbstractEventEmitter class RNMBXMarkerViewContentManager(reactApplicationContext: ReactApplicationContext) : - ViewGroupManager(), + AbstractEventEmitter(reactApplicationContext), RNMBXMarkerViewContentManagerInterface { + override fun getName(): String { return REACT_CLASS } @@ -17,6 +18,10 @@ class RNMBXMarkerViewContentManager(reactApplicationContext: ReactApplicationCon return RNMBXMarkerViewContent(context) } + override fun customEvents(): Map { + return mapOf("topAnnotationPosition" to "onAnnotationPosition") + } + companion object { const val REACT_CLASS = "RNMBXMarkerViewContent" } diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt index afa1ef5551..55dc04cdd7 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt @@ -96,8 +96,6 @@ class RNMBXMarkerViewManager(reactApplicationContext: ReactApplicationContext) : } } } - - }) } } diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotation.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotation.kt index 14c0e3f02e..aa41338d2f 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotation.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotation.kt @@ -36,7 +36,7 @@ class RNMBXPointAnnotation(private val mContext: Context, private val mManager: private val mTitle: String? = null private val mSnippet: String? = null private var mAnchor: Array? = null - private val mIsSelected = false + private var mIsSelected = false private var mDraggable = false private var mChildView: View? = null private var mChildBitmap: Bitmap? = null @@ -187,7 +187,19 @@ class RNMBXPointAnnotation(private val mContext: Context, private val mManager: } } + fun setReactSelected(selected: Boolean) { + if (selected && !mIsSelected) { + pointAnnotations?.let { + it.deselectSelectedAnnotation() + it.selectAnnotation(this) + } + } else if (!selected && mIsSelected) { + pointAnnotations?.deselectAnnotation(this) + } + } + fun doSelect(shouldSendEvent: Boolean) { + mIsSelected = true if (calloutView != null) { makeCallout() } @@ -197,6 +209,7 @@ class RNMBXPointAnnotation(private val mContext: Context, private val mManager: } fun doDeselect() { + mIsSelected = false mManager.handleEvent(makeEvent(false)) mCalloutSymbol?.let { mCalloutSymbol -> pointAnnotations?.delete(mCalloutSymbol) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManager.kt index 4121695662..b9088c5053 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManager.kt @@ -78,6 +78,17 @@ class RNMBXPointAnnotationManager(reactApplicationContext: ReactApplicationConte annotation.setAnchor(mapValue.getDouble("x").toFloat(), mapValue.getDouble("y").toFloat()) } + override fun setSelected( + annotation: RNMBXPointAnnotation, + value: Dynamic + ) { + if (value.isNull) { + Logger.e("RNMBXPointAnnotationManager", "selected value is null") + return + } + annotation.setReactSelected(value.asBoolean()) + } + @ReactProp(name = "draggable") override fun setDraggable(annotation: RNMBXPointAnnotation, draggable: Dynamic) { annotation.setDraggable(draggable.asBoolean()) 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 6b8126b369..305e07ad3f 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 @@ -11,8 +11,11 @@ import com.google.gson.Gson import com.google.gson.stream.JsonWriter import com.mapbox.bindgen.Value import com.mapbox.maps.extension.style.expressions.generated.Expression +import com.rnmapbox.rnmbx.components.location.RNMBXNativeUserLocationManager.Companion.TAG import com.rnmapbox.rnmbx.rncompat.dynamic.* import com.rnmapbox.rnmbx.utils.Logger +import com.rnmapbox.rnmbx.utils.extensions.asBooleanOrNull +import com.rnmapbox.rnmbx.utils.extensions.asStringOrNull import com.rnmapbox.rnmbx.utils.extensions.toJsonArray import java.io.StringWriter import javax.annotation.Nonnull @@ -27,51 +30,50 @@ class RNMBXNativeUserLocationManager : ViewGroupManager @ReactProp(name = "androidRenderMode") override fun setAndroidRenderMode(userLocation: RNMBXNativeUserLocation, mode: Dynamic) { - if (!mode.isNull) { - Logger.e("RNMBXNativeUserLocationManager", "androidRenderMode is deprecated, use puckBearing instead") - } - when (mode.asString()) { - "compass" -> userLocation.androidRenderMode = RenderMode.COMPASS - "gps" -> userLocation.androidRenderMode = RenderMode.GPS - "normal" -> userLocation.androidRenderMode = RenderMode.NORMAL + mode.asStringOrNull()?.let { + Logger.e(TAG, "androidRenderMode is deprecated, use puckBearing instead") + + when (it) { + "compass" -> userLocation.androidRenderMode = RenderMode.COMPASS + "gps" -> userLocation.androidRenderMode = RenderMode.GPS + "normal" -> userLocation.androidRenderMode = RenderMode.NORMAL + } } } @ReactProp(name = "puckBearing") override fun setPuckBearing(view: RNMBXNativeUserLocation, value: Dynamic) { - when (value?.asString()) { + when (value.asStringOrNull()) { "heading" -> view.puckBearing = PuckBearing.HEADING "course" -> view.puckBearing = PuckBearing.COURSE null -> Unit else -> - Logger.e("RNMBXNativeUserLocationManager", "unexpected value for puckBearing: $value") + Logger.e(TAG, "unexpected value for puckBearing: $value") } } @ReactProp(name = "puckBearingEnabled") override fun setPuckBearingEnabled(view: RNMBXNativeUserLocation, value: Dynamic) { - if (!value.isNull) { - if (value.type == ReadableType.Boolean) { - view.puckBearingEnabled = value.asBoolean() - } else { - Logger.e("RNMBXNativeUserLocationManager", "unexpected value for puckBearingEnabled: $value") - } + value.asBooleanOrNull()?.let { + view.puckBearingEnabled = it + } ?: run { + Logger.e(TAG, "unexpected value for puckBearingEnabled: $value") } } @ReactProp(name = "topImage") override fun setTopImage(view: RNMBXNativeUserLocation, value: Dynamic?) { - view.topImage = value?.asString() + view.topImage = value?.asStringOrNull() } @ReactProp(name = "bearingImage") override fun setBearingImage(view: RNMBXNativeUserLocation, value: Dynamic?) { - view.bearingImage = value?.asString() + view.bearingImage = value?.asStringOrNull() } @ReactProp(name = "shadowImage") override fun setShadowImage(view: RNMBXNativeUserLocation, value: Dynamic?) { - view.shadowImage = value?.asString() + view.shadowImage = value?.asStringOrNull() } @ReactProp(name = "scale", defaultDouble = 1.0) @@ -98,11 +100,10 @@ class RNMBXNativeUserLocationManager : ViewGroupManager companion object { const val REACT_CLASS = "RNMBXNativeUserLocation" + const val TAG = "RNMBXNativeUserLocationManager" } } - - fun _convertToDoubleValueOrExpression(value: Dynamic?, name: String): Value? { if (value == null) { return null @@ -111,7 +112,7 @@ fun _convertToDoubleValueOrExpression(value: Dynamic?, name: String): Value? { ReadableType.Array -> { val array = value.asArray() if (array == null) { - Logger.e("RNMBXNativeUserLocationManager", "_convertToDoubleValueOrExpression: array is null for $name") + Logger.e(TAG, "_convertToDoubleValueOrExpression: array is null for $name") return null } Expression.fromRaw(Gson().toJson(array.toJsonArray())) @@ -120,10 +121,10 @@ fun _convertToDoubleValueOrExpression(value: Dynamic?, name: String): Value? { Value.valueOf(value.asDouble()) else -> { Logger.e( - "RNMBXNativeUserLocationmanager", - "_convertToExpressionString: cannot convert $name to a double or double exrpession. $value" + TAG, + "_convertToExpressionString: cannot convert $name to a double or double expression. $value" ) - return null + null } } } diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/NativeMapViewModule.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/NativeMapViewModule.kt index 5ff073e3ff..38de6c8d52 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/NativeMapViewModule.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/NativeMapViewModule.kt @@ -12,6 +12,7 @@ import com.rnmapbox.rnmbx.utils.ExpressionParser import com.rnmapbox.rnmbx.utils.ViewRefTag import com.rnmapbox.rnmbx.utils.ViewTagResolver import com.rnmapbox.rnmbx.utils.extensions.toCoordinate +import com.rnmapbox.rnmbx.utils.extensions.toScreenBox import com.rnmapbox.rnmbx.utils.extensions.toScreenCoordinate import com.rnmapbox.rnmbx.utils.extensions.toValueHashMap @@ -116,7 +117,7 @@ class NativeMapViewModule(context: ReactApplicationContext, val viewTagResolver: val layerIds = ConvertUtils.toStringList(withLayerIDs) it.queryRenderedFeaturesAtPoint( - ConvertUtils.toPointF(atPoint), + atPoint.toScreenCoordinate(), ExpressionParser.from(withFilter), if (layerIds.size == 0) null else layerIds, createCommandResponse(promise) @@ -135,7 +136,7 @@ class NativeMapViewModule(context: ReactApplicationContext, val viewTagResolver: val layerIds = ConvertUtils.toStringList(withLayerIDs) it.queryRenderedFeaturesInRect( - ConvertUtils.toRectF(withBBox), + if (withBBox.size() == 0) null else withBBox.toScreenBox(), ExpressionParser.from(withFilter), if (layerIds.size == 0) null else layerIds, createCommandResponse(promise) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt index b05cdbe74d..1515d898d8 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt @@ -2,12 +2,10 @@ package com.rnmapbox.rnmbx.components.mapview import android.content.Context import android.graphics.BitmapFactory -import android.graphics.PointF -import android.graphics.RectF import android.os.Handler import android.os.Looper -import android.util.Log import android.view.Gravity +import android.view.MotionEvent import android.view.View import android.view.View.OnLayoutChangeListener import android.view.ViewGroup @@ -180,6 +178,18 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie private var wasGestureActive = false private var isGestureActive = false + private var mAfterLongPress = false + + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + if (mAfterLongPress) { + val action = ev.actionMasked + if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { + mAfterLongPress = false + } + } + return super.dispatchTouchEvent(ev) + } + var mapViewImpl: String? = null val mapView: MapView @@ -297,10 +307,17 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie } override fun onMove(moveGestureDetector: MoveGestureDetector): Boolean { + if (mAfterLongPress) { + return true // consume the move events that come after a long press, to prevent the map from moving when the user is trying to long press on something + } return mapGesture(MapGestureType.Move, moveGestureDetector) } override fun onMoveEnd(moveGestureDetector: MoveGestureDetector) { + if (mAfterLongPress) { + mAfterLongPress = false + return + } mapGestureEnd(MapGestureType.Move, moveGestureDetector) } }) @@ -701,24 +718,26 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie return true } } - val screenPoint = mMap?.pixelForCoordinate(point) + val screenPointPx = mMap?.pixelForCoordinate(point) val touchableSources = allTouchableSources val hits = HashMap?>() - if (screenPoint != null) { - handleTapInSources(LinkedList(touchableSources), screenPoint, hits, ArrayList(), object : HandleTap { + if (screenPointPx != null) { + handleTapInSources(LinkedList(touchableSources), screenPointPx, hits, ArrayList(), object : HandleTap { override fun run(hitTouchableSources: List?>?, hits: Map?>) { + /** Android Mapbox SDK returns screen coordinates in physical pixels, while JS expects density-independent pixels. */ + val screenPointDp = toDp(screenPointPx) if (hits.size > 0) { val source = getTouchableSourceWithHighestZIndex(hitTouchableSources as List>?) if (source != null && source.hasPressListener() && source.iD != null && source.iD in hits) { source.onPress(RNMBXSource.OnPressEvent( hits[source.iD] as List, GeoJSONUtils.toLatLng(point), - PointF(screenPoint.x.toFloat(), screenPoint.y.toFloat()) + screenPointDp )) return } } - val event = MapClickEvent(_this, LatLng(point), screenPoint) + val event = MapClickEvent(_this, LatLng(point), screenPointDp) mManager.handleEvent(event) } @@ -732,9 +751,11 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie if (pointAnnotations.getAndClearAnnotationDragged()) { return true } - val screenPoint = mMap?.pixelForCoordinate(point) - if (screenPoint != null) { - val event = MapClickEvent(_this, LatLng(point), screenPoint, EventTypes.MAP_LONG_CLICK) + val screenPointPx = mMap?.pixelForCoordinate(point) + if (screenPointPx != null) { + mAfterLongPress = true + val screenPointDp = toDp(screenPointPx) + val event = MapClickEvent(_this, LatLng(point), screenPointDp, EventTypes.MAP_LONG_CLICK) mManager.handleEvent(event) } @@ -908,48 +929,61 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie } } - private fun getDisplayDensity(): Float { - return mContext.resources.displayMetrics.density + private fun getDisplayDensity(): Double { + return mContext.resources.displayMetrics.density.toDouble() + } + + /** Converts a point from physical pixels to density-independent pixels. */ + private fun toDp(pointPx: ScreenCoordinate): ScreenCoordinate { + val density = getDisplayDensity() + return ScreenCoordinate(pointPx.x / density, pointPx.y / density) + } + + /** Converts a point from density-independent pixels to physical pixels. */ + private fun toPx(pointDp: ScreenCoordinate): ScreenCoordinate { + val density = getDisplayDensity() + return ScreenCoordinate(pointDp.x * density, pointDp.y * density) + } + + /** Converts a bounding box from density-independent pixels to physical pixels. */ + private fun toPx(boxDp: ScreenBox): ScreenBox { + val density = getDisplayDensity() + return ScreenBox( + ScreenCoordinate(boxDp.min.x * density, boxDp.min.y * density), + ScreenCoordinate(boxDp.max.x * density, boxDp.max.y * density), + ) } - fun getCoordinateFromView(pixel: ScreenCoordinate, response: CommandResponse) { - val density: Float = getDisplayDensity() - val screenCoordinate = ScreenCoordinate(pixel.x * density, pixel.y * density) + fun getCoordinateFromView(pointDp: ScreenCoordinate, response: CommandResponse) { + val pointPx = toPx(pointDp) - val coordinate = mMap!!.coordinateForPixel(screenCoordinate) + val coordinate = mMap!!.coordinateForPixel(pointPx) response.success { it.putArray("coordinateFromView", coordinate.toReadableArray()) } } - fun getPointInView(coordinate: Point, response: CommandResponse) { - val point = mMap!!.pixelForCoordinate(coordinate) - val density = getDisplayDensity() - val pointInView = PointF((point.x / density).toFloat(), (point.y / density).toFloat()) + fun getPointInView(coordinates: Point, response: CommandResponse) { + val pointDp = toDp(mMap!!.pixelForCoordinate(coordinates)) response.success { val array: WritableArray = WritableNativeArray() - array.pushDouble(pointInView.x.toDouble()) - array.pushDouble(pointInView.y.toDouble()) + array.pushDouble(pointDp.x) + array.pushDouble(pointDp.y) it.putArray("pointInView", array) } } - fun queryRenderedFeaturesAtPoint(point: PointF, filter: Expression?, layerIDs: List?, response: CommandResponse) { + fun queryRenderedFeaturesAtPoint(pointDp: ScreenCoordinate, filter: Expression?, layerIDs: List?, response: CommandResponse) { if (mMap == null) { Logger.e("queryRenderedFeaturesAtPoint", "mapbox map is null") return } - // JS sends point values in DIP (see getPointInView which divides by display density), - // but Mapbox core expects screen pixel coordinates. Convert back to px here. - val density: Float = getDisplayDensity() - val screenCoordinate = ScreenCoordinate( - (point.x * density).toDouble(), - (point.y * density).toDouble() - ) - val queryGeometry = RenderedQueryGeometry(screenCoordinate) - val layers = layerIDs?.takeUnless { it.isEmpty() } ?: null; + + val pointPx = toPx(pointDp) + val queryGeometry = RenderedQueryGeometry(pointPx) + val layers = layerIDs?.takeUnless { it.isEmpty() } ?: null val queryOptions = RenderedQueryOptions(layers, filter) mMap.queryRenderedFeatures(queryGeometry, queryOptions) { features -> if (features.isValue) { @@ -966,14 +1000,19 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie } } - fun queryRenderedFeaturesInRect(rect: RectF?, filter: Expression?, layerIDs: List?, response: CommandResponse) { + fun queryRenderedFeaturesInRect(rectDp: ScreenBox?, filter: Expression?, layerIDs: List?, response: CommandResponse) { val size = mMap.getMapOptions().size - val screenBox = if (rect == null) ScreenBox(ScreenCoordinate(0.0, 0.0), ScreenCoordinate(size?.width!!.toDouble(), size?.height!!.toDouble())) else ScreenBox( - ScreenCoordinate(rect.right.toDouble(), rect.bottom.toDouble() ), - ScreenCoordinate(rect.left.toDouble(), rect.top.toDouble()), - ) + + val rectPx: ScreenBox = + rectDp?.let { toPx(it) } + ?: ScreenBox( + ScreenCoordinate(0.0, 0.0), + /** No conversion needed, screen size is already returned in physical pixels. */ + ScreenCoordinate(size?.width?.toDouble() ?: 0.0, size?.height?.toDouble() ?: 0.0) + ) + mMap.queryRenderedFeatures( - RenderedQueryGeometry(screenBox), + RenderedQueryGeometry(rectPx), RenderedQueryOptions(layerIDs, filter) ) { features -> if (features.isValue) { diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapViewManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapViewManager.kt index b815af660b..bdc25714d2 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapViewManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapViewManager.kt @@ -10,25 +10,16 @@ import com.facebook.react.uimanager.LayoutShadowNode import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.annotations.ReactProp import com.rnmapbox.rnmbx.events.constants.EventKeys -import com.facebook.react.common.MapBuilder import com.facebook.react.uimanager.ViewManagerDelegate import com.facebook.react.viewmanagers.RNMBXMapViewManagerDelegate import com.facebook.react.viewmanagers.RNMBXMapViewManagerInterface -import com.mapbox.maps.MapInitOptions import com.mapbox.maps.extension.style.layers.properties.generated.ProjectionName import com.mapbox.maps.plugin.gestures.gestures -import com.mapbox.maps.plugin.logo.logo -import com.rnmapbox.rnmbx.events.AndroidCallbackEvent import com.rnmapbox.rnmbx.events.constants.eventMapOf -import com.rnmapbox.rnmbx.utils.ConvertUtils -import com.rnmapbox.rnmbx.utils.ExpressionParser import com.rnmapbox.rnmbx.utils.Logger import com.rnmapbox.rnmbx.utils.ViewTagResolver import com.rnmapbox.rnmbx.utils.extensions.getAndLogIfNotBoolean import com.rnmapbox.rnmbx.utils.extensions.getAndLogIfNotDouble -import com.rnmapbox.rnmbx.utils.extensions.toCoordinate -import com.rnmapbox.rnmbx.utils.extensions.toRectF -import com.rnmapbox.rnmbx.utils.extensions.toScreenCoordinate import java.lang.Exception import java.util.HashMap diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/RNMBXStyleFactory.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/RNMBXStyleFactory.kt index a8456b688d..1420e716de 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/RNMBXStyleFactory.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/RNMBXStyleFactory.kt @@ -18,6 +18,8 @@ import com.mapbox.maps.extension.style.layers.generated.SymbolLayer import com.mapbox.maps.extension.style.layers.generated.HeatmapLayer import com.mapbox.maps.extension.style.layers.generated.HillshadeLayer import com.mapbox.maps.extension.style.atmosphere.generated.Atmosphere +import com.mapbox.maps.extension.style.precipitations.generated.Snow +import com.mapbox.maps.extension.style.precipitations.generated.Rain import com.mapbox.maps.extension.style.terrain.generated.Terrain import com.mapbox.maps.extension.style.layers.generated.ModelLayer // import com.mapbox.maps.extension.style.layers.properties.generated.Visibility @@ -175,12 +177,24 @@ object RNMBXStyleFactory { setLineGradient(layer, styleValue) "lineTrimOffset" -> setLineTrimOffset(layer, styleValue) + "lineBorderWidth" -> + setLineBorderWidth(layer, styleValue) + "lineBorderWidthTransition" -> + setLineBorderWidthTransition(layer, styleValue) + "lineBorderColor" -> + setLineBorderColor(layer, styleValue) + "lineBorderColorTransition" -> + setLineBorderColorTransition(layer, styleValue) "lineZOffset" -> setLineZOffset(layer, styleValue) "lineElevationReference" -> setLineElevationReference(layer, styleValue) "lineCrossSlope" -> setLineCrossSlope(layer, styleValue) + "lineElevationGroundScale" -> + setLineElevationGroundScale(layer, styleValue) + "lineElevationGroundScaleTransition" -> + setLineElevationGroundScaleTransition(layer, styleValue) "linePatternCrossFade" -> style.addImage(styleValue!!, styleKey, object : OnAllImagesLoaded { override fun onAllImagesLoaded() { @@ -795,6 +809,8 @@ object RNMBXStyleFactory { val styleValue = style.getStyleValueForKey(styleKey) when (styleKey) { + "modelAllowDensityReduction" -> + setModelAllowDensityReduction(layer, styleValue) "visibility" -> setVisibility(layer, styleValue) "modelId" -> @@ -847,6 +863,8 @@ object RNMBXStyleFactory { setModelHeightBasedEmissiveStrengthMultiplierTransition(layer, styleValue) "modelCutoffFadeRange" -> setModelCutoffFadeRange(layer, styleValue) + "modelElevationReference" -> + setModelElevationReference(layer, styleValue) } } catch (e: MapboxStyleException) { Logger.e(LOG_TAG, "Failed to update: $styleKey ${e.message}") @@ -1015,6 +1033,118 @@ object RNMBXStyleFactory { } } } + fun setSnowLayerStyle(layer: Snow, style: RNMBXStyle ) { + val styleKeys = style.allStyleKeys + + if (styleKeys.isEmpty()) { + return + } + + for (styleKey in styleKeys) { + try { + val styleValue = style.getStyleValueForKey(styleKey) + + when (styleKey) { + "density" -> + setDensity(layer, styleValue) + "densityTransition" -> + setDensityTransition(layer, styleValue) + "intensity" -> + setIntensity(layer, styleValue) + "intensityTransition" -> + setIntensityTransition(layer, styleValue) + "color" -> + setColor(layer, styleValue) + "colorTransition" -> + setColorTransition(layer, styleValue) + "opacity" -> + setOpacity(layer, styleValue) + "opacityTransition" -> + setOpacityTransition(layer, styleValue) + "vignette" -> + setVignette(layer, styleValue) + "vignetteTransition" -> + setVignetteTransition(layer, styleValue) + "vignetteColor" -> + setVignetteColor(layer, styleValue) + "vignetteColorTransition" -> + setVignetteColorTransition(layer, styleValue) + "centerThinning" -> + setCenterThinning(layer, styleValue) + "centerThinningTransition" -> + setCenterThinningTransition(layer, styleValue) + "direction" -> + setDirection(layer, styleValue) + "directionTransition" -> + setDirectionTransition(layer, styleValue) + "flakeSize" -> + setFlakeSize(layer, styleValue) + "flakeSizeTransition" -> + setFlakeSizeTransition(layer, styleValue) + } + } catch (e: MapboxStyleException) { + Logger.e(LOG_TAG, "Failed to update: $styleKey ${e.message}") + } + } + } + fun setRainLayerStyle(layer: Rain, style: RNMBXStyle ) { + val styleKeys = style.allStyleKeys + + if (styleKeys.isEmpty()) { + return + } + + for (styleKey in styleKeys) { + try { + val styleValue = style.getStyleValueForKey(styleKey) + + when (styleKey) { + "density" -> + setDensity(layer, styleValue) + "densityTransition" -> + setDensityTransition(layer, styleValue) + "intensity" -> + setIntensity(layer, styleValue) + "intensityTransition" -> + setIntensityTransition(layer, styleValue) + "color" -> + setColor(layer, styleValue) + "colorTransition" -> + setColorTransition(layer, styleValue) + "opacity" -> + setOpacity(layer, styleValue) + "opacityTransition" -> + setOpacityTransition(layer, styleValue) + "vignette" -> + setVignette(layer, styleValue) + "vignetteTransition" -> + setVignetteTransition(layer, styleValue) + "vignetteColor" -> + setVignetteColor(layer, styleValue) + "vignetteColorTransition" -> + setVignetteColorTransition(layer, styleValue) + "centerThinning" -> + setCenterThinning(layer, styleValue) + "centerThinningTransition" -> + setCenterThinningTransition(layer, styleValue) + "direction" -> + setDirection(layer, styleValue) + "directionTransition" -> + setDirectionTransition(layer, styleValue) + "dropletSize" -> + setDropletSize(layer, styleValue) + "dropletSizeTransition" -> + setDropletSizeTransition(layer, styleValue) + "distortionStrength" -> + setDistortionStrength(layer, styleValue) + "distortionStrengthTransition" -> + setDistortionStrengthTransition(layer, styleValue) + } + } catch (e: MapboxStyleException) { + Logger.e(LOG_TAG, "Failed to update: $styleKey ${e.message}") + } + } + } fun setTerrainLayerStyle(layer: Terrain, style: RNMBXStyle ) { val styleKeys = style.allStyleKeys @@ -1619,6 +1749,58 @@ object RNMBXStyleFactory { } } + fun setLineBorderWidth(layer: LineLayer, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.lineBorderWidth(expression) + } else { + Logger.e("RNMBXLine", "Expression for lineBorderWidth is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.lineBorderWidth(value) + } else { + Logger.e("RNMBXLine", "value for lineBorderWidth is null") + } + } + } + + + fun setLineBorderWidthTransition(layer: LineLayer, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.lineBorderWidthTransition(transition); + } + } + + fun setLineBorderColor(layer: LineLayer, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.lineBorderColor(expression) + } else { + Logger.e("RNMBXLine", "Expression for lineBorderColor is null") + } + } else { + val value = styleValue.getInt(VALUE_KEY) + if (value != null) { + layer.lineBorderColor(value) + } else { + Logger.e("RNMBXLine", "value for lineBorderColor is null") + } + } + } + + + fun setLineBorderColorTransition(layer: LineLayer, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.lineBorderColorTransition(transition); + } + } + fun setLineZOffset(layer: LineLayer, styleValue: RNMBXStyleValue ) { if (styleValue.isExpression()) { val expression = styleValue.getExpression() @@ -1668,6 +1850,32 @@ object RNMBXStyleFactory { } } + fun setLineElevationGroundScale(layer: LineLayer, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.lineElevationGroundScale(expression) + } else { + Logger.e("RNMBXLine", "Expression for lineElevationGroundScale is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.lineElevationGroundScale(value) + } else { + Logger.e("RNMBXLine", "value for lineElevationGroundScale is null") + } + } + } + + + fun setLineElevationGroundScaleTransition(layer: LineLayer, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.lineElevationGroundScaleTransition(transition); + } + } + fun setLinePatternCrossFade(layer: LineLayer, styleValue: RNMBXStyleValue ) { if (styleValue.isExpression()) { val expression = styleValue.getExpression() @@ -4673,6 +4881,24 @@ object RNMBXStyleFactory { } } + fun setModelAllowDensityReduction(layer: ModelLayer, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.modelAllowDensityReduction(expression) + } else { + Logger.e("RNMBXModel", "Expression for modelAllowDensityReduction is null") + } + } else { + val value = styleValue.getBoolean(VALUE_KEY) + if (value != null) { + layer.modelAllowDensityReduction(value) + } else { + Logger.e("RNMBXModel", "value for modelAllowDensityReduction is null") + } + } + } + fun setVisibility(layer: ModelLayer, styleValue: RNMBXStyleValue ) { layer.visibility(Visibility.valueOf(styleValue.getEnumName())); } @@ -5022,6 +5248,19 @@ object RNMBXStyleFactory { } } + fun setModelElevationReference(layer: ModelLayer, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.modelElevationReference(expression) + } else { + Logger.e("RNMBXModel", "Expression for modelElevationReference is null") + } + } else { + layer.modelElevationReference(ModelElevationReference.valueOf(styleValue.getEnumName())) + } + } + fun setVisibility(layer: BackgroundLayer, styleValue: RNMBXStyleValue ) { layer.visibility(Visibility.valueOf(styleValue.getEnumName())); } @@ -5576,6 +5815,500 @@ object RNMBXStyleFactory { } } + fun setDensity(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.density(expression) + } else { + Logger.e("RNMBXSnow", "Expression for density is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.density(value) + } else { + Logger.e("RNMBXSnow", "value for density is null") + } + } + } + + + fun setDensityTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.densityTransition(transition); + } + } + + fun setIntensity(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.intensity(expression) + } else { + Logger.e("RNMBXSnow", "Expression for intensity is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.intensity(value) + } else { + Logger.e("RNMBXSnow", "value for intensity is null") + } + } + } + + + fun setIntensityTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.intensityTransition(transition); + } + } + + fun setColor(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.color(expression) + } else { + Logger.e("RNMBXSnow", "Expression for color is null") + } + } else { + val value = styleValue.getInt(VALUE_KEY) + if (value != null) { + layer.color(value) + } else { + Logger.e("RNMBXSnow", "value for color is null") + } + } + } + + + fun setColorTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.colorTransition(transition); + } + } + + fun setOpacity(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.opacity(expression) + } else { + Logger.e("RNMBXSnow", "Expression for opacity is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.opacity(value) + } else { + Logger.e("RNMBXSnow", "value for opacity is null") + } + } + } + + + fun setOpacityTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.opacityTransition(transition); + } + } + + fun setVignette(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.vignette(expression) + } else { + Logger.e("RNMBXSnow", "Expression for vignette is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.vignette(value) + } else { + Logger.e("RNMBXSnow", "value for vignette is null") + } + } + } + + + fun setVignetteTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.vignetteTransition(transition); + } + } + + fun setVignetteColor(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.vignetteColor(expression) + } else { + Logger.e("RNMBXSnow", "Expression for vignetteColor is null") + } + } else { + val value = styleValue.getInt(VALUE_KEY) + if (value != null) { + layer.vignetteColor(value) + } else { + Logger.e("RNMBXSnow", "value for vignetteColor is null") + } + } + } + + + fun setVignetteColorTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.vignetteColorTransition(transition); + } + } + + fun setCenterThinning(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.centerThinning(expression) + } else { + Logger.e("RNMBXSnow", "Expression for centerThinning is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.centerThinning(value) + } else { + Logger.e("RNMBXSnow", "value for centerThinning is null") + } + } + } + + + fun setCenterThinningTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.centerThinningTransition(transition); + } + } + + fun setDirection(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.direction(expression) + } else { + Logger.e("RNMBXSnow", "Expression for direction is null") + } + } else { + val value = styleValue.getFloatArray(VALUE_KEY) + if (value != null) { + layer.direction(value) + } else { + Logger.e("RNMBXSnow", "value for direction is null") + } + } + } + + + fun setDirectionTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.directionTransition(transition); + } + } + + fun setFlakeSize(layer: Snow, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.flakeSize(expression) + } else { + Logger.e("RNMBXSnow", "Expression for flakeSize is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.flakeSize(value) + } else { + Logger.e("RNMBXSnow", "value for flakeSize is null") + } + } + } + + + fun setFlakeSizeTransition(layer: Snow, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.flakeSizeTransition(transition); + } + } + + fun setDensity(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.density(expression) + } else { + Logger.e("RNMBXRain", "Expression for density is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.density(value) + } else { + Logger.e("RNMBXRain", "value for density is null") + } + } + } + + + fun setDensityTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.densityTransition(transition); + } + } + + fun setIntensity(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.intensity(expression) + } else { + Logger.e("RNMBXRain", "Expression for intensity is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.intensity(value) + } else { + Logger.e("RNMBXRain", "value for intensity is null") + } + } + } + + + fun setIntensityTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.intensityTransition(transition); + } + } + + fun setColor(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.color(expression) + } else { + Logger.e("RNMBXRain", "Expression for color is null") + } + } else { + val value = styleValue.getInt(VALUE_KEY) + if (value != null) { + layer.color(value) + } else { + Logger.e("RNMBXRain", "value for color is null") + } + } + } + + + fun setColorTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.colorTransition(transition); + } + } + + fun setOpacity(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.opacity(expression) + } else { + Logger.e("RNMBXRain", "Expression for opacity is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.opacity(value) + } else { + Logger.e("RNMBXRain", "value for opacity is null") + } + } + } + + + fun setOpacityTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.opacityTransition(transition); + } + } + + fun setVignette(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.vignette(expression) + } else { + Logger.e("RNMBXRain", "Expression for vignette is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.vignette(value) + } else { + Logger.e("RNMBXRain", "value for vignette is null") + } + } + } + + + fun setVignetteTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.vignetteTransition(transition); + } + } + + fun setVignetteColor(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.vignetteColor(expression) + } else { + Logger.e("RNMBXRain", "Expression for vignetteColor is null") + } + } else { + val value = styleValue.getInt(VALUE_KEY) + if (value != null) { + layer.vignetteColor(value) + } else { + Logger.e("RNMBXRain", "value for vignetteColor is null") + } + } + } + + + fun setVignetteColorTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.vignetteColorTransition(transition); + } + } + + fun setCenterThinning(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.centerThinning(expression) + } else { + Logger.e("RNMBXRain", "Expression for centerThinning is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.centerThinning(value) + } else { + Logger.e("RNMBXRain", "value for centerThinning is null") + } + } + } + + + fun setCenterThinningTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.centerThinningTransition(transition); + } + } + + fun setDirection(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.direction(expression) + } else { + Logger.e("RNMBXRain", "Expression for direction is null") + } + } else { + val value = styleValue.getFloatArray(VALUE_KEY) + if (value != null) { + layer.direction(value) + } else { + Logger.e("RNMBXRain", "value for direction is null") + } + } + } + + + fun setDirectionTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.directionTransition(transition); + } + } + + fun setDropletSize(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.dropletSize(expression) + } else { + Logger.e("RNMBXRain", "Expression for dropletSize is null") + } + } else { + val value = styleValue.getFloatArray(VALUE_KEY) + if (value != null) { + layer.dropletSize(value) + } else { + Logger.e("RNMBXRain", "value for dropletSize is null") + } + } + } + + + fun setDropletSizeTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.dropletSizeTransition(transition); + } + } + + fun setDistortionStrength(layer: Rain, styleValue: RNMBXStyleValue ) { + if (styleValue.isExpression()) { + val expression = styleValue.getExpression() + if (expression != null) { + layer.distortionStrength(expression) + } else { + Logger.e("RNMBXRain", "Expression for distortionStrength is null") + } + } else { + val value = styleValue.getDouble(VALUE_KEY) + if (value != null) { + layer.distortionStrength(value) + } else { + Logger.e("RNMBXRain", "value for distortionStrength is null") + } + } + } + + + fun setDistortionStrengthTransition(layer: Rain, styleValue: RNMBXStyleValue) { + val transition = styleValue.transition + if (transition != null) { + layer.distortionStrengthTransition(transition); + } + } + fun setExaggeration(layer: Terrain, styleValue: RNMBXStyleValue ) { if (styleValue.isExpression()) { val expression = styleValue.getExpression() diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/atmosphere/RNMBXAtmosphere.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/atmosphere/RNMBXAtmosphere.kt index 8a55b1fd62..edd133f232 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/atmosphere/RNMBXAtmosphere.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/atmosphere/RNMBXAtmosphere.kt @@ -4,8 +4,7 @@ import android.content.Context import com.facebook.react.bridge.ReadableMap import com.mapbox.maps.MapboxMap import com.mapbox.maps.extension.style.atmosphere.generated.Atmosphere -import com.mapbox.maps.extension.style.terrain.generated.Terrain -import com.mapbox.maps.extension.style.terrain.generated.removeTerrain +import com.mapbox.maps.extension.style.atmosphere.generated.removeAtmosphere import com.rnmapbox.rnmbx.components.RemovalReason import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView import com.rnmapbox.rnmbx.components.styles.RNMBXStyle @@ -42,7 +41,8 @@ class RNMBXAtmosphere(context: Context?) : AbstractSourceConsumer(context) { } override fun removeFromMap(mapView: RNMBXMapView, reason: RemovalReason): Boolean { - mapView.savedStyle?.let { it.removeTerrain() } + mapView.savedStyle?.let { it.removeAtmosphere() } + mAtmosphere = null mMap = null return super.removeFromMap(mapView, reason) } @@ -55,7 +55,7 @@ class RNMBXAtmosphere(context: Context?) : AbstractSourceConsumer(context) { mAtmosphere?.also { RNMBXStyleFactory.setAtmosphereLayerStyle( it, RNMBXStyle( - context, mReactStyle!!, + context, mReactStyle, mMap!! ) ) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/atmosphere/RNMBXAtmosphereManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/atmosphere/RNMBXAtmosphereManager.kt index 0bef3eb994..fc50e20eb2 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/atmosphere/RNMBXAtmosphereManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/atmosphere/RNMBXAtmosphereManager.kt @@ -2,6 +2,7 @@ package com.rnmapbox.rnmbx.components.styles.atmosphere import com.facebook.react.bridge.Dynamic import com.facebook.react.uimanager.ThemedReactContext +import com.rnmapbox.rnmbx.utils.extensions.asMapOrNull import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.ViewManagerDelegate import com.facebook.react.uimanager.annotations.ReactProp @@ -30,7 +31,7 @@ class RNMBXAtmosphereManager : ViewGroupManager(), RNMBXAtmosph @ReactProp(name = "reactStyle") override fun setReactStyle(atmosphere: RNMBXAtmosphere, reactStyle: Dynamic) { - atmosphere.setReactStyle(reactStyle.asMap()) + atmosphere.setReactStyle(reactStyle.asMapOrNull()) } companion object { diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/layers/RNMBXHillshadeLayer.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/layers/RNMBXHillshadeLayer.kt new file mode 100644 index 0000000000..7771e7993d --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/layers/RNMBXHillshadeLayer.kt @@ -0,0 +1,27 @@ +package com.rnmapbox.rnmbx.components.styles.layers + +import android.content.Context +import com.mapbox.maps.extension.style.layers.generated.HillshadeLayer +import com.rnmapbox.rnmbx.components.styles.RNMBXStyle +import com.rnmapbox.rnmbx.components.styles.RNMBXStyleFactory +import com.rnmapbox.rnmbx.utils.Logger + +class RNMBXHillshadeLayer(context: Context?) : RNMBXLayer( + context!! +) { + override fun makeLayer(): HillshadeLayer { + return HillshadeLayer(iD!!, mSourceID!!) + } + + override fun addStyles() { + mLayer?.also { + RNMBXStyleFactory.setHillshadeLayerStyle(it, RNMBXStyle(context, mReactStyle, mMap!!)) + } ?: run { + Logger.e("RNMBXHillshadeLayer", "mLayer is null") + } + } + + fun setSourceLayerID(asString: String?) { + // no-op + } +} diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/layers/RNMBXHillshadeLayerManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/layers/RNMBXHillshadeLayerManager.kt new file mode 100644 index 0000000000..fe6fcd1c2d --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/layers/RNMBXHillshadeLayerManager.kt @@ -0,0 +1,84 @@ +package com.rnmapbox.rnmbx.components.styles.layers + +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.RNMBXHillshadeLayerManagerInterface + +class RNMBXHillshadeLayerManager : ViewGroupManager(), + RNMBXHillshadeLayerManagerInterface { + override fun getName(): String { + return REACT_CLASS + } + + override fun createViewInstance(reactContext: ThemedReactContext): RNMBXHillshadeLayer { + return RNMBXHillshadeLayer(reactContext) + } + + // @{codepart-replace-start(LayerManagerCommonProps.codepart-kt.ejs,{layerType:"RNMBXHillshadeLayer"})} + @ReactProp(name = "id") + override fun setId(layer: RNMBXHillshadeLayer, id: Dynamic) { + layer.iD = id.asString() + } + + @ReactProp(name = "existing") + override fun setExisting(layer: RNMBXHillshadeLayer, existing: Dynamic) { + layer.setExisting(existing.asBoolean()) + } + + @ReactProp(name = "sourceID") + override fun setSourceID(layer: RNMBXHillshadeLayer, sourceID: Dynamic) { + layer.setSourceID(sourceID.asString()) + } + + @ReactProp(name = "aboveLayerID") + override fun setAboveLayerID(layer: RNMBXHillshadeLayer, aboveLayerID: Dynamic) { + layer.setAboveLayerID(aboveLayerID.asString()) + } + + @ReactProp(name = "belowLayerID") + override fun setBelowLayerID(layer: RNMBXHillshadeLayer, belowLayerID: Dynamic) { + layer.setBelowLayerID(belowLayerID.asString()) + } + + @ReactProp(name = "layerIndex") + override fun setLayerIndex(layer: RNMBXHillshadeLayer, layerIndex: Dynamic) { + layer.setLayerIndex(layerIndex.asInt()) + } + + @ReactProp(name = "minZoomLevel") + override fun setMinZoomLevel(layer: RNMBXHillshadeLayer, minZoomLevel: Dynamic) { + layer.setMinZoomLevel(minZoomLevel.asDouble()) + } + + @ReactProp(name = "maxZoomLevel") + override fun setMaxZoomLevel(layer: RNMBXHillshadeLayer, maxZoomLevel: Dynamic) { + layer.setMaxZoomLevel(maxZoomLevel.asDouble()) + } + + @ReactProp(name = "reactStyle") + override fun setReactStyle(layer: RNMBXHillshadeLayer, style: Dynamic) { + layer.setReactStyle(style.asMap()) + } + + @ReactProp(name = "sourceLayerID") + override fun setSourceLayerID(layer: RNMBXHillshadeLayer, sourceLayerID: Dynamic) { + layer.setSourceLayerID(sourceLayerID.asString()) + } + + @ReactProp(name = "filter") + override fun setFilter(layer: RNMBXHillshadeLayer, filterList: Dynamic) { + layer.setFilter(filterList.asArray()) + } + + @ReactProp(name = "slot") + override fun setSlot(layer: RNMBXHillshadeLayer, slot: Dynamic) { + layer.setSlot(slot.asString()) + } + // @{codepart-replace-end} + + companion object { + const val REACT_CLASS = "RNMBXHillshadeLayer" + } +} 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 index 8f2227c36a..fe7e4eef60 100644 --- 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 @@ -2,6 +2,7 @@ package com.rnmapbox.rnmbx.components.styles.light import com.facebook.react.bridge.Dynamic import com.facebook.react.uimanager.ThemedReactContext +import com.rnmapbox.rnmbx.utils.extensions.asMapOrNull import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.annotations.ReactProp import com.facebook.react.viewmanagers.RNMBXLightManagerInterface @@ -18,7 +19,7 @@ class RNMBXLightManager : ViewGroupManager(), @ReactProp(name = "reactStyle") override fun setReactStyle(light: RNMBXLight, reactStyle: Dynamic) { - light.setReactStyle(reactStyle.asMap()) + light.setReactStyle(reactStyle.asMapOrNull()) } companion object { diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/rain/RNMBXRain.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/rain/RNMBXRain.kt new file mode 100644 index 0000000000..b1604b2075 --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/rain/RNMBXRain.kt @@ -0,0 +1,83 @@ +package com.rnmapbox.rnmbx.components.styles.rain + +import android.content.Context +import com.facebook.react.bridge.ReadableMap +import com.mapbox.maps.MapboxMap +import com.mapbox.maps.extension.style.precipitations.generated.Rain +import com.mapbox.maps.extension.style.precipitations.generated.removeRain +import com.rnmapbox.rnmbx.components.RemovalReason +import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView +import com.rnmapbox.rnmbx.components.styles.RNMBXStyle +import com.rnmapbox.rnmbx.components.styles.RNMBXStyleFactory +import com.rnmapbox.rnmbx.components.styles.sources.AbstractSourceConsumer +import com.rnmapbox.rnmbx.utils.Logger + +class RNMBXRain(context: Context?) : AbstractSourceConsumer(context) { + override var iD: String? = null + protected var mRain: Rain? = null + + // beginregion RNMBXLayer + @JvmField + protected var mMap: MapboxMap? = null + + @JvmField + protected var mReactStyle: ReadableMap? = null + + fun setReactStyle(reactStyle: ReadableMap?) { + mReactStyle = reactStyle + if (mRain != null) { + addStyles() + } + } + // endregion RNMBXLayer + + override fun addToMap(mapView: RNMBXMapView) { + super.addToMap(mapView) + mMap = mapView.getMapboxMap() + mapView.savedStyle?.let { warnIfMeasureLightUnavailable(it) } + val rain = makeRain() + mRain = rain + addStyles() + mapView.savedStyle?.let { rain.bindTo(it) } + } + + private fun warnIfMeasureLightUnavailable(style: com.mapbox.maps.Style) { + val hasLights = style.getStyleLights().isNotEmpty() + if (hasLights) return + + val affectedProps = listOf("color", "opacity", "vignetteColor") + val missingProps = affectedProps.filter { mReactStyle?.hasKey(it) != true } + if (missingProps.isEmpty()) return + + Logger.w( + "RNMBXRain", + "The current style has no 3D lights, so measure-light(\"brightness\") " + + "expressions used in default rain ${missingProps.joinToString(", ")} will fail. " + + "Use a Standard style or set explicit values for: ${missingProps.joinToString(", ")}" + ) + } + + override fun removeFromMap(mapView: RNMBXMapView, reason: RemovalReason): Boolean { + mapView.savedStyle?.let { it.removeRain() } + mRain = null + mMap = null + return super.removeFromMap(mapView, reason) + } + + fun makeRain(): Rain { + return Rain() + } + + fun addStyles() { + mRain?.also { + RNMBXStyleFactory.setRainLayerStyle( + it, RNMBXStyle( + context, mReactStyle, + mMap!! + ) + ) + } ?: run { + Logger.e("RNMBXRain", "mRain is null") + } + } +} diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/rain/RNMBXRainManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/rain/RNMBXRainManager.kt new file mode 100644 index 0000000000..5d1d409675 --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/rain/RNMBXRainManager.kt @@ -0,0 +1,40 @@ +package com.rnmapbox.rnmbx.components.styles.rain + +import com.facebook.react.bridge.Dynamic +import com.facebook.react.uimanager.ThemedReactContext +import com.rnmapbox.rnmbx.utils.extensions.asMapOrNull +import com.facebook.react.uimanager.ViewGroupManager +import com.facebook.react.uimanager.ViewManagerDelegate +import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.RNMBXRainManagerDelegate +import com.facebook.react.viewmanagers.RNMBXRainManagerInterface + +class RNMBXRainManager : ViewGroupManager(), RNMBXRainManagerInterface { + + private val mDelegate: ViewManagerDelegate + + init { + mDelegate = RNMBXRainManagerDelegate(this) + } + + override fun getDelegate(): ViewManagerDelegate { + return mDelegate + } + + override fun getName(): String { + return REACT_CLASS + } + + override fun createViewInstance(reactContext: ThemedReactContext): RNMBXRain { + return RNMBXRain(reactContext) + } + + @ReactProp(name = "reactStyle") + override fun setReactStyle(rain: RNMBXRain, reactStyle: Dynamic) { + rain.setReactStyle(reactStyle.asMapOrNull()) + } + + companion object { + const val REACT_CLASS = "RNMBXRain" + } +} diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/snow/RNMBXSnow.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/snow/RNMBXSnow.kt new file mode 100644 index 0000000000..1f26dd9ab5 --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/snow/RNMBXSnow.kt @@ -0,0 +1,66 @@ +package com.rnmapbox.rnmbx.components.styles.snow + +import android.content.Context +import com.facebook.react.bridge.ReadableMap +import com.mapbox.maps.MapboxMap +import com.mapbox.maps.extension.style.precipitations.generated.Snow +import com.mapbox.maps.extension.style.precipitations.generated.removeSnow +import com.rnmapbox.rnmbx.components.RemovalReason +import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView +import com.rnmapbox.rnmbx.components.styles.RNMBXStyle +import com.rnmapbox.rnmbx.components.styles.RNMBXStyleFactory +import com.rnmapbox.rnmbx.components.styles.sources.AbstractSourceConsumer +import com.rnmapbox.rnmbx.utils.Logger + +class RNMBXSnow(context: Context?) : AbstractSourceConsumer(context) { + override var iD: String? = null + protected var mSnow: Snow? = null + + // beginregion RNMBXLayer + @JvmField + protected var mMap: MapboxMap? = null + + @JvmField + protected var mReactStyle: ReadableMap? = null + + fun setReactStyle(reactStyle: ReadableMap?) { + mReactStyle = reactStyle + if (mSnow != null) { + addStyles() + } + } + // endregion RNMBXLayer + + override fun addToMap(mapView: RNMBXMapView) { + super.addToMap(mapView) + mMap = mapView.getMapboxMap() + val snow = makeSnow() + mSnow = snow + addStyles() + mapView.savedStyle?.let { snow.bindTo(it) } + } + + override fun removeFromMap(mapView: RNMBXMapView, reason: RemovalReason): Boolean { + mapView.savedStyle?.let { it.removeSnow() } + mSnow = null + mMap = null + return super.removeFromMap(mapView, reason) + } + + fun makeSnow(): Snow { + return Snow() + } + + fun addStyles() { + mSnow?.also { + RNMBXStyleFactory.setSnowLayerStyle( + it, RNMBXStyle( + context, mReactStyle, + mMap!! + ) + ) + } ?: run { + Logger.e("RNMBXSnow", "mSnow is null") + } + } +} diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/snow/RNMBXSnowManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/snow/RNMBXSnowManager.kt new file mode 100644 index 0000000000..31edfb5068 --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/snow/RNMBXSnowManager.kt @@ -0,0 +1,40 @@ +package com.rnmapbox.rnmbx.components.styles.snow + +import com.facebook.react.bridge.Dynamic +import com.facebook.react.uimanager.ThemedReactContext +import com.rnmapbox.rnmbx.utils.extensions.asMapOrNull +import com.facebook.react.uimanager.ViewGroupManager +import com.facebook.react.uimanager.ViewManagerDelegate +import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.RNMBXSnowManagerDelegate +import com.facebook.react.viewmanagers.RNMBXSnowManagerInterface + +class RNMBXSnowManager : ViewGroupManager(), RNMBXSnowManagerInterface { + + private val mDelegate: ViewManagerDelegate + + init { + mDelegate = RNMBXSnowManagerDelegate(this) + } + + override fun getDelegate(): ViewManagerDelegate { + return mDelegate + } + + override fun getName(): String { + return REACT_CLASS + } + + override fun createViewInstance(reactContext: ThemedReactContext): RNMBXSnow { + return RNMBXSnow(reactContext) + } + + @ReactProp(name = "reactStyle") + override fun setReactStyle(snow: RNMBXSnow, reactStyle: Dynamic) { + snow.setReactStyle(reactStyle.asMapOrNull()) + } + + companion object { + const val REACT_CLASS = "RNMBXSnow" + } +} diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/sources/RNMBXSource.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/sources/RNMBXSource.kt index a3cdf28df7..3dec5bbe5a 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/styles/sources/RNMBXSource.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/styles/sources/RNMBXSource.kt @@ -6,22 +6,18 @@ import com.mapbox.maps.extension.style.sources.addSource import com.rnmapbox.rnmbx.components.AbstractMapFeature import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView import com.mapbox.maps.MapboxMap -import com.rnmapbox.rnmbx.components.styles.sources.AbstractSourceConsumer import com.facebook.react.bridge.ReadableMap -import com.rnmapbox.rnmbx.components.styles.sources.RNMBXSource -import android.graphics.PointF import android.view.View import com.facebook.react.common.MapBuilder import com.mapbox.geojson.Feature +import com.mapbox.maps.ScreenCoordinate import com.mapbox.maps.Style import com.mapbox.maps.extension.style.StyleContract import com.mapbox.maps.extension.style.sources.Source import com.rnmapbox.rnmbx.components.RemovalReason -import com.rnmapbox.rnmbx.components.styles.sources.RNMBXSource.OnPressEvent import com.rnmapbox.rnmbx.utils.LatLng import com.rnmapbox.rnmbx.utils.Logger import java.lang.ClassCastException -import java.util.ArrayList import java.util.HashMap data class FeatureInfo(val feature: AbstractMapFeature?, var added: Boolean) { @@ -221,7 +217,7 @@ abstract class RNMBXSource(context: Context?) : AbstractMapFeature( abstract fun makeSource(): T - class OnPressEvent(var features: List, var latLng: LatLng, var screenPoint: PointF) + class OnPressEvent(var features: List, var latLng: LatLng, var screenPoint: ScreenCoordinate) abstract fun onPress(event: OnPressEvent?) 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 02a436f8ac..a0db9371b5 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 @@ -2,6 +2,7 @@ package com.rnmapbox.rnmbx.components.styles.terrain import com.facebook.react.bridge.Dynamic import com.facebook.react.uimanager.ThemedReactContext +import com.rnmapbox.rnmbx.utils.extensions.asMapOrNull import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.annotations.ReactProp import com.facebook.react.viewmanagers.RNMBXTerrainManagerInterface @@ -23,7 +24,7 @@ class RNMBXTerrainManager : ViewGroupManager(), @ReactProp(name = "reactStyle") override fun setReactStyle(terrain: RNMBXTerrain, reactStyle: Dynamic) { - terrain.setReactStyle(reactStyle.asMap()) + terrain.setReactStyle(reactStyle.asMapOrNull()) } companion object { diff --git a/android/src/main/java/com/rnmapbox/rnmbx/events/FeatureClickEvent.java b/android/src/main/java/com/rnmapbox/rnmbx/events/FeatureClickEvent.java index 6a53837d53..175aeb1d68 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/events/FeatureClickEvent.java +++ b/android/src/main/java/com/rnmapbox/rnmbx/events/FeatureClickEvent.java @@ -1,16 +1,15 @@ package com.rnmapbox.rnmbx.events; -import android.graphics.PointF; import android.view.View; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; import com.mapbox.geojson.Feature; +import com.mapbox.maps.ScreenCoordinate; import com.rnmapbox.rnmbx.components.styles.sources.RNMBXSource; import com.rnmapbox.rnmbx.events.constants.EventKeys; import com.rnmapbox.rnmbx.events.constants.EventTypes; -import com.rnmapbox.rnmbx.utils.ConvertUtils; import com.rnmapbox.rnmbx.utils.GeoJSONUtils; import com.rnmapbox.rnmbx.utils.LatLng; @@ -24,9 +23,9 @@ public class FeatureClickEvent extends AbstractEvent { private String mEventKey; private List mFeatures; private LatLng mLatLng; - private PointF mPoint; + private ScreenCoordinate mPoint; - public FeatureClickEvent(View view, String eventKey, String eventType, List features, LatLng latLng, PointF point) { + public FeatureClickEvent(View view, String eventKey, String eventType, List features, LatLng latLng, ScreenCoordinate point) { super(view, eventType); mFeatures = features; mEventKey = eventKey; @@ -55,8 +54,8 @@ public WritableMap getPayload() { map.putMap("coordinates", coordinates); WritableMap point = Arguments.createMap(); - point.putDouble("x", mPoint.x); - point.putDouble("y", mPoint.y); + point.putDouble("x", mPoint.getX()); + point.putDouble("y", mPoint.getY()); map.putMap("point", point); return map; diff --git a/android/src/main/java/com/rnmapbox/rnmbx/events/MapSteadyEvent.kt b/android/src/main/java/com/rnmapbox/rnmbx/events/MapSteadyEvent.kt index 18d9f99815..80cff669c6 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/events/MapSteadyEvent.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/events/MapSteadyEvent.kt @@ -7,7 +7,7 @@ import com.facebook.react.bridge.WritableMap /** * Direct event for CameraGestureObserver -> onMapSteady * JS registrationName: onMapSteady - * Native event name (key): topOnMapSteady + * Native event name (key): onMapSteady */ class MapSteadyEvent( view: View?, @@ -16,7 +16,7 @@ class MapSteadyEvent( private val lastGestureType: String? ) : AbstractEvent(view, "mapSteady") { override val key: String - get() = "topOnMapSteady" + get() = "onMapSteady" override val payload: WritableMap get() = Arguments.createMap().apply { @@ -34,6 +34,12 @@ class MapSteadyEvent( putDouble("timestamp", System.currentTimeMillis().toDouble()) } + override fun toJSON(): WritableMap { + val map = Arguments.createMap() + map.merge(payload) + return map + } + override fun canCoalesce(): Boolean { // Do not coalesce - each steady/timeout event is significant return false diff --git a/android/src/main/java/com/rnmapbox/rnmbx/events/RNMBXCameraGestureObserver.kt b/android/src/main/java/com/rnmapbox/rnmbx/events/RNMBXCameraGestureObserver.kt index 52a99143f9..dbeced9976 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/events/RNMBXCameraGestureObserver.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/events/RNMBXCameraGestureObserver.kt @@ -37,7 +37,6 @@ class RNMBXCameraGestureObserver( private var lastTransitionEndedAtMs: Double? = null private var quietRunnable: Runnable? = null private var timeoutRunnable: Runnable? = null - private var emittedForCurrentActivity: Boolean = false private val quietMs: Double get() = quietPeriodMs ?: 200.0 private val maxMs: Double? get() = maxIntervalMs @@ -84,9 +83,9 @@ class RNMBXCameraGestureObserver( } private fun scheduleQuietCheck() { + cancelQuietTimer() val delay = quietMs if (delay <= 0) { - cancelQuietTimer() maybeEmitSteady() return } @@ -99,8 +98,10 @@ class RNMBXCameraGestureObserver( } private fun scheduleTimeout() { + if (timeoutRunnable != null) return val delay = maxMs ?: return val runnable = Runnable { + timeoutRunnable = null emitTimeout() } timeoutRunnable = scheduleTimer(delay, runnable) @@ -108,7 +109,6 @@ class RNMBXCameraGestureObserver( private fun markActivity(gestureType: String? = null) { if (gestureType != null) lastGestureType = gestureType - emittedForCurrentActivity = false scheduleQuietCheck() scheduleTimeout() } @@ -122,7 +122,6 @@ class RNMBXCameraGestureObserver( } private fun emitSteady(idleDurationMs: Double) { - if (emittedForCurrentActivity) return cancelQuietTimer() cancelTimeoutTimer() val gesture = lastGestureType @@ -131,7 +130,6 @@ class RNMBXCameraGestureObserver( MapSteadyEvent.make(this, "steady", idleDurationMs, gesture) ) lastGestureType = null - emittedForCurrentActivity = true } private fun emitTimeout() { diff --git a/android/src/main/java/com/rnmapbox/rnmbx/events/RNMBXCameraGestureObserverManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/events/RNMBXCameraGestureObserverManager.kt index c0d5865ed0..7708ced26f 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/events/RNMBXCameraGestureObserverManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/events/RNMBXCameraGestureObserverManager.kt @@ -65,7 +65,7 @@ class RNMBXCameraGestureObserverManager(private val mContext: ReactApplicationCo // Map the native event name to the JS registration name for direct events override fun customEvents(): Map = mapOf( - "topOnMapSteady" to "onMapSteady" + "onMapSteady" to "onMapSteady" ) companion object { diff --git a/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXModule.kt b/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXModule.kt index 1f2d594ab3..b236fdf60d 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXModule.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXModule.kt @@ -114,6 +114,7 @@ class RNMBXModule(private val mReactContext: ReactApplicationContext) : ReactCon val locationModuleCallbackNames: MutableMap = HashMap() locationModuleCallbackNames["Update"] = RNMBXLocationModule.LOCATION_UPDATE return MapBuilder.builder() + // Deprecated: means v10 or later, always true. Will be removed in next major version. .put("MapboxV10", true) .put("StyleURL", styleURLS) .put("EventTypes", eventTypes) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXSnapshotModule.kt b/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXSnapshotModule.kt index 415763509d..771884c6d6 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXSnapshotModule.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXSnapshotModule.kt @@ -8,10 +8,13 @@ import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.ReadableMap import com.facebook.react.module.annotations.ReactModule import com.mapbox.geojson.Feature +import com.mapbox.geojson.FeatureCollection import com.mapbox.geojson.Point import com.mapbox.maps.CameraOptions +import com.mapbox.maps.EdgeInsets import com.mapbox.maps.MapSnapshotOptions import com.mapbox.maps.Size +import com.mapbox.maps.SnapshotOverlayOptions import com.mapbox.maps.Snapshotter import com.rnmapbox.rnmbx.modules.RNMBXModule.Companion.getAccessToken import com.rnmapbox.rnmbx.modules.RNMBXSnapshotModule @@ -43,30 +46,38 @@ class RNMBXSnapshotModule(private val mContext: ReactApplicationContext) : // FileSource.getInstance(mContext).activate(); mContext.runOnUiQueueThread { val snapshotterID = UUID.randomUUID().toString() - val snapshotter = Snapshotter(mContext, getOptions(jsOptions)) + val showLogo = if (jsOptions.hasKey("withLogo")) jsOptions.getBoolean("withLogo") else true + val overlayOptions = SnapshotOverlayOptions(showLogo = showLogo) + val snapshotter = Snapshotter(mContext, getOptions(jsOptions), overlayOptions) snapshotter.setStyleUri(jsOptions.getString("styleURL")!!) - snapshotter.setCamera(getCameraOptions(jsOptions)) + try { + snapshotter.setCamera(getCameraOptions(jsOptions, snapshotter)) + } catch (e: IllegalArgumentException) { + promise.reject(REACT_CLASS, e.message, e) + return@runOnUiQueueThread + } mSnapshotterMap[snapshotterID] = snapshotter - snapshotter.startV11 { image,error -> + + snapshotter.start(null) { image, error -> try { if (image == null) { Log.w(REACT_CLASS, "Snapshot failed: $error") promise.reject(REACT_CLASS, "Snapshot failed: $error") mSnapshotterMap.remove(snapshotterID) } else { - val image = image.toMapboxImage() + val mapboxImage = image.toMapboxImage() var result: String? = null result = if (jsOptions.getBoolean("writeToDisk")) { - BitmapUtils.createImgTempFile(mContext, image) + BitmapUtils.createImgTempFile(mContext, mapboxImage) } else { - BitmapUtils.createImgBase64(image) + BitmapUtils.createImgBase64(mapboxImage) } if (result == null) { promise.reject( REACT_CLASS, "Could not generate snapshot, please check Android logs for more info." ) - return@startV11 + return@start } promise.resolve(result) mSnapshotterMap.remove(snapshotterID) @@ -79,17 +90,44 @@ class RNMBXSnapshotModule(private val mContext: ReactApplicationContext) : } } - private fun getCameraOptions(jsOptions: ReadableMap): CameraOptions { - val centerPoint = - Feature.fromJson(jsOptions.getString("centerCoordinate")!!) - val point = centerPoint.geometry() as Point? - val cameraOptionsBuilder = CameraOptions.Builder() - return cameraOptionsBuilder - .center(point) - .pitch(jsOptions.getDouble("pitch")) - .bearing(jsOptions.getDouble("heading")) - .zoom(jsOptions.getDouble("zoomLevel")) - .build() + private fun getCameraOptions(jsOptions: ReadableMap, snapshotter: Snapshotter): CameraOptions { + val pitch = jsOptions.getDouble("pitch") + val heading = jsOptions.getDouble("heading") + val zoomLevel = jsOptions.getDouble("zoomLevel") + + // Check if centerCoordinate is provided + if (jsOptions.hasKey("centerCoordinate") && !jsOptions.isNull("centerCoordinate")) { + val centerPoint = Feature.fromJson(jsOptions.getString("centerCoordinate")!!) + val point = centerPoint.geometry() as Point? + return CameraOptions.Builder() + .center(point) + .pitch(pitch) + .bearing(heading) + .zoom(zoomLevel) + .build() + } + + // Check if bounds is provided + if (jsOptions.hasKey("bounds") && !jsOptions.isNull("bounds")) { + val boundsJson = jsOptions.getString("bounds")!! + val featureCollection = FeatureCollection.fromJson(boundsJson) + val coords = featureCollection.features()?.mapNotNull { feature -> + feature.geometry() as? Point + } ?: emptyList() + + if (coords.isEmpty()) { + throw IllegalArgumentException("bounds contains no valid coordinates") + } + + return snapshotter.cameraForCoordinates( + coords, + EdgeInsets(0.0, 0.0, 0.0, 0.0), + heading, + pitch + ) + } + + throw IllegalArgumentException("neither centerCoordinate nor bounds provided") } private fun getOptions(jsOptions: ReadableMap): MapSnapshotOptions { diff --git a/android/src/main/java/com/rnmapbox/rnmbx/utils/ConvertUtils.kt b/android/src/main/java/com/rnmapbox/rnmbx/utils/ConvertUtils.kt index 2fc289f65b..3a2ce430a2 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/utils/ConvertUtils.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/utils/ConvertUtils.kt @@ -1,7 +1,5 @@ package com.rnmapbox.rnmbx.utils -import android.graphics.PointF -import android.graphics.RectF import android.util.Log import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.NoSuchKeyException @@ -172,34 +170,6 @@ object ConvertUtils { return list } - fun toPointF(array: ReadableArray?): PointF { - val pointF = PointF() - - if (array == null) { - return pointF - } - - pointF.set(array.getDouble(0).toFloat(), array.getDouble(1).toFloat()) - return pointF - } - - // returns null if array is null - fun toRectF(array: ReadableArray?): RectF? { - val rectF = RectF() - - if (array == null || array.size() == 0) { - return null - } - - rectF.set( - array.getDouble(3).toFloat(), - array.getDouble(0).toFloat(), - array.getDouble(1).toFloat(), - array.getDouble(2).toFloat() - ) - return rectF - } - fun getDouble(key: String, map: ReadableMap, defaultValue: Double): Double { var value = defaultValue diff --git a/android/src/main/java/com/rnmapbox/rnmbx/utils/extensions/Dynamic.kt b/android/src/main/java/com/rnmapbox/rnmbx/utils/extensions/Dynamic.kt index b5b5f791b3..9e4b55c857 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/utils/extensions/Dynamic.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/utils/extensions/Dynamic.kt @@ -107,4 +107,6 @@ fun Dynamic.asStringOrNull(): String? { } else { asString() } -} \ No newline at end of file +} + +fun Dynamic.asMapOrNull(): ReadableMap? = if (isNull) null else asMap() \ No newline at end of file diff --git a/android/src/main/java/com/rnmapbox/rnmbx/utils/extensions/ReadableArray.kt b/android/src/main/java/com/rnmapbox/rnmbx/utils/extensions/ReadableArray.kt index 9a48ba9af6..bf878c7d95 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/utils/extensions/ReadableArray.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/utils/extensions/ReadableArray.kt @@ -1,17 +1,15 @@ package com.rnmapbox.rnmbx.utils.extensions -import android.graphics.RectF import com.facebook.react.bridge.ReadableArray import com.facebook.react.bridge.ReadableType import com.google.gson.JsonArray import com.google.gson.JsonElement import com.mapbox.geojson.Point +import com.mapbox.maps.ScreenBox import com.mapbox.maps.ScreenCoordinate -import com.rnmapbox.rnmbx.utils.ConvertUtils import com.rnmapbox.rnmbx.utils.Logger -import org.json.JSONArray -import java.lang.Float.max -import java.lang.Float.min +import kotlin.math.max +import kotlin.math.min fun ReadableArray.toCoordinate() : Point { if (this.size() != 2) { @@ -25,20 +23,24 @@ fun ReadableArray.toCoordinate() : Point { fun ReadableArray.toScreenCoordinate() : ScreenCoordinate { if (this.size() != 2) { - Logger.e("ReadableArray.toCoordinate","Cannot convert $this to point, 2 coordinates are required") + Logger.e("ReadableArray.toScreenCoordinate","Cannot convert $this to point, 2 coordinates are required") } return ScreenCoordinate(getDouble(0), getDouble(1)) } -fun ReadableArray.toRectF() : RectF? { - if (size() != 4) { - return null; +fun ReadableArray.toScreenBox() : ScreenBox { + if (this.size() != 4) { + Logger.e("ReadableArray.toScreenBox","Cannot convert $this to box, 4 coordinates are required") } - return RectF( - min(getDouble(3).toFloat(), getDouble(1).toFloat()), - min(getDouble(0).toFloat(), getDouble(2).toFloat()), - max(getDouble(3).toFloat(), getDouble(1).toFloat()), - max(getDouble(0).toFloat(), getDouble(2).toFloat()) + + val top = getDouble(0) + val left = getDouble(1) + val bottom = getDouble(2) + val right = getDouble(3) + + return ScreenBox( + ScreenCoordinate(min(left, right), min(top, bottom)), + ScreenCoordinate(max(left, right), max(top, bottom)) ) } diff --git a/docs/BackgroundLayer.md b/docs/BackgroundLayer.md index d8a61a2908..ec652758ef 100644 --- a/docs/BackgroundLayer.md +++ b/docs/BackgroundLayer.md @@ -201,7 +201,7 @@ The color with which the background will be drawn. #### Expression -Parameters: `zoom` +Parameters: `zoom, measure-light` ___ ### backgroundColorTransition diff --git a/docs/Camera.md b/docs/Camera.md index 18fcac86c6..c68535dffe 100644 --- a/docs/Camera.md +++ b/docs/Camera.md @@ -62,7 +62,7 @@ compatibility; the root `padding` prop should be used instead. ```tsx number ``` -The heading (orientation) of the map. +Heading (bearing, orientation) of the map, measured in degrees clockwise from true north. @@ -71,7 +71,7 @@ The heading (orientation) of the map. ```tsx number ``` -The pitch of the map. +The pitch toward the horizon measured in degrees, with 0 degrees resulting in a top-down view for a two-dimensional map. @@ -212,8 +212,8 @@ type DefaultSettings = { centerCoordinate: Position; /* The location on which the map should center. */ bounds: intersection; /* The corners of a box around which the map should bound. Contains padding props for backwards compatibility; the root `padding` prop should be used instead. */ - heading: number; /* The heading (orientation) of the map. */ - pitch: number; /* The pitch of the map. */ + heading: number; /* Heading (bearing, orientation) of the map, measured in degrees clockwise from true north. */ + pitch: number; /* The pitch toward the horizon measured in degrees, with 0 degrees resulting in a top-down view for a two-dimensional map. */ zoomLevel: number; /* The zoom level of the map. */ padding: signature; /* The viewport padding in points. */ animationDuration: number; /* The duration the map takes to animate to a new configuration. */ diff --git a/docs/HillshadeLayer.md b/docs/HillshadeLayer.md new file mode 100644 index 0000000000..2ca0a0e1f7 --- /dev/null +++ b/docs/HillshadeLayer.md @@ -0,0 +1,383 @@ + + + Mapbox spec: [hillshade](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#hillshade) + + +```tsx +import { HillshadeLayer } from '@rnmapbox/maps'; + +HillshadeLayer + +``` + + +## props + + +### id + +```tsx +string +``` +_required_ +A string that uniquely identifies the source in the style to which it is added. + + + +### existing + +```tsx +boolean +``` +The id refers to an existing layer in the style. Does not create a new layer. + + + +### sourceID + +```tsx +string +``` +The source from which to obtain the data to style. +If the source has not yet been added to the current style, the behavior is undefined. +Inferred from parent source only if the layer is a direct child to it. + + _defaults to:_ `Mapbox.StyleSource.DefaultSourceID` + + +### sourceLayerID + +```tsx +string +``` +Identifier of the layer within the source identified by the sourceID property from which the receiver obtains the data to style. + + + +### aboveLayerID + +```tsx +string +``` +Inserts a layer above aboveLayerID. + + + +### belowLayerID + +```tsx +string +``` +Inserts a layer below belowLayerID + + + +### layerIndex + +```tsx +number +``` +Inserts a layer at a specified index + + + +### filter + +```tsx +FilterExpression +``` +Filter only the features in the source layer that satisfy a condition that you define + + + +### minZoomLevel + +```tsx +number +``` +The minimum zoom level at which the layer gets parsed and appears. + + + +### maxZoomLevel + +```tsx +number +``` +The maximum zoom level at which the layer gets parsed and appears. + + + +### slot + +```tsx +'bottom' | 'middle' | 'top' +``` +The slot this layer is assigned to. If specified, and a slot with that name exists, it will be placed at that position in the layer order. + +v11 only + + + +### style + +```tsx +HillshadeLayerStyleProps +``` +_required_ +Customizable style attributes + + + + + + + + + +## styles + +* visibility
+* hillshadeIlluminationDirection
+* hillshadeIlluminationAnchor
+* hillshadeExaggeration
+* hillshadeShadowColor
+* hillshadeHighlightColor
+* hillshadeAccentColor
+ +___ + +### visibility +Name: `visibility` + +Mapbox spec: [visibility](https://docs.mapbox.com/style-spec/reference/layers/#layout-hillshade-visibility) + +#### Description +Whether this layer is displayed. + +#### Type +`enum` +#### Default Value +`visible` + +#### Supported Values +**visible** - The layer is shown.
+**none** - The layer is not shown.
+ + +#### Expression + +Parameters: `` + +___ + +### hillshadeIlluminationDirection +Name: `hillshadeIlluminationDirection` + +Mapbox spec: [hillshade-illumination-direction](https://docs.mapbox.com/style-spec/reference/layers/#paint-hillshade-hillshade-illumination-direction) + +#### Description +The direction of the light source used to generate the hillshading with 0 as the top of the viewport if `hillshadeIlluminationAnchor` is set to `viewport` and due north if `hillshadeIlluminationAnchor` is set to `map` and no 3d lights enabled. If `hillshadeIlluminationAnchor` is set to `map` and 3d lights enabled, the direction from 3d lights is used instead. + +#### Type +`number` +#### Default Value +`335` + +#### Minimum +`0` + + +#### Maximum +`359` + +#### Expression + +Parameters: `zoom` + +___ + +### hillshadeIlluminationAnchor +Name: `hillshadeIlluminationAnchor` + +Mapbox spec: [hillshade-illumination-anchor](https://docs.mapbox.com/style-spec/reference/layers/#paint-hillshade-hillshade-illumination-anchor) + +#### Description +Direction of light source when map is rotated. + +#### Type +`enum` +#### Default Value +`viewport` + +#### Supported Values +**map** - The hillshade illumination is relative to the north direction.
+**viewport** - The hillshade illumination is relative to the top of the viewport.
+ + +#### Expression + +Parameters: `zoom` + +___ + +### hillshadeExaggeration +Name: `hillshadeExaggeration` + +Mapbox spec: [hillshade-exaggeration](https://docs.mapbox.com/style-spec/reference/layers/#paint-hillshade-hillshade-exaggeration) + +#### Description +Intensity of the hillshade + +#### Type +`number` +#### Default Value +`0.5` + +#### Minimum +`0` + + +#### Maximum +`1` + +#### Expression + +Parameters: `zoom` +___ + +### hillshadeExaggerationTransition +Name: `hillshadeExaggerationTransition` + +#### Description + +The transition affecting any changes to this layer’s hillshadeExaggeration property. + +#### Type + +`{ duration, delay }` + +#### Units +`milliseconds` + +#### Default Value +`{duration: 300, delay: 0}` + + +___ + +### hillshadeShadowColor +Name: `hillshadeShadowColor` + +Mapbox spec: [hillshade-shadow-color](https://docs.mapbox.com/style-spec/reference/layers/#paint-hillshade-hillshade-shadow-color) + +#### Description +The shading color of areas that face away from the light source. + +#### Type +`color` +#### Default Value +`#000000` + + +#### Expression + +Parameters: `zoom, measure-light` +___ + +### hillshadeShadowColorTransition +Name: `hillshadeShadowColorTransition` + +#### Description + +The transition affecting any changes to this layer’s hillshadeShadowColor property. + +#### Type + +`{ duration, delay }` + +#### Units +`milliseconds` + +#### Default Value +`{duration: 300, delay: 0}` + + +___ + +### hillshadeHighlightColor +Name: `hillshadeHighlightColor` + +Mapbox spec: [hillshade-highlight-color](https://docs.mapbox.com/style-spec/reference/layers/#paint-hillshade-hillshade-highlight-color) + +#### Description +The shading color of areas that faces towards the light source. + +#### Type +`color` +#### Default Value +`#FFFFFF` + + +#### Expression + +Parameters: `zoom, measure-light` +___ + +### hillshadeHighlightColorTransition +Name: `hillshadeHighlightColorTransition` + +#### Description + +The transition affecting any changes to this layer’s hillshadeHighlightColor property. + +#### Type + +`{ duration, delay }` + +#### Units +`milliseconds` + +#### Default Value +`{duration: 300, delay: 0}` + + +___ + +### hillshadeAccentColor +Name: `hillshadeAccentColor` + +Mapbox spec: [hillshade-accent-color](https://docs.mapbox.com/style-spec/reference/layers/#paint-hillshade-hillshade-accent-color) + +#### Description +The shading color used to accentuate rugged terrain like sharp cliffs and gorges. + +#### Type +`color` +#### Default Value +`#000000` + + +#### Expression + +Parameters: `zoom, measure-light` +___ + +### hillshadeAccentColorTransition +Name: `hillshadeAccentColorTransition` + +#### Description + +The transition affecting any changes to this layer’s hillshadeAccentColor property. + +#### Type + +`{ duration, delay }` + +#### Units +`milliseconds` + +#### Default Value +`{duration: 300, delay: 0}` + + diff --git a/docs/LineLayer.md b/docs/LineLayer.md index 690aa8ef98..47e96fc68f 100644 --- a/docs/LineLayer.md +++ b/docs/LineLayer.md @@ -145,6 +145,7 @@ Customizable style attributes * lineElevationReference
* lineCrossSlope
* visibility
+* lineElevationGroundScale
* lineOpacity
* lineColor
* lineTranslate
@@ -161,6 +162,8 @@ Customizable style attributes * lineTrimFadeRange
* lineTrimColor
* lineEmissiveStrength
+* lineBorderWidth
+* lineBorderColor
* lineOcclusionOpacity
___ @@ -282,14 +285,7 @@ Name: `lineZOffset` Mapbox spec: [line-z-offset](https://docs.mapbox.com/style-spec/reference/layers/#layout-line-line-z-offset) #### Description -Vertical offset from ground, in meters. Defaults to 0. This is an experimental property with some known issues: - * Not supported for globe projection at the moment - * Elevated line discontinuity is possible on tile borders with terrain enabled - * Rendering artifacts can happen near line joins and line caps depending on the line styling - * Rendering artifacts relating to `lineOpacity` and `lineBlur` - * Elevated line visibility is determined by layer order - * ZFighting issues can happen with intersecting elevated lines - * Elevated lines don't cast shadows +Vertical offset from ground, in meters. Not supported for globe projection at the moment. #### Type `number` @@ -377,6 +373,54 @@ Whether this layer is displayed. Parameters: `` +___ + +### lineElevationGroundScale +Name: `lineElevationGroundScale` + +Mapbox spec: [line-elevation-ground-scale](https://docs.mapbox.com/style-spec/reference/layers/#layout-line-line-elevation-ground-scale) + +#### Description +Controls how much the elevation of lines with `lineElevationReference` set to `sea` scales with terrain exaggeration. A value of 0 keeps the line at a fixed altitude above sea level. A value of 1 scales the elevation proportionally with terrain exaggeration. + +#### Type +`number` +#### Default Value +`0` + +#### Minimum +`0` + + +#### Maximum +`1` + +#### Requires +`lineZOffset` + +#### Expression + +Parameters: `zoom, feature, line-progress` +___ + +### lineElevationGroundScaleTransition +Name: `lineElevationGroundScaleTransition` + +#### Description + +The transition affecting any changes to this layer’s lineElevationGroundScale property. + +#### Type + +`{ duration, delay }` + +#### Units +`milliseconds` + +#### Default Value +`{duration: 300, delay: 0}` + + ___ ### lineOpacity @@ -949,6 +993,87 @@ The transition affecting any changes to this layer’s lineEmissiveStrength prop `{duration: 300, delay: 0}` +___ + +### lineBorderWidth +Name: `lineBorderWidth` + +Mapbox spec: [line-border-width](https://docs.mapbox.com/style-spec/reference/layers/#paint-line-line-border-width) + +#### Description +The width of the line border. A value of zero means no border. + +#### Type +`number` +#### Default Value +`0` + +#### Minimum +`0` + + +#### Expression + +Parameters: `zoom, feature, feature-state` +___ + +### lineBorderWidthTransition +Name: `lineBorderWidthTransition` + +#### Description + +The transition affecting any changes to this layer’s lineBorderWidth property. + +#### Type + +`{ duration, delay }` + +#### Units +`milliseconds` + +#### Default Value +`{duration: 300, delay: 0}` + + +___ + +### lineBorderColor +Name: `lineBorderColor` + +Mapbox spec: [line-border-color](https://docs.mapbox.com/style-spec/reference/layers/#paint-line-line-border-color) + +#### Description +The color of the line border. If lineBorderWidth is greater than zero and the alpha value of this color is 0 (default), the color for the border will be selected automatically based on the line color. + +#### Type +`color` +#### Default Value +`rgba(0, 0, 0, 0)` + + +#### Expression + +Parameters: `zoom, feature, feature-state` +___ + +### lineBorderColorTransition +Name: `lineBorderColorTransition` + +#### Description + +The transition affecting any changes to this layer’s lineBorderColor property. + +#### Type + +`{ duration, delay }` + +#### Units +`milliseconds` + +#### Default Value +`{duration: 300, delay: 0}` + + ___ ### lineOcclusionOpacity diff --git a/docs/MapView.md b/docs/MapView.md index d2ad2d0c82..dbc7f1b0c4 100644 --- a/docs/MapView.md +++ b/docs/MapView.md @@ -253,7 +253,7 @@ boolean ``` [Android only] Enable/Disable use of GLSurfaceView instead of TextureView. - _defaults to:_ `RNMBXModule.MapboxV10 ? true : false` + _defaults to:_ `true` ### requestDisallowInterceptTouchEvent @@ -317,20 +317,20 @@ Gesture configuration allows to control the user touch interaction. ```tsx func ``` -Map press listener, gets called when a user presses the map +Map press listener, called when a user presses the map. *signature:*`(feature:GeoJSON.Feature) => void` -[Show Click](../examples/Map/ShowClick) +[Screen Coordinates](../examples/Map/ScreenCoordinates), [Show Click](../examples/Map/ShowClick) ### onLongPress ```tsx func ``` -Map long press listener, gets called when a user long presses the map +Map long press listener, called when a user long presses the map. *signature:*`(feature:GeoJSON.Feature) => void` - +[Screen Coordinates](../examples/Map/ScreenCoordinates) ### onRegionWillChange @@ -549,39 +549,42 @@ the onPress event for the taps that deselect the annotation. Default is false. ## methods ### getPointInView(coordinate) -Converts a geographic coordinate to a point in the given view’s coordinate system. +Converts a geographic coordinate to a screen coordinate relative to the map view. #### arguments | Name | Type | Required | Description | | ---- | :--: | :------: | :----------: | -| `coordinate` | `Position` | `Yes` | A point expressed in the map view's coordinate system. | +| `coordinate` | `Position` | `Yes` | A point expressed in the map view's coordinate system `[longitude, latitude]`. | ```javascript -const pointInView = await this._map.getPointInView([-37.817070, 144.949901]); +const longitude = 144.949901; +const latitude = -37.817070; +const [x, y] = await this._map.getPointInView([longitude, latitude]); ``` -### getCoordinateFromView(point) +[Screen Coordinates](../examples/Map/ScreenCoordinates)### getCoordinateFromView(point) -Converts a point in the given view’s coordinate system to a geographic coordinate. +Converts a screen coordinate relative to the map view to a geographic coordinate. #### arguments | Name | Type | Required | Description | | ---- | :--: | :------: | :----------: | -| `point` | `Position` | `Yes` | A point expressed in the given view’s coordinate system. | +| `point` | `Position` | `Yes` | A point expressed in screen coordinates relative to the map view `[x, y]`. | ```javascript -const coordinate = await this._map.getCoordinateFromView([100, 100]); +const x = 100; const y = 100; +const [longitude, latitude] = await this._map.getCoordinateFromView([x, y]); ``` -### getVisibleBounds() +[Screen Coordinates](../examples/Map/ScreenCoordinates)### getVisibleBounds() -The coordinate bounds (ne, sw) visible in the user’s viewport. +The coordinate bounds of the map viewport. #### arguments | Name | Type | Required | Description | @@ -591,7 +594,7 @@ The coordinate bounds (ne, sw) visible in the user’s viewport. ```javascript -const visibleBounds = await this._map.getVisibleBounds(); +const [[rightLon, topLat], [leftLon, bottomLat]] = await this._map.getVisibleBounds(); ``` @@ -602,36 +605,39 @@ Returns an array of rendered map features that intersect with a given point. #### arguments | Name | Type | Required | Description | | ---- | :--: | :------: | :----------: | -| `coordinate` | `Position` | `Yes` | A point expressed in the map view’s coordinate system. | -| `filter` | `Array` | `No` | A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array. | -| `layerIDs` | `Array` | `No` | A array of layer id's to filter the features by | +| `coordinate` | `Position` | `Yes` | A point expressed in the map view’s coordinate system `[x, y]`; | +| `filter` | `FilterExpression \| tuple` | `No` | A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array. | +| `layerIDs` | `Array` | `No` | A array of layer IDs by which to filter the features. | ```javascript -this._map.queryRenderedFeaturesAtPoint([30, 40], ['==', 'type', 'Point'], ['id1', 'id2']) +const x = 30; const y = 40; +this._map.queryRenderedFeaturesAtPoint([x, y], ['==', 'type', 'Point'], ['id1', 'id2']) ``` -### queryRenderedFeaturesInRect(bbox[, filter][, layerIDs]) +[Screen Coordinates](../examples/Map/ScreenCoordinates)### queryRenderedFeaturesInRect(bbox[, filter][, layerIDs]) Returns an array of rendered map features that intersect with the given rectangle,
restricted to the given style layers and filtered by the given predicate. In v10,
passing an empty array will query the entire visible bounds of the map. #### arguments | Name | Type | Required | Description | | ---- | :--: | :------: | :----------: | -| `bbox` | `BBox \| []` | `Yes` | A rectangle expressed in the map view’s coordinate system, density independent pixels and not map coordinates. This can be an empty array to query the visible map area. | -| `filter` | `Array` | `No` | A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array. | -| `layerIDs` | `Array` | `No` | A array of layer id's to filter the features by | +| `bbox` | `BBox \| []` | `Yes` | A rectangle expressed in density-independent screen coordinates relative to the map view `[top, left, bottom, right]` or `[minY, minX, maxY, maxX]` (not geographic coordinates). An empty array queries the visible map area. | +| `filter` | `FilterExpression` | `No` | An array of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array. | +| `layerIDs` | `Array` | `No` | A array of layer IDs by which to filter the features. | ```javascript -this._map.queryRenderedFeaturesInRect([30, 40, 20, 10], ['==', 'type', 'Point'], ['id1', 'id2']) +const left = 40; const top = 30; +const right = 10; const bottom = 20; +this._map.queryRenderedFeaturesInRect([top, left, bottom, right], ['==', 'type', 'Point'], ['id1', 'id2']) ``` -### querySourceFeatures(sourceId[, filter][, sourceLayerIDs]) +[Screen Coordinates](../examples/Map/ScreenCoordinates)### querySourceFeatures(sourceId[, filter][, sourceLayerIDs]) Returns an array of GeoJSON Feature objects representing features within the specified vector tile or GeoJSON source that satisfy the query parameters. @@ -639,7 +645,7 @@ Returns an array of GeoJSON Feature objects representing features within the spe | Name | Type | Required | Description | | ---- | :--: | :------: | :----------: | | `sourceId` | `string` | `Yes` | Style source identifier used to query for source features. | -| `filter` | `Array` | `No` | A filter to limit query results. | +| `filter` | `FilterExpression \| tuple` | `No` | A filter to limit query results. | | `sourceLayerIDs` | `Array` | `No` | The name of the source layers to query. For vector tile sources, this parameter is required. For GeoJSON sources, it is ignored. | @@ -661,12 +667,12 @@ Map camera will perform updates based on provided config. Deprecated use Camera# ### takeSnap([writeToDisk]) -Takes snapshot of map with current tiles and returns a URI to the image +Takes snapshot of map with current tiles and returns a Base64-encoded PNG image,
or an file-system URI to a temporary PNG file if `writeToDisk` is `true`. #### arguments | Name | Type | Required | Description | | ---- | :--: | :------: | :----------: | -| `writeToDisk` | `Boolean` | `No` | If true will create a temp file, otherwise it is in base64 | +| `writeToDisk` | `boolean` | `No` | If `true`, creates a temporary PNG file and returns a file-system URI, otherwise returns a Base64-encoded PNG image. (Defaults to `false`) | ### getZoom() @@ -687,7 +693,7 @@ const zoom = await this._map.getZoom(); ### getCenter() -Returns the map's geographical centerpoint +Returns the map's center point expressed as geographic coordinates `[longitude, latitude]`. #### arguments | Name | Type | Required | Description | @@ -718,7 +724,7 @@ Queries the currently loaded data for elevation at a geographical location.
#### arguments | Name | Type | Required | Description | | ---- | :--: | :------: | :----------: | -| `coordinate` | `Position` | `Yes` | the coordinates to query elevation at | +| `coordinate` | `Position` | `Yes` | The geographic coordinates `[longitude, latitude]` at which to query elevation. | [Query Terrain Elevation](../examples/V10/QueryTerrainElevation)### setSourceVisibility(visible, sourceId[, sourceLayerId]) @@ -729,8 +735,8 @@ Sets the visibility of all the layers referencing the specified `sourceLayerId` | Name | Type | Required | Description | | ---- | :--: | :------: | :----------: | | `visible` | `boolean` | `Yes` | Visibility of the layers | -| `sourceId` | `string` | `Yes` | Identifier of the target source (e.g. 'composite') | -| `sourceLayerId` | `String` | `No` | Identifier of the target source-layer (e.g. 'building') | +| `sourceId` | `string` | `Yes` | Target source identifier (e.g. 'composite') | +| `sourceLayerId` | `string` | `No` | Target source-layer identifier (e.g. 'building'). If `null`, the change affects all layers in the target source. | diff --git a/docs/MarkerView.md b/docs/MarkerView.md index acb7626afc..b676aa7aa1 100644 --- a/docs/MarkerView.md +++ b/docs/MarkerView.md @@ -17,8 +17,9 @@ component for a maximum of around 100 views displayed at one time. This is implemented with view annotations on [Android](https://docs.mapbox.com/android/maps/guides/annotations/view-annotations/) and [iOS](https://docs.mapbox.com/ios/maps/guides/annotations/view-annotations). -This component has no dedicated `onPress` method. Instead, you should handle gestures -with the React views passed in as `children`. +This component has no dedicated `onPress` method. Instead, handle gestures +with the React views passed in as `children` — Pressable, TouchableOpacity, +etc. all work including their visual feedback (opacity, scale, etc.). ## props @@ -52,8 +53,6 @@ the view, and (1, 1) is the bottom-right corner. Defaults to the center at (0.5, ```tsx boolean ``` -@v10 - Whether or not nearby markers on the map should all be displayed. If false, adjacent markers will 'collapse' and only one will be shown. Defaults to false. @@ -87,7 +86,8 @@ FIX ME NO DESCRIPTION ReactReactElement ``` _required_ -One or more valid React Native views. +One or more valid React Native views. You can use Pressable, TouchableOpacity, +etc. directly as children — onPress and touch feedback work correctly. diff --git a/docs/ModelLayer.md b/docs/ModelLayer.md index ef4081ff72..47b32b12fd 100644 --- a/docs/ModelLayer.md +++ b/docs/ModelLayer.md @@ -138,6 +138,7 @@ Customizable style attributes * visibility
* modelId
+* modelAllowDensityReduction
* modelOpacity
* modelRotation
* modelScale
@@ -152,6 +153,7 @@ Customizable style attributes * modelRoughness
* modelHeightBasedEmissiveStrengthMultiplier
* modelCutoffFadeRange
+* modelElevationReference
___ @@ -197,6 +199,23 @@ Model to render. It can be either a string referencing an element to the models Parameters: `zoom, feature` +___ + +### modelAllowDensityReduction +Name: `modelAllowDensityReduction` + +Mapbox spec: [model-allow-density-reduction](https://docs.mapbox.com/style-spec/reference/layers/#layout-model-model-allow-density-reduction) + +#### Description +If true, the models will be reduced in density based on the zoom level. This is useful for large datasets that may be slow to render. + +#### Type +`boolean` +#### Default Value +`true` + + + ___ ### modelOpacity @@ -704,3 +723,28 @@ This parameter defines the range for the fadeOut effect before an automatic cont Parameters: `` +___ + +### modelElevationReference +Name: `modelElevationReference` + +Mapbox spec: [model-elevation-reference](https://docs.mapbox.com/style-spec/reference/layers/#paint-model-model-elevation-reference) + +#### Description +Selects the base of the model. Some modes might require precomputed elevation data in the tileset. When using vector tiled source as the model layer source and hdRoadMarkup elevation reference, this property acts as layout property and elevation is evaluated only in tile loading time. + +#### Type +`enum` +#### Default Value +`ground` + +#### Supported Values +**sea** - Elevated rendering is enabled. Use this mode to elevate models relative to the sea level.
+**ground** - Elevated rendering is enabled. Use this mode to elevate models relative to the ground's height below them.
+**hd-road-markup** - Elevated rendering is enabled. Use this mode to describe additive and stackable features that should exist only on top of road polygons.
+ + +#### Expression + +Parameters: `` + diff --git a/docs/Rain.md b/docs/Rain.md new file mode 100644 index 0000000000..6ea88d9991 --- /dev/null +++ b/docs/Rain.md @@ -0,0 +1,37 @@ + + + + +```tsx +import { Rain } from '@rnmapbox/maps'; + +Rain + +``` + + +## props + + +### style + +```tsx +RainLayerStyleProps +``` +Rain particle effect style properties. + +@note The default `color` and `vignetteColor` values use `measure-light("brightness")` +expressions that are only available in Mapbox Standard-based styles +(`mapbox://styles/mapbox/standard`, `mapbox://styles/mapbox/standard-satellite`). +When using legacy or custom styles, set `color` and `vignetteColor` explicitly to +avoid "Brightness is unavailable in the current evaluation context" warnings and +invisible rain. For example: `color="#a8adbc" vignetteColor="#464646"`. + + + + + + + + + diff --git a/docs/RasterLayer.md b/docs/RasterLayer.md index 49d6390072..642cd149d1 100644 --- a/docs/RasterLayer.md +++ b/docs/RasterLayer.md @@ -665,7 +665,7 @@ Name: `rasterElevation` Mapbox spec: [raster-elevation](https://docs.mapbox.com/style-spec/reference/layers/#paint-raster-raster-elevation) #### Description -Specifies an uniform elevation from the ground, in meters. +Defines an uniform elevation from the base specified in rasterElevationReference, in meters. #### Type `number` diff --git a/docs/Snow.md b/docs/Snow.md new file mode 100644 index 0000000000..c58b1d3a8e --- /dev/null +++ b/docs/Snow.md @@ -0,0 +1,30 @@ + + + + +```tsx +import { Snow } from '@rnmapbox/maps'; + +Snow + +``` + + +## props + + +### style + +```tsx +SnowLayerStyleProps +``` +FIX ME NO DESCRIPTION + + + + + + + + + diff --git a/docs/docs.json b/docs/docs.json index 6d6bd98b29..f11c2b03dd 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -514,7 +514,8 @@ "expression": { "interpolated": true, "parameters": [ - "zoom" + "zoom", + "measure-light" ] }, "transition": true, @@ -755,14 +756,14 @@ "required": false, "type": "number", "default": "none", - "description": "The heading (orientation) of the map." + "description": "Heading (bearing, orientation) of the map, measured in degrees clockwise from true north." }, { "name": "pitch", "required": false, "type": "number", "default": "none", - "description": "The pitch of the map." + "description": "The pitch toward the horizon measured in degrees, with 0 degrees resulting in a top-down view for a two-dimensional map." }, { "name": "zoomLevel", @@ -937,14 +938,14 @@ "required": false, "type": "number", "default": "none", - "description": "The heading (orientation) of the map." + "description": "Heading (bearing, orientation) of the map, measured in degrees clockwise from true north." }, { "name": "pitch", "required": false, "type": "number", "default": "none", - "description": "The pitch of the map." + "description": "The pitch toward the horizon measured in degrees, with 0 degrees resulting in a top-down view for a two-dimensional map." }, { "name": "zoomLevel", @@ -3038,6 +3039,279 @@ } ] }, + "HillshadeLayer": { + "description": "", + "displayName": "HillshadeLayer", + "methods": [], + "props": [ + { + "name": "id", + "required": true, + "type": "string", + "default": "none", + "description": "A string that uniquely identifies the source in the style to which it is added." + }, + { + "name": "existing", + "required": false, + "type": "boolean", + "default": "none", + "description": "The id refers to an existing layer in the style. Does not create a new layer." + }, + { + "name": "sourceID", + "required": false, + "type": "string", + "default": "Mapbox.StyleSource.DefaultSourceID", + "description": "The source from which to obtain the data to style.\nIf the source has not yet been added to the current style, the behavior is undefined.\nInferred from parent source only if the layer is a direct child to it." + }, + { + "name": "sourceLayerID", + "required": false, + "type": "string", + "default": "none", + "description": "Identifier of the layer within the source identified by the sourceID property from which the receiver obtains the data to style." + }, + { + "name": "aboveLayerID", + "required": false, + "type": "string", + "default": "none", + "description": "Inserts a layer above aboveLayerID." + }, + { + "name": "belowLayerID", + "required": false, + "type": "string", + "default": "none", + "description": "Inserts a layer below belowLayerID" + }, + { + "name": "layerIndex", + "required": false, + "type": "number", + "default": "none", + "description": "Inserts a layer at a specified index" + }, + { + "name": "filter", + "required": false, + "type": "FilterExpression", + "default": "none", + "description": "Filter only the features in the source layer that satisfy a condition that you define" + }, + { + "name": "minZoomLevel", + "required": false, + "type": "number", + "default": "none", + "description": "The minimum zoom level at which the layer gets parsed and appears." + }, + { + "name": "maxZoomLevel", + "required": false, + "type": "number", + "default": "none", + "description": "The maximum zoom level at which the layer gets parsed and appears." + }, + { + "name": "slot", + "required": false, + "type": "'bottom' \\| 'middle' \\| 'top'", + "default": "none", + "description": "The slot this layer is assigned to. If specified, and a slot with that name exists, it will be placed at that position in the layer order.\n\nv11 only" + }, + { + "name": "style", + "required": true, + "type": "HillshadeLayerStyleProps", + "default": "none", + "description": "Customizable style attributes" + } + ], + "fileNameWithExt": "HillshadeLayer.tsx", + "relPath": "src/components/HillshadeLayer.tsx", + "name": "HillshadeLayer", + "mbx": { + "name": "hillshade" + }, + "styles": [ + { + "name": "visibility", + "type": "enum", + "values": [ + { + "value": "visible", + "doc": "The layer is shown." + }, + { + "value": "none", + "doc": "The layer is not shown." + } + ], + "default": "visible", + "description": "Whether this layer is displayed.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": false + }, + "mbx": { + "fullName": "layout-hillshade-visibility", + "name": "visibility", + "namespace": "layout" + } + }, + { + "name": "hillshadeIlluminationDirection", + "type": "number", + "values": [], + "minimum": 0, + "maximum": 359, + "default": 335, + "description": "The direction of the light source used to generate the hillshading with 0 as the top of the viewport if `hillshadeIlluminationAnchor` is set to `viewport` and due north if `hillshadeIlluminationAnchor` is set to `map` and no 3d lights enabled. If `hillshadeIlluminationAnchor` is set to `map` and 3d lights enabled, the direction from 3d lights is used instead.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": false, + "mbx": { + "fullName": "paint-hillshade-hillshade-illumination-direction", + "name": "hillshade-illumination-direction", + "namespace": "paint" + } + }, + { + "name": "hillshadeIlluminationAnchor", + "type": "enum", + "values": [ + { + "value": "map", + "doc": "The hillshade illumination is relative to the north direction." + }, + { + "value": "viewport", + "doc": "The hillshade illumination is relative to the top of the viewport." + } + ], + "default": "viewport", + "description": "Direction of light source when map is rotated.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "mbx": { + "fullName": "paint-hillshade-hillshade-illumination-anchor", + "name": "hillshade-illumination-anchor", + "namespace": "paint" + } + }, + { + "name": "hillshadeExaggeration", + "type": "number", + "values": [], + "minimum": 0, + "maximum": 1, + "default": 0.5, + "description": "Intensity of the hillshade", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "mbx": { + "fullName": "paint-hillshade-hillshade-exaggeration", + "name": "hillshade-exaggeration", + "namespace": "paint" + } + }, + { + "name": "hillshadeShadowColor", + "type": "color", + "values": [], + "default": "#000000", + "description": "The shading color of areas that face away from the light source.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": true, + "parameters": [ + "zoom", + "measure-light" + ] + }, + "transition": true, + "mbx": { + "fullName": "paint-hillshade-hillshade-shadow-color", + "name": "hillshade-shadow-color", + "namespace": "paint" + } + }, + { + "name": "hillshadeHighlightColor", + "type": "color", + "values": [], + "default": "#FFFFFF", + "description": "The shading color of areas that faces towards the light source.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": true, + "parameters": [ + "zoom", + "measure-light" + ] + }, + "transition": true, + "mbx": { + "fullName": "paint-hillshade-hillshade-highlight-color", + "name": "hillshade-highlight-color", + "namespace": "paint" + } + }, + { + "name": "hillshadeAccentColor", + "type": "color", + "values": [], + "default": "#000000", + "description": "The shading color used to accentuate rugged terrain like sharp cliffs and gorges.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": true, + "parameters": [ + "zoom", + "measure-light" + ] + }, + "transition": true, + "mbx": { + "fullName": "paint-hillshade-hillshade-accent-color", + "name": "hillshade-accent-color", + "namespace": "paint" + } + } + ] + }, "Image": { "description": "", "displayName": "Image", @@ -3569,7 +3843,7 @@ "type": "number", "values": [], "default": 0, - "description": "Vertical offset from ground, in meters. Defaults to 0. This is an experimental property with some known issues:\n * Not supported for globe projection at the moment \n * Elevated line discontinuity is possible on tile borders with terrain enabled \n * Rendering artifacts can happen near line joins and line caps depending on the line styling \n * Rendering artifacts relating to `lineOpacity` and `lineBlur` \n * Elevated line visibility is determined by layer order \n * ZFighting issues can happen with intersecting elevated lines \n * Elevated lines don't cast shadows", + "description": "Vertical offset from ground, in meters. Not supported for globe projection at the moment.", "requires": [ "lineElevationReference" ], @@ -3671,6 +3945,34 @@ "namespace": "layout" } }, + { + "name": "lineElevationGroundScale", + "type": "number", + "values": [], + "minimum": 0, + "maximum": 1, + "default": 0, + "description": "Controls how much the elevation of lines with `lineElevationReference` set to `sea` scales with terrain exaggeration. A value of 0 keeps the line at a fixed altitude above sea level. A value of 1 scales the elevation proportionally with terrain exaggeration.", + "requires": [ + "lineZOffset" + ], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": true, + "parameters": [ + "zoom", + "feature", + "line-progress" + ] + }, + "transition": true, + "mbx": { + "fullName": "layout-line-line-elevation-ground-scale", + "name": "line-elevation-ground-scale", + "namespace": "layout" + } + }, { "name": "lineOpacity", "type": "number", @@ -4105,6 +4407,55 @@ "namespace": "paint" } }, + { + "name": "lineBorderWidth", + "type": "number", + "values": [], + "minimum": 0, + "default": 0, + "description": "The width of the line border. A value of zero means no border.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": true, + "parameters": [ + "zoom", + "feature", + "feature-state" + ] + }, + "transition": true, + "mbx": { + "fullName": "paint-line-line-border-width", + "name": "line-border-width", + "namespace": "paint" + } + }, + { + "name": "lineBorderColor", + "type": "color", + "values": [], + "default": "rgba(0, 0, 0, 0)", + "description": "The color of the line border. If lineBorderWidth is greater than zero and the alpha value of this color is 0 (default), the color for the border will be selected automatically based on the line color.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": true, + "parameters": [ + "zoom", + "feature", + "feature-state" + ] + }, + "transition": true, + "mbx": { + "fullName": "paint-line-line-border-color", + "name": "line-border-color", + "namespace": "paint" + } + }, { "name": "lineOcclusionOpacity", "type": "number", @@ -4217,14 +4568,14 @@ "methods": [ { "name": "getPointInView", - "docblock": "Converts a geographic coordinate to a point in the given view’s coordinate system.\n\n@example\nconst pointInView = await this._map.getPointInView([-37.817070, 144.949901]);\n\n@param {Array} coordinate - A point expressed in the map view's coordinate system.\n@return {Array}", + "docblock": "Converts a geographic coordinate to a screen coordinate relative to the map view.\n\n@example\nconst longitude = 144.949901;\nconst latitude = -37.817070;\nconst [x, y] = await this._map.getPointInView([longitude, latitude]);\n\n@param {Position} coordinate - A point expressed in the map view's coordinate system `[longitude, latitude]`.\n@return {Position} A point expressed in screen coordinates relative to the map view `[x, y]`.", "modifiers": [ "async" ], "params": [ { "name": "coordinate", - "description": "A point expressed in the map view's coordinate system.", + "description": "A point expressed in the map view's coordinate system `[longitude, latitude]`.", "type": { "name": "Position" }, @@ -4232,6 +4583,7 @@ } ], "returns": { + "description": "A point expressed in screen coordinates relative to the map view `[x, y]`.", "type": { "name": "Promise", "elements": [ @@ -4242,21 +4594,21 @@ "raw": "Promise" } }, - "description": "Converts a geographic coordinate to a point in the given view’s coordinate system.", + "description": "Converts a geographic coordinate to a screen coordinate relative to the map view.", "examples": [ - "\nconst pointInView = await this._map.getPointInView([-37.817070, 144.949901]);\n\n" + "\nconst longitude = 144.949901;\nconst latitude = -37.817070;\nconst [x, y] = await this._map.getPointInView([longitude, latitude]);\n\n" ] }, { "name": "getCoordinateFromView", - "docblock": "Converts a point in the given view’s coordinate system to a geographic coordinate.\n\n@example\nconst coordinate = await this._map.getCoordinateFromView([100, 100]);\n\n@param {Array} point - A point expressed in the given view’s coordinate system.\n@return {Array}", + "docblock": "Converts a screen coordinate relative to the map view to a geographic coordinate.\n\n@example\nconst x = 100; const y = 100;\nconst [longitude, latitude] = await this._map.getCoordinateFromView([x, y]);\n\n@param {Position} point - A point expressed in screen coordinates relative to the map view `[x, y]`.\n@return {Position} A point expressed in the map view's coordinate system `[longitude, latitude]`.", "modifiers": [ "async" ], "params": [ { "name": "point", - "description": "A point expressed in the given view’s coordinate system.", + "description": "A point expressed in screen coordinates relative to the map view `[x, y]`.", "type": { "name": "Position" }, @@ -4264,6 +4616,7 @@ } ], "returns": { + "description": "A point expressed in the map view's coordinate system `[longitude, latitude]`.", "type": { "name": "Promise", "elements": [ @@ -4274,19 +4627,20 @@ "raw": "Promise" } }, - "description": "Converts a point in the given view’s coordinate system to a geographic coordinate.", + "description": "Converts a screen coordinate relative to the map view to a geographic coordinate.", "examples": [ - "\nconst coordinate = await this._map.getCoordinateFromView([100, 100]);\n\n" + "\nconst x = 100; const y = 100;\nconst [longitude, latitude] = await this._map.getCoordinateFromView([x, y]);\n\n" ] }, { "name": "getVisibleBounds", - "docblock": "The coordinate bounds (ne, sw) visible in the user’s viewport.\n\n@example\nconst visibleBounds = await this._map.getVisibleBounds();\n\n@return {Array}", + "docblock": "The coordinate bounds of the map viewport.\n\n@example\nconst [[rightLon, topLat], [leftLon, bottomLat]] = await this._map.getVisibleBounds();\n\n@return {[Position, Position]} The geographic coordinate bounds of the map viewport `[[rightLon, topLat], [leftLon, bottomLat]]`.", "modifiers": [ "async" ], "params": [], "returns": { + "description": "The geographic coordinate bounds of the map viewport `[[rightLon, topLat], [leftLon, bottomLat]]`.", "type": { "name": "Promise", "elements": [ @@ -4306,21 +4660,21 @@ "raw": "Promise<[Position, Position]>" } }, - "description": "The coordinate bounds (ne, sw) visible in the user’s viewport.", + "description": "The coordinate bounds of the map viewport.", "examples": [ - "\nconst visibleBounds = await this._map.getVisibleBounds();\n\n" + "\nconst [[rightLon, topLat], [leftLon, bottomLat]] = await this._map.getVisibleBounds();\n\n" ] }, { "name": "queryRenderedFeaturesAtPoint", - "docblock": "Returns an array of rendered map features that intersect with a given point.\n\n@example\nthis._map.queryRenderedFeaturesAtPoint([30, 40], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n@param {Array} coordinate - A point expressed in the map view’s coordinate system.\n@param {Array=} filter - A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.\n@param {Array=} layerIDs - A array of layer id's to filter the features by\n@return {FeatureCollection}", + "docblock": "Returns an array of rendered map features that intersect with a given point.\n\n@example\nconst x = 30; const y = 40;\nthis._map.queryRenderedFeaturesAtPoint([x, y], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n@param {Position} coordinate - A point expressed in the map view’s coordinate system `[x, y]`;\n@param {FilterExpression | []} filter - A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.\n@param {string[]} layerIDs - A array of layer IDs by which to filter the features.\n@return {FeatureCollection} A GeoJSON feature collection containing the query results.", "modifiers": [ "async" ], "params": [ { "name": "coordinate", - "description": "A point expressed in the map view’s coordinate system.", + "description": "A point expressed in the map view’s coordinate system `[x, y]`;", "type": { "name": "Position" }, @@ -4330,13 +4684,13 @@ "name": "filter", "description": "A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.", "type": { - "name": "Array" + "name": "FilterExpression \\| tuple" }, "optional": true }, { "name": "layerIDs", - "description": "A array of layer id's to filter the features by", + "description": "A array of layer IDs by which to filter the features.", "type": { "name": "Array" }, @@ -4344,6 +4698,7 @@ } ], "returns": { + "description": "A GeoJSON feature collection containing the query results.", "type": { "name": "Promise", "elements": [ @@ -4365,19 +4720,19 @@ }, "description": "Returns an array of rendered map features that intersect with a given point.", "examples": [ - "\nthis._map.queryRenderedFeaturesAtPoint([30, 40], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n" + "\nconst x = 30; const y = 40;\nthis._map.queryRenderedFeaturesAtPoint([x, y], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n" ] }, { "name": "queryRenderedFeaturesInRect", - "docblock": "Returns an array of rendered map features that intersect with the given rectangle,\nrestricted to the given style layers and filtered by the given predicate. In v10,\npassing an empty array will query the entire visible bounds of the map.\n\n@example\nthis._map.queryRenderedFeaturesInRect([30, 40, 20, 10], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n@param {Array} bbox - A rectangle expressed in the map view’s coordinate system, density independent pixels and not map coordinates. This can be an empty array to query the visible map area.\n@param {Array=} filter - A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.\n@param {Array=} layerIDs - A array of layer id's to filter the features by\n@return {FeatureCollection}", + "docblock": "Returns an array of rendered map features that intersect with the given rectangle,\nrestricted to the given style layers and filtered by the given predicate. In v10,\npassing an empty array will query the entire visible bounds of the map.\n\n@example\nconst left = 40; const top = 30;\nconst right = 10; const bottom = 20;\nthis._map.queryRenderedFeaturesInRect([top, left, bottom, right], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n@param {BBox | []} bbox - A rectangle expressed in density-independent screen coordinates relative to the map view `[top, left, bottom, right]` or `[minY, minX, maxY, maxX]` (not geographic coordinates). An empty array queries the visible map area.\n@param {FilterExpression} filter - An array of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.\n@param {string[] | null} layerIDs - A array of layer IDs by which to filter the features.\n@return {FeatureCollection} A GeoJSON feature collection containing the query results.", "modifiers": [ "async" ], "params": [ { "name": "bbox", - "description": "A rectangle expressed in the map view’s coordinate system, density independent pixels and not map coordinates. This can be an empty array to query the visible map area.", + "description": "A rectangle expressed in density-independent screen coordinates relative to the map view `[top, left, bottom, right]` or `[minY, minX, maxY, maxX]` (not geographic coordinates). An empty array queries the visible map area.", "type": { "name": "BBox \\| []" }, @@ -4385,15 +4740,15 @@ }, { "name": "filter", - "description": "A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.", + "description": "An array of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.", "type": { - "name": "Array" + "name": "FilterExpression" }, "optional": true }, { "name": "layerIDs", - "description": " A array of layer id's to filter the features by", + "description": " A array of layer IDs by which to filter the features.", "type": { "name": "Array" }, @@ -4401,6 +4756,7 @@ } ], "returns": { + "description": "A GeoJSON feature collection containing the query results.", "type": { "name": "Promise", "elements": [ @@ -4422,12 +4778,12 @@ }, "description": "Returns an array of rendered map features that intersect with the given rectangle,\nrestricted to the given style layers and filtered by the given predicate. In v10,\npassing an empty array will query the entire visible bounds of the map.", "examples": [ - "\nthis._map.queryRenderedFeaturesInRect([30, 40, 20, 10], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n" + "\nconst left = 40; const top = 30;\nconst right = 10; const bottom = 20;\nthis._map.queryRenderedFeaturesInRect([top, left, bottom, right], ['==', 'type', 'Point'], ['id1', 'id2'])\n\n" ] }, { "name": "querySourceFeatures", - "docblock": "Returns an array of GeoJSON Feature objects representing features within the specified vector tile or GeoJSON source that satisfy the query parameters.\n\n@example\nthis._map.querySourceFeatures('your-source-id', [], ['your-source-layer'])\n\n@param {String} sourceId - Style source identifier used to query for source features.\n@param {Array=} filter - A filter to limit query results.\n@param {Array=} sourceLayerIDs - The name of the source layers to query. For vector tile sources, this parameter is required. For GeoJSON sources, it is ignored.\n@return {FeatureCollection}", + "docblock": "Returns an array of GeoJSON Feature objects representing features within the specified vector tile or GeoJSON source that satisfy the query parameters.\n\n@example\nthis._map.querySourceFeatures('your-source-id', [], ['your-source-layer'])\n\n@param {String} sourceId - Style source identifier used to query for source features.\n@param {FilterExpression | []} filter - A filter to limit query results.\n@param {string[]} sourceLayerIDs - The name of the source layers to query. For vector tile sources, this parameter is required. For GeoJSON sources, it is ignored.\n@return {FeatureCollection} A GeoJSON feature collection.", "modifiers": [ "async" ], @@ -4444,7 +4800,7 @@ "name": "filter", "description": "A filter to limit query results.", "type": { - "name": "Array" + "name": "FilterExpression \\| tuple" }, "optional": true }, @@ -4458,6 +4814,7 @@ } ], "returns": { + "description": "A GeoJSON feature collection.", "type": { "name": "Promise", "elements": [ @@ -4484,21 +4841,22 @@ }, { "name": "takeSnap", - "docblock": "Takes snapshot of map with current tiles and returns a URI to the image\n@param {Boolean} writeToDisk If true will create a temp file, otherwise it is in base64\n@return {String}", + "docblock": "Takes snapshot of map with current tiles and returns a Base64-encoded PNG image,\nor an file-system URI to a temporary PNG file if `writeToDisk` is `true`.\n\n@param {boolean} writeToDisk If `true`, creates a temporary PNG file and returns a file-system URI, otherwise returns a Base64-encoded PNG image. (Defaults to `false`)\n@return {string} A a Base64-encoded PNG image or a file-system URI to a temporary PNG file.", "modifiers": [ "async" ], "params": [ { "name": "writeToDisk", - "description": "If true will create a temp file, otherwise it is in base64", + "description": "If `true`, creates a temporary PNG file and returns a file-system URI, otherwise returns a Base64-encoded PNG image. (Defaults to `false`)", "type": { - "name": "Boolean" + "name": "boolean" }, "optional": true } ], "returns": { + "description": "A a Base64-encoded PNG image or a file-system URI to a temporary PNG file.", "type": { "name": "Promise", "elements": [ @@ -4509,17 +4867,18 @@ "raw": "Promise" } }, - "description": "Takes snapshot of map with current tiles and returns a URI to the image", + "description": "Takes snapshot of map with current tiles and returns a Base64-encoded PNG image,\nor an file-system URI to a temporary PNG file if `writeToDisk` is `true`.", "examples": [] }, { "name": "getZoom", - "docblock": "Returns the current zoom of the map view.\n\n@example\nconst zoom = await this._map.getZoom();\n\n@return {Number}", + "docblock": "Returns the current zoom of the map view.\n\n@example\nconst zoom = await this._map.getZoom();\n\n@return {number} The current zoom of the map view.", "modifiers": [ "async" ], "params": [], "returns": { + "description": "The current zoom of the map view.", "type": { "name": "Promise", "elements": [ @@ -4537,13 +4896,13 @@ }, { "name": "getCenter", - "docblock": "Returns the map's geographical centerpoint\n\n@example\nconst center = await this._map.getCenter();\n\n@return {Array} Coordinates", + "docblock": "Returns the map's center point expressed as geographic coordinates `[longitude, latitude]`.\n\n@example\nconst center = await this._map.getCenter();\n\n@return {Position} The map's center point expressed as geographic coordinates `[longitude, latitude]`.", "modifiers": [ "async" ], "params": [], "returns": { - "description": "Coordinates", + "description": "The map's center point expressed as geographic coordinates `[longitude, latitude]`.", "type": { "name": "Promise", "elements": [ @@ -4554,7 +4913,7 @@ "raw": "Promise" } }, - "description": "Returns the map's geographical centerpoint", + "description": "Returns the map's center point expressed as geographic coordinates `[longitude, latitude]`.", "examples": [ "\nconst center = await this._map.getCenter();\n\n" ] @@ -4582,14 +4941,14 @@ }, { "name": "queryTerrainElevation", - "docblock": "Queries the currently loaded data for elevation at a geographical location.\nThe elevation is returned in meters relative to mean sea-level.\nReturns null if terrain is disabled or if terrain data for the location hasn't been loaded yet.\n\n@param {Array} coordinate - the coordinates to query elevation at\n@return {Number}", + "docblock": "Queries the currently loaded data for elevation at a geographical location.\nThe elevation is returned in meters relative to mean sea-level.\nReturns null if terrain is disabled or if terrain data for the location hasn't been loaded yet.\n\n@param {Position} coordinate - The geographic coordinates `[longitude, latitude]` at which to query elevation.\n@return {number} Elevation in meters relative to mean sea-level.", "modifiers": [ "async" ], "params": [ { "name": "coordinate", - "description": "the coordinates to query elevation at", + "description": "The geographic coordinates `[longitude, latitude]` at which to query elevation.", "type": { "name": "Position" }, @@ -4597,6 +4956,7 @@ } ], "returns": { + "description": "Elevation in meters relative to mean sea-level.", "type": { "name": "Promise", "elements": [ @@ -4612,7 +4972,7 @@ }, { "name": "setSourceVisibility", - "docblock": "Sets the visibility of all the layers referencing the specified `sourceLayerId` and/or `sourceId`\n\n@example\nawait this._map.setSourceVisibility(false, 'composite', 'building')\n\n@param {boolean} visible - Visibility of the layers\n@param {String} sourceId - Identifier of the target source (e.g. 'composite')\n@param {String=} sourceLayerId - Identifier of the target source-layer (e.g. 'building')", + "docblock": "Sets the visibility of all the layers referencing the specified `sourceLayerId` and/or `sourceId`\n\n@example\nawait this._map.setSourceVisibility(false, 'composite', 'building')\n\n@param {boolean} visible - Visibility of the layers\n@param {string} sourceId - Target source identifier (e.g. 'composite')\n@param {string | null} sourceLayerId - Target source-layer identifier (e.g. 'building'). If `null`, the change affects all layers in the target source.", "modifiers": [], "params": [ { @@ -4625,7 +4985,7 @@ }, { "name": "sourceId", - "description": "Identifier of the target source (e.g. 'composite')", + "description": "Target source identifier (e.g. 'composite')", "type": { "name": "string" }, @@ -4633,9 +4993,9 @@ }, { "name": "sourceLayerId", - "description": "Identifier of the target source-layer (e.g. 'building')", + "description": "Target source-layer identifier (e.g. 'building'). If `null`, the change affects all layers in the target source.", "type": { - "name": "String" + "name": "string" }, "optional": true } @@ -4997,7 +5357,7 @@ "name": "surfaceView", "required": false, "type": "boolean", - "default": "RNMBXModule.MapboxV10 ? true : false", + "default": "true", "description": "[Android only] Enable/Disable use of GLSurfaceView instead of TextureView." }, { @@ -5124,7 +5484,7 @@ "funcSignature": "(feature:GeoJSON.Feature) => void" }, "default": "none", - "description": "Map press listener, gets called when a user presses the map\n*signature:*`(feature:GeoJSON.Feature) => void`" + "description": "Map press listener, called when a user presses the map.\n*signature:*`(feature:GeoJSON.Feature) => void`" }, { "name": "onLongPress", @@ -5134,7 +5494,7 @@ "funcSignature": "(feature:GeoJSON.Feature) => void" }, "default": "none", - "description": "Map long press listener, gets called when a user long presses the map\n*signature:*`(feature:GeoJSON.Feature) => void`" + "description": "Map long press listener, called when a user long presses the map.\n*signature:*`(feature:GeoJSON.Feature) => void`" }, { "name": "onRegionWillChange", @@ -5333,7 +5693,7 @@ "name": "MapView" }, "MarkerView": { - "description": "MarkerView represents an interactive React Native marker on the map.\n\nIf you have static views, consider using PointAnnotation or SymbolLayer to display\nan image, as they'll offer much better performance. Mapbox suggests using this\ncomponent for a maximum of around 100 views displayed at one time.\n\nThis is implemented with view annotations on [Android](https://docs.mapbox.com/android/maps/guides/annotations/view-annotations/)\nand [iOS](https://docs.mapbox.com/ios/maps/guides/annotations/view-annotations).\n\nThis component has no dedicated `onPress` method. Instead, you should handle gestures\nwith the React views passed in as `children`.", + "description": "MarkerView represents an interactive React Native marker on the map.\n\nIf you have static views, consider using PointAnnotation or SymbolLayer to display\nan image, as they'll offer much better performance. Mapbox suggests using this\ncomponent for a maximum of around 100 views displayed at one time.\n\nThis is implemented with view annotations on [Android](https://docs.mapbox.com/android/maps/guides/annotations/view-annotations/)\nand [iOS](https://docs.mapbox.com/ios/maps/guides/annotations/view-annotations).\n\nThis component has no dedicated `onPress` method. Instead, handle gestures\nwith the React views passed in as `children` — Pressable, TouchableOpacity,\netc. all work including their visual feedback (opacity, scale, etc.).", "displayName": "MarkerView", "methods": [], "props": [ @@ -5374,7 +5734,7 @@ "required": false, "type": "boolean", "default": "false", - "description": "@v10\n\nWhether or not nearby markers on the map should all be displayed. If false, adjacent\nmarkers will 'collapse' and only one will be shown. Defaults to false." + "description": "Whether or not nearby markers on the map should all be displayed. If false, adjacent\nmarkers will 'collapse' and only one will be shown. Defaults to false." }, { "name": "allowOverlapWithPuck", @@ -5395,7 +5755,7 @@ "required": true, "type": "ReactReactElement", "default": "none", - "description": "One or more valid React Native views." + "description": "One or more valid React Native views. You can use Pressable, TouchableOpacity,\netc. directly as children — onPress and touch feedback work correctly." } ], "fileNameWithExt": "MarkerView.tsx", @@ -5549,6 +5909,22 @@ "namespace": "layout" } }, + { + "name": "modelAllowDensityReduction", + "type": "boolean", + "values": [], + "default": true, + "description": "If true, the models will be reduced in density based on the zoom level. This is useful for large datasets that may be slow to render.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "transition": false, + "mbx": { + "fullName": "layout-model-model-allow-density-reduction", + "name": "model-allow-density-reduction", + "namespace": "layout" + } + }, { "name": "modelOpacity", "type": "number", @@ -5893,6 +6269,38 @@ "name": "model-cutoff-fade-range", "namespace": "paint" } + }, + { + "name": "modelElevationReference", + "type": "enum", + "values": [ + { + "value": "sea", + "doc": "Elevated rendering is enabled. Use this mode to elevate models relative to the sea level." + }, + { + "value": "ground", + "doc": "Elevated rendering is enabled. Use this mode to elevate models relative to the ground's height below them." + }, + { + "value": "hd-road-markup", + "doc": "Elevated rendering is enabled. Use this mode to describe additive and stackable features that should exist only on top of road polygons." + } + ], + "default": "ground", + "description": "Selects the base of the model. Some modes might require precomputed elevation data in the tileset. When using vector tiled source as the model layer source and hdRoadMarkup elevation reference, this property acts as layout property and elevation is evaluated only in tile loading time.", + "requires": [], + "disabledBy": [], + "allowedFunctionTypes": [], + "expression": { + "interpolated": false + }, + "transition": false, + "mbx": { + "fullName": "paint-model-model-elevation-reference", + "name": "model-elevation-reference", + "namespace": "paint" + } } ] }, @@ -6077,6 +6485,23 @@ "relPath": "src/components/PointAnnotation.tsx", "name": "PointAnnotation" }, + "Rain": { + "description": "", + "displayName": "Rain", + "methods": [], + "props": [ + { + "name": "style", + "required": false, + "type": "RainLayerStyleProps", + "default": "none", + "description": "Rain particle effect style properties.\n\n@note The default `color` and `vignetteColor` values use `measure-light(\"brightness\")`\nexpressions that are only available in Mapbox Standard-based styles\n(`mapbox://styles/mapbox/standard`, `mapbox://styles/mapbox/standard-satellite`).\nWhen using legacy or custom styles, set `color` and `vignetteColor` explicitly to\navoid \"Brightness is unavailable in the current evaluation context\" warnings and\ninvisible rain. For example: `color=\"#a8adbc\" vignetteColor=\"#464646\"`." + } + ], + "fileNameWithExt": "Rain.tsx", + "relPath": "src/components/Rain.tsx", + "name": "Rain" + }, "RasterArraySource": { "description": "RasterArraySource is a map content source that supplies raster array image tiles to be shown on the map.\nThis is typically used for particle animations like wind or precipitation patterns.\nThe location of and metadata about the tiles are defined either by an option dictionary\nor by an external file that conforms to the TileJSON specification.\n\n@experimental This component requires Mapbox Maps SDK v11.4.0 or later", "displayName": "RasterArraySource", @@ -6658,7 +7083,7 @@ "values": [], "minimum": 0, "default": 0, - "description": "Specifies an uniform elevation from the ground, in meters.", + "description": "Defines an uniform elevation from the base specified in rasterElevationReference, in meters.", "requires": [], "disabledBy": [], "allowedFunctionTypes": [], @@ -7602,6 +8027,23 @@ } ] }, + "Snow": { + "description": "", + "displayName": "Snow", + "methods": [], + "props": [ + { + "name": "style", + "required": false, + "type": "SnowLayerStyleProps", + "default": "none", + "description": "FIX ME NO DESCRIPTION" + } + ], + "fileNameWithExt": "Snow.tsx", + "relPath": "src/components/Snow.tsx", + "name": "Snow" + }, "Style": { "description": "Style is a component that automatically adds sources / layers to the map using Mapbox GL Style Spec.\nOnly [`sources`](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources) & [`layers`](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/) are supported.\nOther fields such as `sprites`, `glyphs` etc. will be ignored. Not all layer / source attributes from the style spec are supported, in general the supported attributes will be mentioned under https://github.com/rnmapbox/maps/tree/main/docs.", "displayName": "Style", diff --git a/docs/examples.json b/docs/examples.json index 77b52e1e08..6567edf548 100644 --- a/docs/examples.json +++ b/docs/examples.json @@ -378,6 +378,23 @@ "relPath": "Map/PointInMapView.js", "name": "PointInMapView" }, + { + "metadata": { + "title": "Screen Coordinates", + "tags": [ + "MapView#onPress", + "MapView#onLongPress", + "MapView#getCoordinateFromView", + "MapView#getPointInView", + "MapView#queryRenderedFeaturesAtPoint", + "MapView#queryRenderedFeaturesInRect" + ], + "docs": "\nTests conversion from screen to geographic coordinates and vice versa. \n" + }, + "fullPath": "example/src/examples/Map/ScreenCoordinates.tsx", + "relPath": "Map/ScreenCoordinates.tsx", + "name": "ScreenCoordinates" + }, { "metadata": { "title": "Show and hide layer", @@ -585,9 +602,11 @@ "RasterDemSource", "Terrain", "Atmosphere", - "SkyLayer" + "SkyLayer", + "Snow", + "Rain" ], - "docs": "\nDemostrates use of Terrain, Atmosphere and SkyLayer.\n" + "docs": "\nDemonstrates use of Terrain, Atmosphere and SkyLayer. Use the Snow/Rain buttons to toggle experimental particle weather effects.\n" }, "fullPath": "example/src/examples/V10/TerrainSkyAtmosphere.tsx", "relPath": "V10/TerrainSkyAtmosphere.tsx", @@ -631,9 +650,11 @@ "title": "Marker View", "tags": [ "PointAnnotation", - "MarkerView" + "MarkerView", + "Slider", + "Interactive" ], - "docs": "\nShows marker view and point annotations\n" + "docs": "\nShows marker view and point annotations, including an interactive marker with\nsliders, switch, counter, text input, and pressable button to verify complex\ntouch interactions inside a MarkerView.\n" }, "fullPath": "example/src/examples/Annotations/MarkerView.tsx", "relPath": "Annotations/MarkerView.tsx", @@ -709,6 +730,19 @@ "relPath": "FillRasterLayer/GeoJSONSource.js", "name": "GeoJSONSource" }, + { + "metadata": { + "title": "Hillshade Layer", + "tags": [ + "RasterDemSource", + "HillshadeLayer" + ], + "docs": "Renders terrain hillshading from a raster-dem source." + }, + "fullPath": "example/src/examples/FillRasterLayer/HillshadeSource.tsx", + "relPath": "FillRasterLayer/HillshadeSource.tsx", + "name": "HillshadeSource" + }, { "metadata": { "title": "Image Overlay", @@ -716,7 +750,8 @@ "RasterLayer", "ImageSource" ], - "docs": "" + "docs": "", + "disableSync": true }, "fullPath": "example/src/examples/FillRasterLayer/ImageOverlay.js", "relPath": "FillRasterLayer/ImageOverlay.js", diff --git a/example/.detoxrc.js b/example/.detoxrc.js index 195e5d232c..5b841feee6 100644 --- a/example/.detoxrc.js +++ b/example/.detoxrc.js @@ -9,21 +9,21 @@ module.exports = { ios: { type: 'ios.app', build: - "xcodebuild -quiet -workspace ios/RNMapboxExample.xcworkspace -configuration Release -scheme RNMapboxExample -sdk iphonesimulator -derivedDataPath ios/build -destination 'platform=iOS Simulator,OS=16.4,name=iPhone SE (3rd generation)'", + "xcodebuild -quiet -workspace ios/RNMapboxExample.xcworkspace -configuration Release -scheme RNMapboxExample -sdk iphonesimulator -derivedDataPath ios/build -destination 'generic/platform=iOS Simulator'", binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/RNMapboxExample.app', }, 'ios.debug': { type: 'ios.app', build: - "FORCE_BUNDLING=1 xcodebuild -quiet -workspace ios/RNMapboxExample.xcworkspace -configuration Debug -scheme RNMapboxExample DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING=1 GCC_PREPROCESSOR_DEFINITIONS='$GCC_PREPROCESSOR_DEFINITIONS DEBUG_RCT_BUNDLE=1' -sdk iphonesimulator -derivedDataPath ios/build -destination 'platform=iOS Simulator,OS=16.4,name=iPhone SE (3rd generation)'", + "FORCE_BUNDLING=1 xcodebuild -quiet -workspace ios/RNMapboxExample.xcworkspace -configuration Debug -scheme RNMapboxExample DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING=1 GCC_PREPROCESSOR_DEFINITIONS='$GCC_PREPROCESSOR_DEFINITIONS DEBUG_RCT_BUNDLE=1' -sdk iphonesimulator -derivedDataPath ios/build -destination 'generic/platform=iOS Simulator'", binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/RNMapboxExample.app', }, 'ios.debug.ci': { type: 'ios.app', build: - "FORCE_BUNDLING=1 xcodebuild -quiet -workspace ios/RNMapboxExample.xcworkspace -configuration Debug -scheme RNMapboxExample DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING=1 GCC_PREPROCESSOR_DEFINITIONS='$GCC_PREPROCESSOR_DEFINITIONS DEBUG_RCT_BUNDLE=1' -sdk iphonesimulator -derivedDataPath ios/build -destination 'platform=iOS Simulator,OS=18.6,arch=arm64,name=iPhone SE (3rd generation)'", + "FORCE_BUNDLING=1 xcodebuild -quiet -workspace ios/RNMapboxExample.xcworkspace -configuration Debug -scheme RNMapboxExample DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING=1 GCC_PREPROCESSOR_DEFINITIONS='$GCC_PREPROCESSOR_DEFINITIONS DEBUG_RCT_BUNDLE=1' -sdk iphonesimulator -derivedDataPath ios/build -destination 'generic/platform=iOS Simulator'", binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/RNMapboxExample.app', }, @@ -32,15 +32,13 @@ module.exports = { simulator: { type: 'ios.simulator', device: { - type: 'iPhone 14 Pro', - os: '16.4', + type: 'iPhone 16', }, }, 'simulator.ci': { type: 'ios.simulator', device: { type: 'iPhone SE (3rd generation)', - os: '18.2', }, }, }, diff --git a/example/android/app/src/main/java/com/rnmapboxexample/MainApplication.kt b/example/android/app/src/main/java/com/rnmapboxexample/MainApplication.kt index 6e141f6054..bfca9bdccc 100644 --- a/example/android/app/src/main/java/com/rnmapboxexample/MainApplication.kt +++ b/example/android/app/src/main/java/com/rnmapboxexample/MainApplication.kt @@ -9,20 +9,17 @@ import com.facebook.react.ReactPackage import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost import com.facebook.react.defaults.DefaultReactNativeHost class MainApplication : Application(), ReactApplication { - override val reactNativeHost: ReactNativeHost = - object : DefaultReactNativeHost(this) { - override fun getPackages(): List = - PackageList(this).packages.apply { - // Packages that cannot be autolinked yet can be added manually here, for example: - // add(MyReactNativePackage()) - } - override fun getJSMainModuleName(): String = "index" - override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG - override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED - override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED - } - override val reactHost: ReactHost - get() = getDefaultReactHost(applicationContext, reactNativeHost) + override val reactHost: ReactHost by lazy { + getDefaultReactHost( + context = applicationContext, + packageList = + PackageList(this).packages.apply { + // Packages that cannot be autolinked yet can be added manually here, for example: // Packages that cannot be autolinked yet can be added manually here, for example: + // add(MyReactNativePackage()) + }, + ) + } + override fun onCreate() { super.onCreate() loadReactNative(this) diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index d4081da476..2a84e188b8 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/example/android/gradlew b/example/android/gradlew index 23d15a9367..ef07e0162b 100755 --- a/example/android/gradlew +++ b/example/android/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/example/babel.config.js b/example/babel.config.js index 4354ce3f62..c6d8e9b7c7 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -10,20 +10,11 @@ module.exports = getConfig( { presets: ['babel-preset-expo'], plugins: [ + 'react-native-reanimated/plugin', [ 'babel-plugin-react-compiler', { - // Log what the compiler is doing (set to false to disable logging) - // When enabled, you'll see "React Compiler: compiled X functions" in Metro logs - compilationMode: 'infer', // 'annotation' | 'all' | 'infer' - - /* - panicThreshold: 'all_errors', // Show all compilation errors/warnings - logger: { - logEvent(filename, event) { - console.log(`[React Compiler] ${filename}: ${event}`); - }, - }*/ + compilationMode: 'infer', }, ], ], diff --git a/example/e2e/docScreenshots.e2e.js b/example/e2e/docScreenshots.e2e.js index c9be59915c..2f4a4638bd 100644 --- a/example/e2e/docScreenshots.e2e.js +++ b/example/e2e/docScreenshots.e2e.js @@ -170,6 +170,10 @@ if (['true', 1, '1'].includes(process.env.SKIP_TESTS_NO_METAL)) { if (shouldRestartAppBetweenTests) { await device.launchApp({ permissions: { location: 'always' } }); } + await device.setURLBlacklist([ + '.*tile.openstreetmap.org.*', + '.*mapbox.com.*', + ]); await device.reloadReactNative(); }); afterEach(async () => { @@ -198,15 +202,19 @@ if (['true', 1, '1'].includes(process.env.SKIP_TESTS_NO_METAL)) { }); await setSampleLocation(); - await expect( - element(by.text(groupMetadata.title)), - ).toBeVisible(); + await waitFor(element(by.text(groupMetadata.title))) + .toBeVisible() + .whileElement(by.id('example-list')) + .scroll(200, 'down'); await element(by.text(groupMetadata.title)).tap(); await waitFor(element(by.text(metadata.title))) .toBeVisible() .whileElement(by.id('example-list')) .scroll(50, 'down'); + if (metadata.disableSync) { + await device.disableSynchronization(); + } await element(by.text(metadata.title)).tap(); let shots = new ExampleScreenshots( @@ -214,8 +222,7 @@ if (['true', 1, '1'].includes(process.env.SKIP_TESTS_NO_METAL)) { screenshots, ); - await wait(1000); - + await wait(metadata.disableSync ? 3000 : 1000); await shots.screenshot(); }); } diff --git a/example/index.js b/example/index.js index e14d5e0776..4879a9867b 100644 --- a/example/index.js +++ b/example/index.js @@ -1,4 +1,5 @@ console.log('index.js'); +import './src/setup'; import { AppRegistry } from 'react-native'; import App from './src/App'; diff --git a/example/ios/Podfile b/example/ios/Podfile index ce3fffc3ee..0306fededd 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -92,8 +92,7 @@ target 'RNMapboxExample' do end react_native_post_install( installer, - # Set `mac_catalyst_enabled` to `true` in order to apply patches - # necessary for Mac Catalyst builds + config[:reactNativePath], :mac_catalyst_enabled => false, # :ccache_enabled => true ) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index e1e86b7d4b..af881ad44d 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2,19 +2,19 @@ PODS: - boost (1.84.0) - DoubleConversion (1.1.6) - fast_float (8.0.0) - - FBLazyVector (0.81.1) + - FBLazyVector (0.82.0) - fmt (11.0.2) - glog (0.3.5) - - hermes-engine (0.81.1): - - hermes-engine/Pre-built (= 0.81.1) - - hermes-engine/Pre-built (0.81.1) - - MapboxCommon (24.15.2): + - hermes-engine (0.82.0): + - hermes-engine/Pre-built (= 0.82.0) + - hermes-engine/Pre-built (0.82.0) + - MapboxCommon (24.16.6): - Turf (= 4.0.0) - - MapboxCoreMaps (11.15.2): - - MapboxCommon (= 24.15.2) - - MapboxMaps (11.15.2): - - MapboxCommon (= 24.15.2) - - MapboxCoreMaps (= 11.15.2) + - MapboxCoreMaps (11.16.6): + - MapboxCommon (= 24.16.6) + - MapboxMaps (11.16.6): + - MapboxCommon (= 24.16.6) + - MapboxCoreMaps (= 11.16.6) - Turf (= 4.0.0) - RCT-Folly (2024.11.18.00): - boost @@ -35,27 +35,27 @@ PODS: - fast_float (= 8.0.0) - fmt (= 11.0.2) - glog - - RCTDeprecation (0.81.1) - - RCTRequired (0.81.1) - - RCTTypeSafety (0.81.1): - - FBLazyVector (= 0.81.1) - - RCTRequired (= 0.81.1) - - React-Core (= 0.81.1) - - React (0.81.1): - - React-Core (= 0.81.1) - - React-Core/DevSupport (= 0.81.1) - - React-Core/RCTWebSocket (= 0.81.1) - - React-RCTActionSheet (= 0.81.1) - - React-RCTAnimation (= 0.81.1) - - React-RCTBlob (= 0.81.1) - - React-RCTImage (= 0.81.1) - - React-RCTLinking (= 0.81.1) - - React-RCTNetwork (= 0.81.1) - - React-RCTSettings (= 0.81.1) - - React-RCTText (= 0.81.1) - - React-RCTVibration (= 0.81.1) - - React-callinvoker (0.81.1) - - React-Core (0.81.1): + - RCTDeprecation (0.82.0) + - RCTRequired (0.82.0) + - RCTTypeSafety (0.82.0): + - FBLazyVector (= 0.82.0) + - RCTRequired (= 0.82.0) + - React-Core (= 0.82.0) + - React (0.82.0): + - React-Core (= 0.82.0) + - React-Core/DevSupport (= 0.82.0) + - React-Core/RCTWebSocket (= 0.82.0) + - React-RCTActionSheet (= 0.82.0) + - React-RCTAnimation (= 0.82.0) + - React-RCTBlob (= 0.82.0) + - React-RCTImage (= 0.82.0) + - React-RCTLinking (= 0.82.0) + - React-RCTNetwork (= 0.82.0) + - React-RCTSettings (= 0.82.0) + - React-RCTText (= 0.82.0) + - React-RCTVibration (= 0.82.0) + - React-callinvoker (0.82.0) + - React-Core (0.82.0): - boost - DoubleConversion - fast_float @@ -65,7 +65,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTDeprecation - - React-Core/Default (= 0.81.1) + - React-Core/Default (= 0.82.0) - React-cxxreact - React-featureflags - React-hermes @@ -80,7 +80,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/CoreModulesHeaders (0.81.1): + - React-Core/CoreModulesHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -105,7 +105,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/Default (0.81.1): + - React-Core/Default (0.82.0): - boost - DoubleConversion - fast_float @@ -129,7 +129,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/DevSupport (0.81.1): + - React-Core/DevSupport (0.82.0): - boost - DoubleConversion - fast_float @@ -139,8 +139,8 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTDeprecation - - React-Core/Default (= 0.81.1) - - React-Core/RCTWebSocket (= 0.81.1) + - React-Core/Default (= 0.82.0) + - React-Core/RCTWebSocket (= 0.82.0) - React-cxxreact - React-featureflags - React-hermes @@ -155,7 +155,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTActionSheetHeaders (0.81.1): + - React-Core/RCTActionSheetHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -180,7 +180,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTAnimationHeaders (0.81.1): + - React-Core/RCTAnimationHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -205,7 +205,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTBlobHeaders (0.81.1): + - React-Core/RCTBlobHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -230,7 +230,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTImageHeaders (0.81.1): + - React-Core/RCTImageHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -255,7 +255,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTLinkingHeaders (0.81.1): + - React-Core/RCTLinkingHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -280,7 +280,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTNetworkHeaders (0.81.1): + - React-Core/RCTNetworkHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -305,7 +305,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTSettingsHeaders (0.81.1): + - React-Core/RCTSettingsHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -330,7 +330,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTTextHeaders (0.81.1): + - React-Core/RCTTextHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -355,7 +355,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTVibrationHeaders (0.81.1): + - React-Core/RCTVibrationHeaders (0.82.0): - boost - DoubleConversion - fast_float @@ -380,7 +380,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTWebSocket (0.81.1): + - React-Core/RCTWebSocket (0.82.0): - boost - DoubleConversion - fast_float @@ -390,7 +390,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTDeprecation - - React-Core/Default (= 0.81.1) + - React-Core/Default (= 0.82.0) - React-cxxreact - React-featureflags - React-hermes @@ -405,7 +405,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-CoreModules (0.81.1): + - React-CoreModules (0.82.0): - boost - DoubleConversion - fast_float @@ -413,20 +413,21 @@ PODS: - glog - RCT-Folly - RCT-Folly/Fabric - - RCTTypeSafety (= 0.81.1) - - React-Core/CoreModulesHeaders (= 0.81.1) - - React-jsi (= 0.81.1) + - RCTTypeSafety (= 0.82.0) + - React-Core/CoreModulesHeaders (= 0.82.0) + - React-debug + - React-jsi (= 0.82.0) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - React-NativeModulesApple - React-RCTBlob - React-RCTFBReactNativeSpec - - React-RCTImage (= 0.81.1) + - React-RCTImage (= 0.82.0) - React-runtimeexecutor - ReactCommon - SocketRocket - - React-cxxreact (0.81.1): + - React-cxxreact (0.82.0): - boost - DoubleConversion - fast_float @@ -435,19 +436,19 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-callinvoker (= 0.81.1) - - React-debug (= 0.81.1) - - React-jsi (= 0.81.1) + - React-callinvoker (= 0.82.0) + - React-debug (= 0.82.0) + - React-jsi (= 0.82.0) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - - React-logger (= 0.81.1) - - React-perflogger (= 0.81.1) + - React-logger (= 0.82.0) + - React-perflogger (= 0.82.0) - React-runtimeexecutor - - React-timing (= 0.81.1) + - React-timing (= 0.82.0) - SocketRocket - - React-debug (0.81.1) - - React-defaultsnativemodule (0.81.1): + - React-debug (0.82.0) + - React-defaultsnativemodule (0.82.0): - boost - DoubleConversion - fast_float @@ -463,8 +464,9 @@ PODS: - React-jsiexecutor - React-microtasksnativemodule - React-RCTFBReactNativeSpec + - React-webperformancenativemodule - SocketRocket - - React-domnativemodule (0.81.1): + - React-domnativemodule (0.82.0): - boost - DoubleConversion - fast_float @@ -484,7 +486,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-Fabric (0.81.1): + - React-Fabric (0.82.0): - boost - DoubleConversion - fast_float @@ -498,23 +500,23 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/animations (= 0.81.1) - - React-Fabric/attributedstring (= 0.81.1) - - React-Fabric/bridging (= 0.81.1) - - React-Fabric/componentregistry (= 0.81.1) - - React-Fabric/componentregistrynative (= 0.81.1) - - React-Fabric/components (= 0.81.1) - - React-Fabric/consistency (= 0.81.1) - - React-Fabric/core (= 0.81.1) - - React-Fabric/dom (= 0.81.1) - - React-Fabric/imagemanager (= 0.81.1) - - React-Fabric/leakchecker (= 0.81.1) - - React-Fabric/mounting (= 0.81.1) - - React-Fabric/observers (= 0.81.1) - - React-Fabric/scheduler (= 0.81.1) - - React-Fabric/telemetry (= 0.81.1) - - React-Fabric/templateprocessor (= 0.81.1) - - React-Fabric/uimanager (= 0.81.1) + - React-Fabric/animations (= 0.82.0) + - React-Fabric/attributedstring (= 0.82.0) + - React-Fabric/bridging (= 0.82.0) + - React-Fabric/componentregistry (= 0.82.0) + - React-Fabric/componentregistrynative (= 0.82.0) + - React-Fabric/components (= 0.82.0) + - React-Fabric/consistency (= 0.82.0) + - React-Fabric/core (= 0.82.0) + - React-Fabric/dom (= 0.82.0) + - React-Fabric/imagemanager (= 0.82.0) + - React-Fabric/leakchecker (= 0.82.0) + - React-Fabric/mounting (= 0.82.0) + - React-Fabric/observers (= 0.82.0) + - React-Fabric/scheduler (= 0.82.0) + - React-Fabric/telemetry (= 0.82.0) + - React-Fabric/templateprocessor (= 0.82.0) + - React-Fabric/uimanager (= 0.82.0) - React-featureflags - React-graphics - React-jsi @@ -526,7 +528,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/animations (0.81.1): + - React-Fabric/animations (0.82.0): - boost - DoubleConversion - fast_float @@ -551,7 +553,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/attributedstring (0.81.1): + - React-Fabric/attributedstring (0.82.0): - boost - DoubleConversion - fast_float @@ -576,7 +578,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/bridging (0.81.1): + - React-Fabric/bridging (0.82.0): - boost - DoubleConversion - fast_float @@ -601,7 +603,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/componentregistry (0.81.1): + - React-Fabric/componentregistry (0.82.0): - boost - DoubleConversion - fast_float @@ -626,7 +628,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/componentregistrynative (0.81.1): + - React-Fabric/componentregistrynative (0.82.0): - boost - DoubleConversion - fast_float @@ -651,7 +653,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components (0.81.1): + - React-Fabric/components (0.82.0): - boost - DoubleConversion - fast_float @@ -665,10 +667,10 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/components/legacyviewmanagerinterop (= 0.81.1) - - React-Fabric/components/root (= 0.81.1) - - React-Fabric/components/scrollview (= 0.81.1) - - React-Fabric/components/view (= 0.81.1) + - React-Fabric/components/legacyviewmanagerinterop (= 0.82.0) + - React-Fabric/components/root (= 0.82.0) + - React-Fabric/components/scrollview (= 0.82.0) + - React-Fabric/components/view (= 0.82.0) - React-featureflags - React-graphics - React-jsi @@ -680,7 +682,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components/legacyviewmanagerinterop (0.81.1): + - React-Fabric/components/legacyviewmanagerinterop (0.82.0): - boost - DoubleConversion - fast_float @@ -705,7 +707,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components/root (0.81.1): + - React-Fabric/components/root (0.82.0): - boost - DoubleConversion - fast_float @@ -730,7 +732,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components/scrollview (0.81.1): + - React-Fabric/components/scrollview (0.82.0): - boost - DoubleConversion - fast_float @@ -755,7 +757,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components/view (0.81.1): + - React-Fabric/components/view (0.82.0): - boost - DoubleConversion - fast_float @@ -782,7 +784,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-Fabric/consistency (0.81.1): + - React-Fabric/consistency (0.82.0): - boost - DoubleConversion - fast_float @@ -807,7 +809,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/core (0.81.1): + - React-Fabric/core (0.82.0): - boost - DoubleConversion - fast_float @@ -832,7 +834,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/dom (0.81.1): + - React-Fabric/dom (0.82.0): - boost - DoubleConversion - fast_float @@ -857,7 +859,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/imagemanager (0.81.1): + - React-Fabric/imagemanager (0.82.0): - boost - DoubleConversion - fast_float @@ -882,7 +884,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/leakchecker (0.81.1): + - React-Fabric/leakchecker (0.82.0): - boost - DoubleConversion - fast_float @@ -907,7 +909,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/mounting (0.81.1): + - React-Fabric/mounting (0.82.0): - boost - DoubleConversion - fast_float @@ -932,7 +934,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/observers (0.81.1): + - React-Fabric/observers (0.82.0): - boost - DoubleConversion - fast_float @@ -946,7 +948,7 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/observers/events (= 0.81.1) + - React-Fabric/observers/events (= 0.82.0) - React-featureflags - React-graphics - React-jsi @@ -958,7 +960,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/observers/events (0.81.1): + - React-Fabric/observers/events (0.82.0): - boost - DoubleConversion - fast_float @@ -983,7 +985,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/scheduler (0.81.1): + - React-Fabric/scheduler (0.82.0): - boost - DoubleConversion - fast_float @@ -1003,6 +1005,7 @@ PODS: - React-jsi - React-jsiexecutor - React-logger + - React-performancecdpmetrics - React-performancetimeline - React-rendererdebug - React-runtimeexecutor @@ -1010,7 +1013,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/telemetry (0.81.1): + - React-Fabric/telemetry (0.82.0): - boost - DoubleConversion - fast_float @@ -1035,7 +1038,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/templateprocessor (0.81.1): + - React-Fabric/templateprocessor (0.82.0): - boost - DoubleConversion - fast_float @@ -1060,7 +1063,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/uimanager (0.81.1): + - React-Fabric/uimanager (0.82.0): - boost - DoubleConversion - fast_float @@ -1074,7 +1077,7 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/uimanager/consistency (= 0.81.1) + - React-Fabric/uimanager/consistency (= 0.82.0) - React-featureflags - React-graphics - React-jsi @@ -1087,7 +1090,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/uimanager/consistency (0.81.1): + - React-Fabric/uimanager/consistency (0.82.0): - boost - DoubleConversion - fast_float @@ -1113,7 +1116,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-FabricComponents (0.81.1): + - React-FabricComponents (0.82.0): - boost - DoubleConversion - fast_float @@ -1128,8 +1131,8 @@ PODS: - React-cxxreact - React-debug - React-Fabric - - React-FabricComponents/components (= 0.81.1) - - React-FabricComponents/textlayoutmanager (= 0.81.1) + - React-FabricComponents/components (= 0.82.0) + - React-FabricComponents/textlayoutmanager (= 0.82.0) - React-featureflags - React-graphics - React-jsi @@ -1142,7 +1145,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components (0.81.1): + - React-FabricComponents/components (0.82.0): - boost - DoubleConversion - fast_float @@ -1157,17 +1160,18 @@ PODS: - React-cxxreact - React-debug - React-Fabric - - React-FabricComponents/components/inputaccessory (= 0.81.1) - - React-FabricComponents/components/iostextinput (= 0.81.1) - - React-FabricComponents/components/modal (= 0.81.1) - - React-FabricComponents/components/rncore (= 0.81.1) - - React-FabricComponents/components/safeareaview (= 0.81.1) - - React-FabricComponents/components/scrollview (= 0.81.1) - - React-FabricComponents/components/switch (= 0.81.1) - - React-FabricComponents/components/text (= 0.81.1) - - React-FabricComponents/components/textinput (= 0.81.1) - - React-FabricComponents/components/unimplementedview (= 0.81.1) - - React-FabricComponents/components/virtualview (= 0.81.1) + - React-FabricComponents/components/inputaccessory (= 0.82.0) + - React-FabricComponents/components/iostextinput (= 0.82.0) + - React-FabricComponents/components/modal (= 0.82.0) + - React-FabricComponents/components/rncore (= 0.82.0) + - React-FabricComponents/components/safeareaview (= 0.82.0) + - React-FabricComponents/components/scrollview (= 0.82.0) + - React-FabricComponents/components/switch (= 0.82.0) + - React-FabricComponents/components/text (= 0.82.0) + - React-FabricComponents/components/textinput (= 0.82.0) + - React-FabricComponents/components/unimplementedview (= 0.82.0) + - React-FabricComponents/components/virtualview (= 0.82.0) + - React-FabricComponents/components/virtualviewexperimental (= 0.82.0) - React-featureflags - React-graphics - React-jsi @@ -1180,7 +1184,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/inputaccessory (0.81.1): + - React-FabricComponents/components/inputaccessory (0.82.0): - boost - DoubleConversion - fast_float @@ -1207,7 +1211,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/iostextinput (0.81.1): + - React-FabricComponents/components/iostextinput (0.82.0): - boost - DoubleConversion - fast_float @@ -1234,7 +1238,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/modal (0.81.1): + - React-FabricComponents/components/modal (0.82.0): - boost - DoubleConversion - fast_float @@ -1261,7 +1265,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/rncore (0.81.1): + - React-FabricComponents/components/rncore (0.82.0): - boost - DoubleConversion - fast_float @@ -1288,7 +1292,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/safeareaview (0.81.1): + - React-FabricComponents/components/safeareaview (0.82.0): - boost - DoubleConversion - fast_float @@ -1315,7 +1319,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/scrollview (0.81.1): + - React-FabricComponents/components/scrollview (0.82.0): - boost - DoubleConversion - fast_float @@ -1342,7 +1346,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/switch (0.81.1): + - React-FabricComponents/components/switch (0.82.0): - boost - DoubleConversion - fast_float @@ -1369,7 +1373,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/text (0.81.1): + - React-FabricComponents/components/text (0.82.0): - boost - DoubleConversion - fast_float @@ -1396,7 +1400,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/textinput (0.81.1): + - React-FabricComponents/components/textinput (0.82.0): - boost - DoubleConversion - fast_float @@ -1423,7 +1427,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/unimplementedview (0.81.1): + - React-FabricComponents/components/unimplementedview (0.82.0): - boost - DoubleConversion - fast_float @@ -1450,7 +1454,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/virtualview (0.81.1): + - React-FabricComponents/components/virtualview (0.82.0): - boost - DoubleConversion - fast_float @@ -1477,7 +1481,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/textlayoutmanager (0.81.1): + - React-FabricComponents/components/virtualviewexperimental (0.82.0): - boost - DoubleConversion - fast_float @@ -1504,7 +1508,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricImage (0.81.1): + - React-FabricComponents/textlayoutmanager (0.82.0): - boost - DoubleConversion - fast_float @@ -1513,21 +1517,48 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - RCTRequired (= 0.81.1) - - RCTTypeSafety (= 0.81.1) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-cxxreact + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-jsi + - React-jsiexecutor + - React-logger + - React-RCTFBReactNativeSpec + - React-rendererdebug + - React-runtimescheduler + - React-utils + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - React-FabricImage (0.82.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired (= 0.82.0) + - RCTTypeSafety (= 0.82.0) - React-Fabric - React-featureflags - React-graphics - React-ImageManager - React-jsi - - React-jsiexecutor (= 0.81.1) + - React-jsiexecutor (= 0.82.0) - React-logger - React-rendererdebug - React-utils - ReactCommon - SocketRocket - Yoga - - React-featureflags (0.81.1): + - React-featureflags (0.82.0): - boost - DoubleConversion - fast_float @@ -1536,7 +1567,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-featureflagsnativemodule (0.81.1): + - React-featureflagsnativemodule (0.82.0): - boost - DoubleConversion - fast_float @@ -1551,7 +1582,7 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon/turbomodule/core - SocketRocket - - React-graphics (0.81.1): + - React-graphics (0.82.0): - boost - DoubleConversion - fast_float @@ -1564,7 +1595,7 @@ PODS: - React-jsiexecutor - React-utils - SocketRocket - - React-hermes (0.81.1): + - React-hermes (0.82.0): - boost - DoubleConversion - fast_float @@ -1573,16 +1604,17 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-cxxreact (= 0.81.1) + - React-cxxreact (= 0.82.0) - React-jsi - - React-jsiexecutor (= 0.81.1) + - React-jsiexecutor (= 0.82.0) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - - React-perflogger (= 0.81.1) + - React-oscompat + - React-perflogger (= 0.82.0) - React-runtimeexecutor - SocketRocket - - React-idlecallbacksnativemodule (0.81.1): + - React-idlecallbacksnativemodule (0.82.0): - boost - DoubleConversion - fast_float @@ -1598,7 +1630,7 @@ PODS: - React-runtimescheduler - ReactCommon/turbomodule/core - SocketRocket - - React-ImageManager (0.81.1): + - React-ImageManager (0.82.0): - boost - DoubleConversion - fast_float @@ -1613,7 +1645,7 @@ PODS: - React-rendererdebug - React-utils - SocketRocket - - React-jserrorhandler (0.81.1): + - React-jserrorhandler (0.82.0): - boost - DoubleConversion - fast_float @@ -1628,7 +1660,7 @@ PODS: - React-jsi - ReactCommon/turbomodule/bridging - SocketRocket - - React-jsi (0.81.1): + - React-jsi (0.82.0): - boost - DoubleConversion - fast_float @@ -1638,7 +1670,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-jsiexecutor (0.81.1): + - React-jsiexecutor (0.82.0): - boost - DoubleConversion - fast_float @@ -1647,15 +1679,16 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-cxxreact (= 0.81.1) - - React-jsi (= 0.81.1) + - React-cxxreact + - React-debug + - React-jsi - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - - React-perflogger (= 0.81.1) + - React-perflogger - React-runtimeexecutor - SocketRocket - - React-jsinspector (0.81.1): + - React-jsinspector (0.82.0): - boost - DoubleConversion - fast_float @@ -1670,10 +1703,10 @@ PODS: - React-jsinspectornetwork - React-jsinspectortracing - React-oscompat - - React-perflogger (= 0.81.1) + - React-perflogger (= 0.82.0) - React-runtimeexecutor - SocketRocket - - React-jsinspectorcdp (0.81.1): + - React-jsinspectorcdp (0.82.0): - boost - DoubleConversion - fast_float @@ -1682,7 +1715,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-jsinspectornetwork (0.81.1): + - React-jsinspectornetwork (0.82.0): - boost - DoubleConversion - fast_float @@ -1695,7 +1728,7 @@ PODS: - React-performancetimeline - React-timing - SocketRocket - - React-jsinspectortracing (0.81.1): + - React-jsinspectortracing (0.82.0): - boost - DoubleConversion - fast_float @@ -1706,7 +1739,7 @@ PODS: - React-oscompat - React-timing - SocketRocket - - React-jsitooling (0.81.1): + - React-jsitooling (0.82.0): - boost - DoubleConversion - fast_float @@ -1714,16 +1747,17 @@ PODS: - glog - RCT-Folly - RCT-Folly/Fabric - - React-cxxreact (= 0.81.1) - - React-jsi (= 0.81.1) + - React-cxxreact (= 0.82.0) + - React-debug + - React-jsi (= 0.82.0) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - React-runtimeexecutor - SocketRocket - - React-jsitracing (0.81.1): + - React-jsitracing (0.82.0): - React-jsi - - React-logger (0.81.1): + - React-logger (0.82.0): - boost - DoubleConversion - fast_float @@ -1732,7 +1766,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-Mapbuffer (0.81.1): + - React-Mapbuffer (0.82.0): - boost - DoubleConversion - fast_float @@ -1742,7 +1776,7 @@ PODS: - RCT-Folly/Fabric - React-debug - SocketRocket - - React-microtasksnativemodule (0.81.1): + - React-microtasksnativemodule (0.82.0): - boost - DoubleConversion - fast_float @@ -1843,7 +1877,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-NativeModulesApple (0.81.1): + - React-NativeModulesApple (0.82.0): - boost - DoubleConversion - fast_float @@ -1855,6 +1889,7 @@ PODS: - React-callinvoker - React-Core - React-cxxreact + - React-debug - React-featureflags - React-jsi - React-jsinspector @@ -1863,8 +1898,8 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - SocketRocket - - React-oscompat (0.81.1) - - React-perflogger (0.81.1): + - React-oscompat (0.82.0) + - React-perflogger (0.82.0): - boost - DoubleConversion - fast_float @@ -1873,7 +1908,21 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-performancetimeline (0.81.1): + - React-performancecdpmetrics (0.82.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - React-jsi + - React-performancetimeline + - React-runtimeexecutor + - React-timing + - SocketRocket + - React-performancetimeline (0.82.0): - boost - DoubleConversion - fast_float @@ -1886,9 +1935,9 @@ PODS: - React-perflogger - React-timing - SocketRocket - - React-RCTActionSheet (0.81.1): - - React-Core/RCTActionSheetHeaders (= 0.81.1) - - React-RCTAnimation (0.81.1): + - React-RCTActionSheet (0.82.0): + - React-Core/RCTActionSheetHeaders (= 0.82.0) + - React-RCTAnimation (0.82.0): - boost - DoubleConversion - fast_float @@ -1904,7 +1953,7 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon - SocketRocket - - React-RCTAppDelegate (0.81.1): + - React-RCTAppDelegate (0.82.0): - boost - DoubleConversion - fast_float @@ -1938,7 +1987,7 @@ PODS: - React-utils - ReactCommon - SocketRocket - - React-RCTBlob (0.81.1): + - React-RCTBlob (0.82.0): - boost - DoubleConversion - fast_float @@ -1957,7 +2006,7 @@ PODS: - React-RCTNetwork - ReactCommon - SocketRocket - - React-RCTFabric (0.81.1): + - React-RCTFabric (0.82.0): - boost - DoubleConversion - fast_float @@ -1979,6 +2028,7 @@ PODS: - React-jsinspectorcdp - React-jsinspectornetwork - React-jsinspectortracing + - React-performancecdpmetrics - React-performancetimeline - React-RCTAnimation - React-RCTFBReactNativeSpec @@ -1992,7 +2042,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-RCTFBReactNativeSpec (0.81.1): + - React-RCTFBReactNativeSpec (0.82.0): - boost - DoubleConversion - fast_float @@ -2006,10 +2056,10 @@ PODS: - React-Core - React-jsi - React-NativeModulesApple - - React-RCTFBReactNativeSpec/components (= 0.81.1) + - React-RCTFBReactNativeSpec/components (= 0.82.0) - ReactCommon - SocketRocket - - React-RCTFBReactNativeSpec/components (0.81.1): + - React-RCTFBReactNativeSpec/components (0.82.0): - boost - DoubleConversion - fast_float @@ -2032,7 +2082,7 @@ PODS: - ReactCommon - SocketRocket - Yoga - - React-RCTImage (0.81.1): + - React-RCTImage (0.82.0): - boost - DoubleConversion - fast_float @@ -2048,14 +2098,14 @@ PODS: - React-RCTNetwork - ReactCommon - SocketRocket - - React-RCTLinking (0.81.1): - - React-Core/RCTLinkingHeaders (= 0.81.1) - - React-jsi (= 0.81.1) + - React-RCTLinking (0.82.0): + - React-Core/RCTLinkingHeaders (= 0.82.0) + - React-jsi (= 0.82.0) - React-NativeModulesApple - React-RCTFBReactNativeSpec - ReactCommon - - ReactCommon/turbomodule/core (= 0.81.1) - - React-RCTNetwork (0.81.1): + - ReactCommon/turbomodule/core (= 0.82.0) + - React-RCTNetwork (0.82.0): - boost - DoubleConversion - fast_float @@ -2065,6 +2115,7 @@ PODS: - RCT-Folly/Fabric - RCTTypeSafety - React-Core/RCTNetworkHeaders + - React-debug - React-featureflags - React-jsi - React-jsinspectorcdp @@ -2073,7 +2124,7 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon - SocketRocket - - React-RCTRuntime (0.81.1): + - React-RCTRuntime (0.82.0): - boost - DoubleConversion - fast_float @@ -2083,6 +2134,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - React-Core + - React-debug - React-jsi - React-jsinspector - React-jsinspectorcdp @@ -2093,7 +2145,7 @@ PODS: - React-runtimeexecutor - React-RuntimeHermes - SocketRocket - - React-RCTSettings (0.81.1): + - React-RCTSettings (0.82.0): - boost - DoubleConversion - fast_float @@ -2108,10 +2160,10 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon - SocketRocket - - React-RCTText (0.81.1): - - React-Core/RCTTextHeaders (= 0.81.1) + - React-RCTText (0.82.0): + - React-Core/RCTTextHeaders (= 0.82.0) - Yoga - - React-RCTVibration (0.81.1): + - React-RCTVibration (0.82.0): - boost - DoubleConversion - fast_float @@ -2125,11 +2177,11 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon - SocketRocket - - React-rendererconsistency (0.81.1) - - React-renderercss (0.81.1): + - React-rendererconsistency (0.82.0) + - React-renderercss (0.82.0): - React-debug - React-utils - - React-rendererdebug (0.81.1): + - React-rendererdebug (0.82.0): - boost - DoubleConversion - fast_float @@ -2139,7 +2191,7 @@ PODS: - RCT-Folly/Fabric - React-debug - SocketRocket - - React-RuntimeApple (0.81.1): + - React-RuntimeApple (0.82.0): - boost - DoubleConversion - fast_float @@ -2168,7 +2220,7 @@ PODS: - React-runtimescheduler - React-utils - SocketRocket - - React-RuntimeCore (0.81.1): + - React-RuntimeCore (0.82.0): - boost - DoubleConversion - fast_float @@ -2190,7 +2242,7 @@ PODS: - React-runtimescheduler - React-utils - SocketRocket - - React-runtimeexecutor (0.81.1): + - React-runtimeexecutor (0.82.0): - boost - DoubleConversion - fast_float @@ -2200,10 +2252,10 @@ PODS: - RCT-Folly/Fabric - React-debug - React-featureflags - - React-jsi (= 0.81.1) + - React-jsi (= 0.82.0) - React-utils - SocketRocket - - React-RuntimeHermes (0.81.1): + - React-RuntimeHermes (0.82.0): - boost - DoubleConversion - fast_float @@ -2224,7 +2276,7 @@ PODS: - React-runtimeexecutor - React-utils - SocketRocket - - React-runtimescheduler (0.81.1): + - React-runtimescheduler (0.82.0): - boost - DoubleConversion - fast_float @@ -2246,9 +2298,9 @@ PODS: - React-timing - React-utils - SocketRocket - - React-timing (0.81.1): + - React-timing (0.82.0): - React-debug - - React-utils (0.81.1): + - React-utils (0.82.0): - boost - DoubleConversion - fast_float @@ -2258,11 +2310,27 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - React-debug - - React-jsi (= 0.81.1) + - React-jsi (= 0.82.0) + - SocketRocket + - React-webperformancenativemodule (0.82.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - React-jsi + - React-jsiexecutor + - React-performancetimeline + - React-RCTFBReactNativeSpec + - React-runtimeexecutor + - ReactCommon/turbomodule/core - SocketRocket - - ReactAppDependencyProvider (0.81.1): + - ReactAppDependencyProvider (0.82.0): - ReactCodegen - - ReactCodegen (0.81.1): + - ReactCodegen (0.82.0): - boost - DoubleConversion - fast_float @@ -2288,7 +2356,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - SocketRocket - - ReactCommon (0.81.1): + - ReactCommon (0.82.0): - boost - DoubleConversion - fast_float @@ -2296,9 +2364,9 @@ PODS: - glog - RCT-Folly - RCT-Folly/Fabric - - ReactCommon/turbomodule (= 0.81.1) + - ReactCommon/turbomodule (= 0.82.0) - SocketRocket - - ReactCommon/turbomodule (0.81.1): + - ReactCommon/turbomodule (0.82.0): - boost - DoubleConversion - fast_float @@ -2307,15 +2375,15 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-callinvoker (= 0.81.1) - - React-cxxreact (= 0.81.1) - - React-jsi (= 0.81.1) - - React-logger (= 0.81.1) - - React-perflogger (= 0.81.1) - - ReactCommon/turbomodule/bridging (= 0.81.1) - - ReactCommon/turbomodule/core (= 0.81.1) + - React-callinvoker (= 0.82.0) + - React-cxxreact (= 0.82.0) + - React-jsi (= 0.82.0) + - React-logger (= 0.82.0) + - React-perflogger (= 0.82.0) + - ReactCommon/turbomodule/bridging (= 0.82.0) + - ReactCommon/turbomodule/core (= 0.82.0) - SocketRocket - - ReactCommon/turbomodule/bridging (0.81.1): + - ReactCommon/turbomodule/bridging (0.82.0): - boost - DoubleConversion - fast_float @@ -2324,13 +2392,13 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-callinvoker (= 0.81.1) - - React-cxxreact (= 0.81.1) - - React-jsi (= 0.81.1) - - React-logger (= 0.81.1) - - React-perflogger (= 0.81.1) + - React-callinvoker (= 0.82.0) + - React-cxxreact (= 0.82.0) + - React-jsi (= 0.82.0) + - React-logger (= 0.82.0) + - React-perflogger (= 0.82.0) - SocketRocket - - ReactCommon/turbomodule/core (0.81.1): + - ReactCommon/turbomodule/core (0.82.0): - boost - DoubleConversion - fast_float @@ -2339,14 +2407,14 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-callinvoker (= 0.81.1) - - React-cxxreact (= 0.81.1) - - React-debug (= 0.81.1) - - React-featureflags (= 0.81.1) - - React-jsi (= 0.81.1) - - React-logger (= 0.81.1) - - React-perflogger (= 0.81.1) - - React-utils (= 0.81.1) + - React-callinvoker (= 0.82.0) + - React-cxxreact (= 0.82.0) + - React-debug (= 0.82.0) + - React-featureflags (= 0.82.0) + - React-jsi (= 0.82.0) + - React-logger (= 0.82.0) + - React-perflogger (= 0.82.0) + - React-utils (= 0.82.0) - SocketRocket - RNCAsyncStorage (2.2.0): - boost @@ -2376,19 +2444,19 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - rnmapbox-maps (10.2.7): - - MapboxMaps (~> 11.15.2) + - rnmapbox-maps (10.3.0): + - MapboxMaps (~> 11.16.2) - React - React-Core - - rnmapbox-maps/DynamicLibrary (= 10.2.7) + - rnmapbox-maps/DynamicLibrary (= 10.3.0) - Turf - - rnmapbox-maps/DynamicLibrary (10.2.7): + - rnmapbox-maps/DynamicLibrary (10.3.0): - boost - DoubleConversion - fast_float - fmt - hermes-engine - - MapboxMaps (~> 11.15.2) + - MapboxMaps (~> 11.16.2) - RCT-Folly - RCT-Folly/Fabric - RCTRequired @@ -2408,6 +2476,98 @@ PODS: - SocketRocket - Turf - Yoga + - RNReanimated (4.1.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNReanimated/reanimated (= 4.1.3) + - RNWorklets + - SocketRocket + - Yoga + - RNReanimated/reanimated (4.1.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNReanimated/reanimated/apple (= 4.1.3) + - RNWorklets + - SocketRocket + - Yoga + - RNReanimated/reanimated/apple (4.1.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNWorklets + - SocketRocket + - Yoga - RNScreens (4.16.0): - boost - DoubleConversion @@ -2495,6 +2655,95 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga + - RNWorklets (0.6.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNWorklets/worklets (= 0.6.1) + - SocketRocket + - Yoga + - RNWorklets/worklets (0.6.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNWorklets/worklets/apple (= 0.6.1) + - SocketRocket + - Yoga + - RNWorklets/worklets/apple (0.6.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - SocketRocket (0.7.1) - Turf (4.0.0) - Yoga (0.0.0) @@ -2545,6 +2794,7 @@ DEPENDENCIES: - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-oscompat (from `../node_modules/react-native/ReactCommon/oscompat`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) + - React-performancecdpmetrics (from `../node_modules/react-native/ReactCommon/react/performance/cdpmetrics`) - React-performancetimeline (from `../node_modules/react-native/ReactCommon/react/performance/timeline`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -2569,13 +2819,16 @@ DEPENDENCIES: - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) - React-timing (from `../node_modules/react-native/ReactCommon/react/timing`) - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) + - React-webperformancenativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/webperformance`) - ReactAppDependencyProvider (from `build/generated/ios`) - ReactCodegen (from `build/generated/ios`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - rnmapbox-maps (from `../..`) + - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) + - RNWorklets (from `../node_modules/react-native-worklets`) - SocketRocket (~> 0.7.1) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) @@ -2602,7 +2855,7 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" - :tag: hermes-2025-07-07-RNv0.81.0-e0fc67142ec0763c6b6153ca2bf96df815539782 + :tag: hermes-2025-09-01-RNv0.82.0-265ef62ff3eb7289d17e366664ac0da82303e101 RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTDeprecation: @@ -2677,6 +2930,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/oscompat" React-perflogger: :path: "../node_modules/react-native/ReactCommon/reactperflogger" + React-performancecdpmetrics: + :path: "../node_modules/react-native/ReactCommon/react/performance/cdpmetrics" React-performancetimeline: :path: "../node_modules/react-native/ReactCommon/react/performance/timeline" React-RCTActionSheet: @@ -2725,6 +2980,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/react/timing" React-utils: :path: "../node_modules/react-native/ReactCommon/react/utils" + React-webperformancenativemodule: + :path: "../node_modules/react-native/ReactCommon/react/nativemodule/webperformance" ReactAppDependencyProvider: :path: build/generated/ios ReactCodegen: @@ -2735,10 +2992,14 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-async-storage/async-storage" rnmapbox-maps: :path: "../.." + RNReanimated: + :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" RNVectorIcons: :path: "../node_modules/react-native-vector-icons" + RNWorklets: + :path: "../node_modules/react-native-worklets" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -2746,85 +3007,89 @@ SPEC CHECKSUMS: boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 - FBLazyVector: b8f1312d48447cca7b4abc21ed155db14742bd03 + FBLazyVector: 41b4dd99afd0aad861444ee141abdedaa6c3d238 fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 - hermes-engine: 4f8246b1f6d79f625e0d99472d1f3a71da4d28ca - MapboxCommon: 5b702d1562a1bc56a8a9d141ebbbaa72390536c9 - MapboxCoreMaps: ae6fcbe255e3fa9f290ee9cd72d125d1a2ecabfa - MapboxMaps: 7627bc07bcad10259668d83a3f0ed3920ee0eaf7 - RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f - RCTDeprecation: c4b9e2fd0ab200e3af72b013ed6113187c607077 - RCTRequired: e97dd5dafc1db8094e63bc5031e0371f092ae92a - RCTTypeSafety: 720403058b7c1380c6a3ae5706981d6362962c89 - React: f1486d005993b0af01943af1850d3d4f3b597545 - React-callinvoker: 133f69368c8559e744efa345223625d412f5dfbe - React-Core: d6d8c1fd33697cec596d33b820456505ee305686 - React-CoreModules: 81ab751a7668ba161440f9623b994e1a6a3019fe - React-cxxreact: 16f2a2751d0dce8b569f23c1914edc90f655b01b - React-debug: e01581e1589f329e61c95b332bf7f4969b10564b - React-defaultsnativemodule: e956b1d8fe15cc79d23061db229bf88170565f2f - React-domnativemodule: a18b0f7a31b9c75f12fa369baece5542d1265b36 - React-Fabric: c0237a32c3c0dbea2d2b294c8e95605e1dfe2f57 - React-FabricComponents: 65b03884bd5d9f24c79a631d7d26f0fa079bc4aa - React-FabricImage: de1ea2f2a0b32ad02e5cbb64827d1eec0439cf0d - React-featureflags: 02de9c35256cc624269b01d670d99e1fd706ea8d - React-featureflagsnativemodule: 8b84e67edbaa7b9318390c5bd3ae19790a74f356 - React-graphics: 004b40c1b236ea3bb8de6693439bef9797922ba9 - React-hermes: 2179a018b2f86652f6f33ef23efd9e5ac284b247 - React-idlecallbacksnativemodule: f54ea68f984b12e42feed1e7110623b2c38df4d1 - React-ImageManager: 9dd04b7b62bc5397f876ca5fb1b712e700ce390c - React-jserrorhandler: 2f90bf50fffea1d012e7f3d717c6adf748b1813d - React-jsi: b27208f8866e53238534f65f304903e4eff25e05 - React-jsiexecutor: 1d3e827797f592c393860dea91aaa6d53c7715e7 - React-jsinspector: bda319277ae779bc476b736fe3a497c6aed304cd - React-jsinspectorcdp: 69e1736edfd5420037680b7b4557fa748c3c8216 - React-jsinspectornetwork: 7aa707b057c6129b4af59e0c9160436bbab25022 - React-jsinspectortracing: b4a8a328ad2697f9638daa4b7cc054e0303fa47f - React-jsitooling: a6c7e2829437b28665e97a398b3374d443125e24 - React-jsitracing: d87ae17dd0eef7844e605945da926c5433fe2b51 - React-logger: d27dd2000f520bf891d24f6e141cde34df41f0ee - React-Mapbuffer: 0746ffab5ac0f49b7c9347338e3d0c1d9dd634c8 - React-microtasksnativemodule: b0fb3f97372df39bda3e657536039f1af227cc29 - react-native-safe-area-context: 6d8a7b750e496e37bda47c938320bf2c734d441f - React-NativeModulesApple: 9ec9240159974c94886ebbe4caec18e3395f6aef - React-oscompat: b12c633e9c00f1f99467b1e0e0b8038895dae436 - React-perflogger: ccf4fd2664b00818645e588623c7531a8b32d114 - React-performancetimeline: a866ba759d8e06e9ba174b4421677edcae487baf - React-RCTActionSheet: 3f741a3712653611a6bfc5abceb8260af9d0b218 - React-RCTAnimation: 2edeebfba175cc2e937e2752209ab605d3c48f21 - React-RCTAppDelegate: e292321e83ee966897244a032216a70930b758d6 - React-RCTBlob: 8dfb24b6dd4a5af45e1e59e2fd925b2df1e44d08 - React-RCTFabric: b25b02a2016f5cb15926a60c77a8d75865aa3558 - React-RCTFBReactNativeSpec: 20338571a1ed853d01da6c68576aa6e8e107b6f6 - React-RCTImage: c7fe8c2f2ae8bad98ab4d944d5d50a889da4b652 - React-RCTLinking: 9ac21ce9f1af914bb01c06af3752db2ec840d0ee - React-RCTNetwork: 09a5de71d757dbad4b3fe3615839290200b932aa - React-RCTRuntime: da3f1e0ce088c20350044cdf1efcd7f8d9b9b40c - React-RCTSettings: fee112652ac7569ea9abe910206e1685f5f9adba - React-RCTText: 7ee9d0bc16b3a8149f8df6d70c48e724d0db1d89 - React-RCTVibration: 619d613abaeb05f6fbc2b2e5e33f724f05df8eb8 - React-rendererconsistency: a05f6c37f9389c53213d1e28798e441fa6fbdbcd - React-renderercss: 3decb27a81648fcdee837c59994b51fff5be5a67 - React-rendererdebug: 3b9a92d36932af52e1b473f2a89ea4b05dbdecdf - React-RuntimeApple: 4e35fb74be4b721c2e1fd6d54ec66456fa7043e9 - React-RuntimeCore: 0fd7ac6e3e9dd20cb47e87c6b9f35832dd445d5e - React-runtimeexecutor: 7680156c9f3a5a49c688bc33f9ec5ea1b00527f5 - React-RuntimeHermes: 435b7104a3c749af6251353dcb7317a8e53cbd73 - React-runtimescheduler: 8056b916168e446ea44531883928034e62e76a81 - React-timing: 36da85e32e53008ce73f87528818191e7f2508ba - React-utils: 71e53d55ce778c6e7c7c9db4b1b9d63ef8f55289 - ReactAppDependencyProvider: 448b422f8af1dedf81374eacc90a15439a0ed7f5 - ReactCodegen: 3baedb0c33f963250c866151b825a3c5194b12f1 - ReactCommon: e897f9a1b4afab370cfefaaf5fb3c80371bc3937 - RNCAsyncStorage: 302f2fac014fd450046c120567ca364632da682b - rnmapbox-maps: 7269bdcd5cb3716d27e07d3632384792f655be32 - RNScreens: 74985ca8e102294a60cec7513fa84c936fa0b20b - RNVectorIcons: 6acc19c833be864e9c70894e101a587fe491150a + hermes-engine: 8642d8f14a548ab718ec112e9bebdfdd154138b5 + MapboxCommon: 10cbf74edb23c9abcfe2424899d804f288a47334 + MapboxCoreMaps: f19680d20681797067268284b2292349de861730 + MapboxMaps: 04c7bf46d66265ad0f4b98484a251777a926c423 + RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 + RCTDeprecation: 22bf66112da540a7d40e536366ddd8557934fca1 + RCTRequired: a0ed4dc41b35f79fbb6d8ba320e06882a8c792cf + RCTTypeSafety: 59a046ff1e602409a86b89fcd6edff367a5b14af + React: ade831e2e38887292c2c7d40f2f4098826a9dda4 + React-callinvoker: fb097304922c5da47152147a5fb0712713438575 + React-Core: 60e3adb5af2863587d4a0650a0bbf8d5b1327502 + React-CoreModules: 8647d480cf788eb0e0ae353db836dbb5edb98eb0 + React-cxxreact: 2be8c8494b345bd1896f542bafc18dff72335c55 + React-debug: c855f7565d8c4aeceb23219ca3baa0e1ebfb578a + React-defaultsnativemodule: 88870580c41100965ead4ae46b7e6b47825e1c9a + React-domnativemodule: 5624a09547dbf9e01bd4274a4ec5666209bb96bf + React-Fabric: 95df97f2ee3469efa70f37d7e23109b43405c683 + React-FabricComponents: c2718daaee02101a4e4958e35abcf038c5f8525e + React-FabricImage: 46deb618808c5f211ac91ad8a417a955c96d3b93 + React-featureflags: 37120df645adeaa3d634f15bfb3f47bf3701147f + React-featureflagsnativemodule: 8afcb75324b1ba0d2174b88d4c413b0512345014 + React-graphics: 43dbe83e403ec3dec26b41f7c484c4d8a5fee656 + React-hermes: 5061dfbb68b7cc4a015302b4c9125c5d7426f9f9 + React-idlecallbacksnativemodule: 9e1782dce65fed2fb2f7b1049274dad9cbb76f9a + React-ImageManager: 119a820c7c207d7fcbdd3386f74856dc071d3040 + React-jserrorhandler: 2d2c2c3ac205ce415fc36d51c300bec6f74449d0 + React-jsi: a884efb76496c1492c8063918d5588f3e2ab8b42 + React-jsiexecutor: 47e858b79890e212469a76d61edd871b1444e869 + React-jsinspector: 80d4292bdf4163de86564ee7b8384f7d4e40df8c + React-jsinspectorcdp: 26ddf22f569bc8bf1ebd4d644de53614d68eba92 + React-jsinspectornetwork: c8a66abfc5928b00a1729a97314207e4c8a1790c + React-jsinspectortracing: bf319882c2ef5ec76bb2ba1632fbd388cfeea569 + React-jsitooling: fa5a0040eeb62e2340c2fad1732735ae449bcd38 + React-jsitracing: 2c6bf5ef2527c6fe1ee55faa950c70f1a5e7cd8e + React-logger: 30adf849117e87cf86e88dca1824bb0f18f87e10 + React-Mapbuffer: 499069c3dcd4b438a70fcc2a65e8a4185ea9170b + React-microtasksnativemodule: f0238469cb9894fd18c419137d312665b8fc05b3 + react-native-safe-area-context: c6e2edd1c1da07bdce287fa9d9e60c5f7b514616 + React-NativeModulesApple: 628df250681ccb569bd203494ed5187269580d6f + React-oscompat: 80ca388c4831481cd03a6b45ecfc82739ca9a95e + React-perflogger: 9725c8b401ca406f52e4bb59bf0b22ef9354f96a + React-performancecdpmetrics: b8bfac3d66e8ba7aede1e3629f786e6450838e99 + React-performancetimeline: 848b4852baa600174446670f9fab860da2bd1d88 + React-RCTActionSheet: 2f0a844b3f4b749ce54bee10e5006aacbcb754e0 + React-RCTAnimation: 680cd054a53b6525b587e6e1f1aeb885135e28cd + React-RCTAppDelegate: 5f8969018d773b22ca0b4c9679c3bad73767c5c7 + React-RCTBlob: 9bcdb5549e877fc08684f129047fbf029e37eabe + React-RCTFabric: 06c4c93dffb204c9a54f8ab41c0a0a24ec209cdd + React-RCTFBReactNativeSpec: afd34c1c42b0f1d306a57c9d1c63e9993c41f3cf + React-RCTImage: 937d9ebf5b92f688c2c501de731af47a4df2c208 + React-RCTLinking: b0fde8f005ffd6bdbb9e274a8f132f0e61cb0185 + React-RCTNetwork: 0c23d5f6a3544c98065fed622ef7ed2bce593cb5 + React-RCTRuntime: 158407a5a2edfc3ab01aa4c301c8d246e234a328 + React-RCTSettings: 093d5fba8bfb4c80a409b06f1e99156e4b7ffa8b + React-RCTText: 286dc4b5314a45b8beb8d06d7fd46b0f9da264ac + React-RCTVibration: 080c11b0ec39f1202bbd91e468dba50894fe4233 + React-rendererconsistency: 74f53d2a1fa3bd87ed3fdbc83ad69cecf4bd0cb7 + React-renderercss: 564483d161020cec10e91a364c2d4fabad91c13e + React-rendererdebug: bdf0a36e11247b67c8c13095c7512f0ad3197d2f + React-RuntimeApple: 881afe60c37cf1ce5af6e84952cb1bb05237222c + React-RuntimeCore: e796152403fee6a4ad7263e767ce78a4dd15a8d5 + React-runtimeexecutor: 5cd2fbb140e093ead45632e7558bda5e816acebd + React-RuntimeHermes: 113d9aca75644e8bbcf976d4b53e58c3f2666591 + React-runtimescheduler: c0a466837f8ac8e6f009aff038d2cedc4b401650 + React-timing: 89ea436bb6d784f3ec4648e40ffd0492f7b1ea33 + React-utils: 96191b0f5e02b57c70a4bbf7b6f6721958e1d369 + React-webperformancenativemodule: 9c76ddf8d1a243e2eecd7ce1aeadb46ceccbdbd2 + ReactAppDependencyProvider: c5c4f5280e4ae0f9f4a739c64c4260fe0b3edaf1 + ReactCodegen: 374f1c9242fbdd673b460d358b33860c0cc9d926 + ReactCommon: 25c7f94aee74ddd93a8287756a8ac0830a309544 + RNCAsyncStorage: 29f0230e1a25f36c20b05f65e2eb8958d6526e82 + rnmapbox-maps: bf6182eaabb29ac87350635ece7f38fe85dc7364 + RNReanimated: 732e7d1662f8cc0e533fa32791800de5b5934726 + RNScreens: 0bbf16c074ae6bb1058a7bf2d1ae017f4306797c + RNVectorIcons: 791f13226ec4a3fd13062eda9e892159f0981fae + RNWorklets: ab618bf7d1c7fd2cb793b9f0f39c3e29274b3ebf SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Turf: c9eb11a65d96af58cac523460fd40fec5061b081 - Yoga: fa23995c18b65978347b096d0836f4f5093df545 + Yoga: 93bc00d78638987f9ffd928f4a9f895d3e601bc3 -PODFILE CHECKSUM: 4d32367122d25b7d1454f5251323be49f7228d81 +PODFILE CHECKSUM: a8d0bcee36da1ae6663f56323461c0f72eac22a6 COCOAPODS: 1.16.2 diff --git a/example/ios/RNMapboxExample.xcodeproj/project.pbxproj b/example/ios/RNMapboxExample.xcodeproj/project.pbxproj index 7fc22cd973..3e65c85b82 100644 --- a/example/ios/RNMapboxExample.xcodeproj/project.pbxproj +++ b/example/ios/RNMapboxExample.xcodeproj/project.pbxproj @@ -264,7 +264,7 @@ "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCommon/MapboxCommon.framework/MapboxCommon", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCoreMaps/MapboxCoreMaps.framework/MapboxCoreMaps", "${PODS_XCFRAMEWORKS_BUILD_DIR}/Turf/Turf.framework/Turf", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermesvm.framework/hermesvm", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -272,7 +272,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCommon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCoreMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Turf.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermesvm.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/example/ios/RNMapboxExample/Info.plist b/example/ios/RNMapboxExample/Info.plist index 8e8c9a2fd2..aeea131590 100644 --- a/example/ios/RNMapboxExample/Info.plist +++ b/example/ios/RNMapboxExample/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion en CFBundleDisplayName diff --git a/example/package.json b/example/package.json index 9a058a9ea3..a670e798ca 100644 --- a/example/package.json +++ b/example/package.json @@ -37,11 +37,13 @@ "lodash.isequal": "^4.5.0", "moment": "^2.30.1", "prop-types": "^15.8.1", - "react": "19.1.0", - "react-native": "0.81.1", + "react": "19.1.1", + "react-native": "0.82.0", + "react-native-reanimated": "^4.1.3", "react-native-safe-area-context": "^5.6.1", "react-native-screens": "^4.15.2", - "react-native-vector-icons": "^10.3.0" + "react-native-vector-icons": "^10.3.0", + "react-native-worklets": "^0.6.1" }, "optionalDependencies": { "@expo/metro-runtime": "~6.1.2", @@ -58,18 +60,18 @@ "@react-native-community/cli": "^20.0.1", "@react-native-community/cli-platform-android": "^20.0.1", "@react-native-community/cli-platform-ios": "^20.0.1", - "@react-native/babel-preset": "^0.81.1", - "@react-native/eslint-config": "^0.81.1", - "@react-native/metro-config": "^0.81.1", - "@react-native/typescript-config": "^0.81.1", + "@react-native/babel-preset": "^0.82.0", + "@react-native/eslint-config": "^0.82.0", + "@react-native/metro-config": "^0.82.0", + "@react-native/typescript-config": "^0.82.0", "@types/lodash.isequal": "^4.5.8", "@types/prop-types": "^15.7.15", - "@types/react": "^19.1.10", + "@types/react": "^19.1.1", "@types/react-test-renderer": "^19.1.0", "babel-jest": "^30.1.2", "babel-plugin-module-resolver": "^5.0.2", "babel-plugin-react-compiler": "^1.0.0", - "detox": "^20.40.2", + "detox": "^20.47.0", "eslint": "^8.19.0", "eslint-plugin-react-hooks": "latest", "glob-to-regexp": "^0.4.1", @@ -79,7 +81,7 @@ "prettier": "^2.8.8", "react-native-builder-bob": "^0.40.13", "react-native-monorepo-config": "^0.1.9", - "react-test-renderer": "19.1.0", + "react-test-renderer": "19.1.1", "typescript": "^5.8.3" }, "engines": { diff --git a/example/src/App.js b/example/src/App.js index 04542c84c1..f08563a870 100755 --- a/example/src/App.js +++ b/example/src/App.js @@ -1,6 +1,6 @@ import React from 'react'; import Mapbox from '@rnmapbox/maps'; -import { StyleSheet, Text, View, LogBox } from 'react-native'; +import { StyleSheet, Text, View } from 'react-native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { NavigationContainer } from '@react-navigation/native'; import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'; @@ -13,11 +13,6 @@ import { Group, Item } from './scenes/GroupAndItem'; import { ScreenWithoutMap } from './scenes/ScreenWithoutMap'; import MapInModal from './examples/Map/MapInModal'; -LogBox.ignoreLogs([ - 'Warning: isMounted(...) is deprecated', - 'Module RCTImageLoader', -]); - const styles = StyleSheet.create({ noPermissionsText: { fontSize: 18, diff --git a/example/src/examples/Annotations/MarkerView.tsx b/example/src/examples/Annotations/MarkerView.tsx index 7b3e03ddf8..1ea6380b14 100644 --- a/example/src/examples/Annotations/MarkerView.tsx +++ b/example/src/examples/Annotations/MarkerView.tsx @@ -1,5 +1,15 @@ import React from 'react'; -import { Button, StyleSheet, View, Text, TouchableOpacity } from 'react-native'; +import { + Button, + Pressable, + StyleSheet, + Switch, + Text, + TextInput, + TouchableOpacity, + View, +} from 'react-native'; +import { Slider } from '@rneui/base'; import Mapbox from '@rnmapbox/maps'; import Bubble from '../common/Bubble'; @@ -19,6 +29,115 @@ const styles = StyleSheet.create({ fontWeight: 'bold', }, matchParent: { flex: 1 }, + interactiveCard: { + backgroundColor: 'white', + borderRadius: 12, + padding: 12, + width: 200, + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.25, + shadowRadius: 4, + elevation: 5, + borderWidth: 1, + borderColor: '#ddd', + }, + cardTitle: { + fontWeight: 'bold', + fontSize: 13, + marginBottom: 8, + color: '#333', + }, + sliderLabel: { + fontSize: 11, + color: '#666', + marginBottom: 2, + }, + sliderValue: { + fontSize: 11, + fontWeight: '600', + color: '#333', + textAlign: 'right', + }, + sliderRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginBottom: 4, + }, + switchRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginVertical: 4, + }, + switchLabel: { + fontSize: 11, + color: '#666', + }, + counterRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + marginVertical: 6, + }, + counterButton: { + backgroundColor: '#4A90D9', + width: 30, + height: 30, + borderRadius: 15, + alignItems: 'center', + justifyContent: 'center', + }, + counterButtonText: { + color: 'white', + fontWeight: 'bold', + fontSize: 16, + }, + counterValue: { + fontSize: 16, + fontWeight: 'bold', + marginHorizontal: 16, + minWidth: 24, + textAlign: 'center', + }, + textInput: { + borderWidth: 1, + borderColor: '#ccc', + borderRadius: 6, + paddingHorizontal: 8, + paddingVertical: 4, + fontSize: 11, + marginTop: 4, + backgroundColor: '#fafafa', + }, + pressableButton: { + marginTop: 8, + backgroundColor: '#4A90D9', + borderRadius: 6, + paddingVertical: 6, + alignItems: 'center', + }, + pressableButtonPressed: { + backgroundColor: '#2E6DB4', + }, + pressableText: { + color: 'white', + fontWeight: '600', + fontSize: 12, + }, + colorPreview: { + height: 20, + borderRadius: 4, + marginTop: 4, + borderWidth: 1, + borderColor: '#ccc', + }, + divider: { + height: 1, + backgroundColor: '#eee', + marginVertical: 6, + }, }); const AnnotationContent = ({ title }: { title: string }) => ( @@ -29,9 +148,125 @@ const AnnotationContent = ({ title }: { title: string }) => ( ); + +/** + * An interactive MarkerView with slider, switch, counter, text input, and + * pressable button — useful for verifying that complex touch interactions + * work correctly inside a MarkerView. + */ +const InteractiveMarkerContent = () => { + const [sliderValue, setSliderValue] = React.useState(0.5); + const [opacity, setOpacity] = React.useState(1.0); + const [toggleOn, setToggleOn] = React.useState(false); + const [counter, setCounter] = React.useState(0); + const [note, setNote] = React.useState(''); + const [pressCount, setPressCount] = React.useState(0); + + const hue = Math.round(sliderValue * 360); + const bgColor = `hsla(${hue}, 70%, 55%, ${opacity})`; + + return ( + + Interactive Marker + + {/* Slider: Hue */} + + Hue + {hue}° + + + + {/* Slider: Opacity */} + + Opacity + {opacity.toFixed(2)} + + + + {/* Color preview */} + + + + + {/* Switch */} + + + Toggle: {toggleOn ? 'ON' : 'OFF'} + + + + + + + {/* Counter */} + + setCounter((c) => c - 1)} + > + + + {counter} + setCounter((c) => c + 1)} + > + + + + + + + + {/* Text input */} + Note + + + {/* Pressable button */} + [ + styles.pressableButton, + pressed && styles.pressableButtonPressed, + ]} + onPress={() => setPressCount((c) => c + 1)} + > + + Pressed {pressCount} time{pressCount !== 1 ? 's' : ''} + + + + ); +}; + const INITIAL_COORDINATES: [number, number][] = [ [-73.99155, 40.73581], [-73.99155, 40.73681], + [-73.98955, 40.73581], ]; const ShowMarkerView = () => { @@ -68,13 +303,21 @@ const ShowMarkerView = () => { - {pointList.slice(2).map((coordinate, index) => ( + + + + + {pointList.slice(3).map((coordinate, index) => ( - - Generating Snapshot - - ); - } else { - childView = ( - - + + Generating Snapshots... ); } - return childView; + return ( + + + With Logo (withLogo: true) + {withLogoURI && ( + + )} + + + + Without Logo (withLogo: false) + {withoutLogoURI && ( + + )} + + + + + Using Bounds (instead of centerCoordinate) + + {boundsURI && ( + + )} + + + { + this.setState({ loading: true }); + this.takeAllSnapshots(); + }} + > + Retake Snapshots + + + ); } } diff --git a/example/src/examples/FillRasterLayer/HillshadeSource.tsx b/example/src/examples/FillRasterLayer/HillshadeSource.tsx new file mode 100644 index 0000000000..6c70ced40b --- /dev/null +++ b/example/src/examples/FillRasterLayer/HillshadeSource.tsx @@ -0,0 +1,60 @@ +import { useState } from 'react'; +import { Button } from 'react-native'; +import { + MapView, + Camera, + RasterDemSource, + HillshadeLayer, +} from '@rnmapbox/maps'; + +const HillshadeSource = () => { + const [showHillshade, setShowHillshade] = useState(true); + + return ( + <> +