Skip to content

Commit

Permalink
fix(android): remove ts and use NativeModule instead of setNativeProp…
Browse files Browse the repository at this point in the history
…s to update camera with imperative method (#3376)
  • Loading branch information
mfazekas authored Feb 14, 2024
1 parent 85d12b5 commit b90fe4b
Show file tree
Hide file tree
Showing 15 changed files with 362 additions and 120 deletions.
15 changes: 13 additions & 2 deletions android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.rnmapbox.rnmbx.components.annotation.RNMBXMarkerViewManager
import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationManager
import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationModule
import com.rnmapbox.rnmbx.components.camera.RNMBXCameraManager
import com.rnmapbox.rnmbx.components.camera.RNMBXCameraModule
import com.rnmapbox.rnmbx.components.camera.RNMBXViewport
import com.rnmapbox.rnmbx.components.camera.RNMBXViewportManager
import com.rnmapbox.rnmbx.components.camera.RNMBXViewportModule
Expand Down Expand Up @@ -96,6 +97,7 @@ class RNMBXPackage : TurboReactPackage() {
RNMBXSnapshotModule.REACT_CLASS -> return RNMBXSnapshotModule(reactApplicationContext)
RNMBXLogging.REACT_CLASS -> return RNMBXLogging(reactApplicationContext)
NativeMapViewModule.NAME -> return NativeMapViewModule(reactApplicationContext, getViewTagResolver(reactApplicationContext, s))
RNMBXCameraModule.NAME -> return RNMBXCameraModule(reactApplicationContext, getViewTagResolver(reactApplicationContext, s))
RNMBXViewportModule.NAME -> return RNMBXViewportModule(reactApplicationContext, getViewTagResolver(reactApplicationContext, s))
RNMBXShapeSourceModule.NAME -> return RNMBXShapeSourceModule(reactApplicationContext, getViewTagResolver(reactApplicationContext, s))
RNMBXImageModule.NAME -> return RNMBXImageModule(reactApplicationContext, getViewTagResolver(reactApplicationContext, s))
Expand All @@ -114,8 +116,8 @@ class RNMBXPackage : TurboReactPackage() {
val managers: MutableList<ViewManager<*, *>> = ArrayList()

// components
managers.add(RNMBXCameraManager(reactApplicationContext))
managers.add(RNMBXViewportManager(reactApplicationContext))
managers.add(RNMBXCameraManager(reactApplicationContext, getViewTagResolver(reactApplicationContext, "RNMBXCameraManager")))
managers.add(RNMBXViewportManager(reactApplicationContext, getViewTagResolver(reactApplicationContext, "RNMBXViewportManager")))
managers.add(RNMBXMapViewManager(reactApplicationContext, getViewTagResolver(reactApplicationContext, "RNMBXMapViewManager")))
managers.add(RNMBXStyleImportManager(reactApplicationContext))
managers.add(RNMBXModelsManager(reactApplicationContext))
Expand Down Expand Up @@ -245,6 +247,15 @@ class RNMBXPackage : TurboReactPackage() {
false, // isCxxModule
isTurboModule // isTurboModule
)
moduleInfos[RNMBXCameraModule.NAME] = ReactModuleInfo(
RNMBXCameraModule.NAME,
RNMBXCameraModule.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
false, // hasConstants
false, // isCxxModule
isTurboModule // isTurboModule
)
moduleInfos[RNMBXShapeSourceModule.NAME] = ReactModuleInfo(
RNMBXShapeSourceModule.NAME,
RNMBXShapeSourceModule.NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ class CameraStop {
private var mDuration = 2000
private var mCallback: Animator.AnimatorListener? = null

var ts: Int? = null

fun setBearing(bearing: Double) {
mBearing = bearing
}
Expand Down Expand Up @@ -156,10 +154,6 @@ class CameraStop {
): CameraStop {
val stop = CameraStop()

if (readableMap.hasKey("__updateTS")) {
stop.ts = readableMap.getInt("__updateTS")
}

if (readableMap.hasKey("pitch")) {
stop.setTilt(readableMap.getDouble("pitch"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.rnmapbox.rnmbx.components.camera
import android.animation.Animator
import android.content.Context
import android.location.Location
import com.facebook.react.bridge.Dynamic
import com.facebook.react.bridge.ReadableMap
import com.mapbox.maps.plugin.gestures.gestures
import com.rnmapbox.rnmbx.location.LocationManager.Companion.getInstance
Expand All @@ -15,6 +16,7 @@ import com.mapbox.maps.plugin.locationcomponent.OnIndicatorBearingChangedListene
import com.mapbox.maps.plugin.locationcomponent.OnIndicatorPositionChangedListener
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.WritableNativeMap
import com.facebook.react.uimanager.annotations.ReactProp
import com.mapbox.maps.*
import com.mapbox.maps.plugin.locationcomponent.location
import com.mapbox.maps.plugin.viewport.ViewportStatus
Expand Down Expand Up @@ -113,15 +115,18 @@ class RNMBXCamera(private val mContext: Context, private val mManager: RNMBXCame
}
}
fun setStop(stop: CameraStop) {
if ((stop.ts != mCameraStop?.ts) || (mCameraStop == null)) {
mCameraStop = stop
stop.setCallback(mCameraCallback)
if (mMapView != null) {
stop.let { updateCamera(it) }
}
mCameraStop = stop
stop.setCallback(mCameraCallback)
if (mMapView != null) {
stop.let { updateCamera(it) }
}
}

fun updateCameraStop(map: ReadableMap) {
val stop = CameraStop.fromReadableMap(mContext, map, null)
setStop(stop)
}

fun setDefaultStop(stop: CameraStop?) {
mDefaultStop = stop
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import com.mapbox.geojson.FeatureCollection
import com.rnmapbox.rnmbx.components.AbstractEventEmitter
import com.rnmapbox.rnmbx.components.camera.CameraStop.Companion.fromReadableMap
import com.rnmapbox.rnmbx.utils.GeoJSONUtils.toLatLngBounds
import com.rnmapbox.rnmbx.utils.ViewTagResolver
import com.rnmapbox.rnmbx.utils.extensions.asBooleanOrNull
import com.rnmapbox.rnmbx.utils.extensions.asDoubleOrNull
import com.rnmapbox.rnmbx.utils.extensions.asStringOrNull

class RNMBXCameraManager(private val mContext: ReactApplicationContext) :
class RNMBXCameraManager(private val mContext: ReactApplicationContext, val viewTagResolver: ViewTagResolver) :
AbstractEventEmitter<RNMBXCamera?>(
mContext
), RNMBXCameraManagerInterface<RNMBXCamera> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.rnmapbox.rnmbx.components.camera

import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.WritableNativeMap
import com.rnmapbox.rnmbx.NativeRNMBXCameraModuleSpec
import com.rnmapbox.rnmbx.components.mapview.CommandResponse
import com.rnmapbox.rnmbx.utils.ViewTagResolver


class RNMBXCameraModule(context: ReactApplicationContext, val viewTagResolver: ViewTagResolver) : NativeRNMBXCameraModuleSpec(context) {
private fun withViewportOnUIThread(
viewRef: Double?,
reject: Promise,
fn: (RNMBXCamera) -> Unit
) {
if (viewRef == null) {
reject.reject(Exception("viewRef is null"))
} else {
viewTagResolver.withViewResolved(viewRef.toInt(), reject, fn)
}
}

private fun createCommandResponse(promise: Promise): CommandResponse = object : CommandResponse {
override fun success(builder: (WritableMap) -> Unit) {
val payload: WritableMap = WritableNativeMap()
builder(payload)

promise.resolve(payload)
}

override fun error(message: String) {
promise.reject(Exception(message))
}
}

companion object {
const val NAME = "RNMBXCameraModule"
}

override fun updateCameraStop(viewRef: Double?, stop: ReadableMap, promise: Promise) {
withViewportOnUIThread(viewRef, promise) {
it.updateCameraStop(stop)
promise.resolve(null)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import com.facebook.react.viewmanagers.RNMBXViewportManagerInterface
import com.rnmapbox.rnmbx.components.AbstractEventEmitter
import com.rnmapbox.rnmbx.events.constants.EventKeys
import com.rnmapbox.rnmbx.events.constants.eventMapOf
import com.rnmapbox.rnmbx.utils.ViewTagResolver

class RNMBXViewportManager(private val mContext: ReactApplicationContext) : AbstractEventEmitter<RNMBXViewport?>(
class RNMBXViewportManager(private val mContext: ReactApplicationContext, val viewTagResolver: ViewTagResolver) : AbstractEventEmitter<RNMBXViewport?>(
mContext
), RNMBXViewportManagerInterface<RNMBXViewport> {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleJavaSpec.js
*
* @nolint
*/

package com.rnmapbox.rnmbx;

import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactModuleWithSpec;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public abstract class NativeRNMBXCameraModuleSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule {
public static final String NAME = "RNMBXCameraModule";

public NativeRNMBXCameraModuleSpec(ReactApplicationContext reactContext) {
super(reactContext);
}

@Override
public @Nonnull String getName() {
return NAME;
}

@ReactMethod
@DoNotStrip
public abstract void updateCameraStop(@Nullable Double viewRef, ReadableMap stops, Promise promise);
}
4 changes: 4 additions & 0 deletions ios/RNMBX/RNMBXCamera.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ open class RNMBXCamera : RNMBXMapComponentBase {
map.viewport.idle()
}

@objc public func updateCameraStop(_ stop: [String: Any]) {
self.stop = stop
}

func _toCoordinateBounds(_ bounds: FeatureCollection) throws -> CoordinateBounds {
guard bounds.features.count == 2 else {
throw RNMBXError.paramError("Expected two Points in FeatureColletion")
Expand Down
18 changes: 18 additions & 0 deletions ios/RNMBX/RNMBXCameraModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#ifdef RCT_NEW_ARCH_ENABLED
#import "rnmapbox_maps_specs.h"
#else
#import <React/RCTBridge.h>
#endif

@interface RNMBXCameraModule : NSObject
#ifdef RCT_NEW_ARCH_ENABLED
<NativeRNMBXCameraModuleSpec>
#else
<RCTBridgeModule>
#endif

@end

67 changes: 67 additions & 0 deletions ios/RNMBX/RNMBXCameraModule.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#import <React/RCTBridge.h>
#import <React/RCTUIManager.h>
#import <React/RCTUIManagerUtils.h>

#import "RNMBXCameraModule.h"
#ifdef RCT_NEW_ARCH_ENABLED
#import "RNMBXCameraComponentView.h"
#endif // RCT_NEW_ARCH_ENABLED

#import "rnmapbox_maps-Swift.pre.h"

@implementation RNMBXCameraModule

RCT_EXPORT_MODULE();

#ifdef RCT_NEW_ARCH_ENABLED
@synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED;
#endif // RCT_NEW_ARCH_ENABLED
@synthesize bridge = _bridge;

- (dispatch_queue_t)methodQueue
{
// It seems that due to how UIBlocks work with uiManager, we need to call the methods there
// for the blocks to be dispatched before the batch is completed
return RCTGetUIManagerQueue();
}

// Thanks to this guard, we won't compile this code when we build for the old architecture.
#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeRNMBXCameraModuleSpecJSI>(params);
}
#endif // RCT_NEW_ARCH_ENABLED

- (void)withCamera:(nonnull NSNumber*)viewRef block:(void (^)(RNMBXCamera *))block reject:(RCTPromiseRejectBlock)reject methodName:(NSString *)methodName
{
#ifdef RCT_NEW_ARCH_ENABLED
[self.viewRegistry_DEPRECATED addUIBlock:^(RCTViewRegistry *viewRegistry) {
RNMBXCameraComponentView *componentView = [self.viewRegistry_DEPRECATED viewForReactTag:viewRef];
RNMBXCamera *view = componentView.contentView;

#else
[self.bridge.uiManager
addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
RNMBXCamera *view = [uiManager viewForReactTag:viewRef];
#endif // RCT_NEW_ARCH_ENABLED
if (view != nil) {
block(view);
} else {
reject(methodName, [NSString stringWithFormat:@"Unknown reactTag: %@", viewRef], nil);
}
}];
}

RCT_EXPORT_METHOD(updateCameraStop:(nonnull NSNumber *)viewRef
stop: (NSDictionary*)stop
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
{
[self withCamera:viewRef block:^(RNMBXCamera *view) {
[view updateCameraStop: stop];
} reject:reject methodName:@"someMethod"];
}

@end
4 changes: 4 additions & 0 deletions setup-jest.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ NativeModules.RNMBXViewportModule = {
getState: jest.fn(),
};

NativeModules.RNMBXCameraModule = {
updateCameraStop: jest.fn(),
};

NativeModules.RNMBXTileStoreModule = {
setOptions: jest.fn(),
shared: jest.fn(),
Expand Down
Loading

0 comments on commit b90fe4b

Please sign in to comment.