oblador / react-native-pinchable

Instagram like pinch to zoom for React Native
MIT License
224 stars 23 forks source link

adding onActive event #19

Open Bayramito opened 9 months ago

Bayramito commented 9 months ago

We needed this feature to be able to prevent click or any other events before pinch zoom completed.

diff --git a/node_modules/react-native-pinchable/android/src/main/java/com/oblador/pinchable/PinchableView.java b/node_modules/react-native-pinchable/android/src/main/java/com/oblador/pinchable/PinchableView.java
index 9f22074..b934292 100644
--- a/node_modules/react-native-pinchable/android/src/main/java/com/oblador/pinchable/PinchableView.java
+++ b/node_modules/react-native-pinchable/android/src/main/java/com/oblador/pinchable/PinchableView.java
@@ -18,6 +18,11 @@ import android.animation.ValueAnimator;
 import android.view.animation.DecelerateInterpolator;

 import com.facebook.react.views.view.ReactViewGroup;
+import com.facebook.react.uimanager.events.RCTEventEmitter;
+import com.facebook.react.bridge.WritableMap;
+import com.facebook.react.bridge.Arguments;
+
+import javax.annotation.Nullable;

 public class PinchableView extends ReactViewGroup implements OnTouchListener {
     private final int animationDuration = 400;
@@ -33,6 +38,7 @@ public class PinchableView extends ReactViewGroup implements OnTouchListener {
     private ValueAnimator currentAnimator = null;
     private ColorDrawable backdrop = null;
     private BitmapDrawable clone = null;
+    private @Nullable RCTEventEmitter mEventEmitter;

     public PinchableView(Context context) {
         super(context);
@@ -122,6 +128,7 @@ public class PinchableView extends ReactViewGroup implements OnTouchListener {
         }

         active = true;
+        setOnActive(true);

         if (backdrop == null) {
             backdrop = new ColorDrawable(Color.BLACK);
@@ -195,6 +202,7 @@ public class PinchableView extends ReactViewGroup implements OnTouchListener {
             clone = null;
         }
         setVisibility(View.VISIBLE);
+        setOnActive(false);
     }

     public void setMinimumZoomScale(float minimumZoomScale) {
@@ -204,4 +212,16 @@ public class PinchableView extends ReactViewGroup implements OnTouchListener {
     public void setMaximumZoomScale(float maximumZoomScale) {
         maxScale = maximumZoomScale;
     }
+
+    public void setOnActive(boolean active) {
+        if (mEventEmitter != null) {
+            WritableMap params = Arguments.createMap();
+            params.putBoolean("value", active);
+            mEventEmitter.receiveEvent(getId(), "onActive", params);
+        }
+    }
+
+    public void setEventEmitter(RCTEventEmitter eventEmitter) {
+        mEventEmitter = eventEmitter;
+    }
 }
diff --git a/node_modules/react-native-pinchable/android/src/main/java/com/oblador/pinchable/PinchableViewManager.java b/node_modules/react-native-pinchable/android/src/main/java/com/oblador/pinchable/PinchableViewManager.java
index 22457bb..7a7017f 100644
--- a/node_modules/react-native-pinchable/android/src/main/java/com/oblador/pinchable/PinchableViewManager.java
+++ b/node_modules/react-native-pinchable/android/src/main/java/com/oblador/pinchable/PinchableViewManager.java
@@ -6,8 +6,13 @@ import com.facebook.react.uimanager.ViewGroupManager;
 import com.facebook.react.uimanager.ThemedReactContext;
 import com.facebook.react.uimanager.annotations.ReactProp;
 import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.uimanager.events.RCTEventEmitter;
+import com.facebook.react.common.MapBuilder;
+
+import java.util.Map;

 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;

 public class PinchableViewManager extends ViewGroupManager<PinchableView> {
     private static final String REACT_CLASS = "PinchableView";
@@ -28,7 +33,9 @@ public class PinchableViewManager extends ViewGroupManager<PinchableView> {

     @Override
     public @Nonnull PinchableView createViewInstance(@Nonnull ThemedReactContext ctx) {
-        return new PinchableView(ctx);
+        PinchableView pinchableView = new PinchableView(ctx);
+        pinchableView.setEventEmitter(ctx.getJSModule(RCTEventEmitter.class));
+        return pinchableView;
     }

     @ReactProp(name = "minimumZoomScale", defaultFloat = defaultMinimumZoomScale)
@@ -40,4 +47,13 @@ public class PinchableViewManager extends ViewGroupManager<PinchableView> {
     public void setMaximumZoomScale(PinchableView view, float maximumZoomScale) {
         view.setMaximumZoomScale(maximumZoomScale);
     }
+
+    @Override
+    public @Nullable
+    Map getExportedCustomDirectEventTypeConstants() {
+        return MapBuilder.of(
+                "onActive",
+                MapBuilder.of("registrationName", "onActive")
+        );
+    }
 }
diff --git a/node_modules/react-native-pinchable/index.js b/node_modules/react-native-pinchable/index.js
index 2dea3c3..12f2413 100755
--- a/node_modules/react-native-pinchable/index.js
+++ b/node_modules/react-native-pinchable/index.js
@@ -1,3 +1,20 @@
+import React, {Component} from "react";
 import { requireNativeComponent } from 'react-native';
+import PropTypes from 'prop-types';

-export default requireNativeComponent('PinchableView');
+class PinchableView extends Component {
+  static propTypes = {
+    onActive: PropTypes.func,
+    // other props...
+  };
+
+  render() {
+    return <PinchableView {...this.props} />;
+  }
+}
+
+const PinchableViewNative = requireNativeComponent('PinchableView', PinchableView, {
+  nativeOnly: { onActive: true },
+});
+
+export default PinchableViewNative;
diff --git a/node_modules/react-native-pinchable/ios/RNPinchableView.h b/node_modules/react-native-pinchable/ios/RNPinchableView.h
index 6ae6599..5ca103f 100644
--- a/node_modules/react-native-pinchable/ios/RNPinchableView.h
+++ b/node_modules/react-native-pinchable/ios/RNPinchableView.h
@@ -15,6 +15,9 @@ NS_ASSUME_NONNULL_BEGIN

 @property (nonatomic) CGFloat minimumZoomScale;
 @property (nonatomic) CGFloat maximumZoomScale;
+@property (nonatomic, copy) RCTBubblingEventBlock onActive;
+
+- (void)onActive:(BOOL)isActive;

 @end

diff --git a/node_modules/react-native-pinchable/ios/RNPinchableView.m b/node_modules/react-native-pinchable/ios/RNPinchableView.m
index 84429f3..c59bbd8 100644
--- a/node_modules/react-native-pinchable/ios/RNPinchableView.m
+++ b/node_modules/react-native-pinchable/ios/RNPinchableView.m
@@ -40,6 +40,8 @@ UIView *backgroundView;
   initialTouchPoint = CGPointZero;
   lastTouchPoint = CGPointZero;
   backgroundView = nil;
+  [self onActive:NO];
+
 }

 - (void)setupGesture
@@ -74,6 +76,7 @@ UIView *backgroundView;
     isActive = YES;
     initialSuperView = view.superview;
     initialIndex = [initialSuperView.subviews indexOfObject:view];
+    [self onActive:YES];

     CGPoint center = [gestureRecognizer locationInView:view];
     CGPoint absoluteOrigin = [view.superview convertPoint:view.frame.origin toView:window];
@@ -130,4 +133,18 @@ UIView *backgroundView;
   }
 }

+- (void)onActive:(BOOL)isActive {
+    // Implement your onActive logic here with the boolean parameter
+    NSLog(@"ETCView is active: %@", isActive ? @"YES" : @"NO");
+    // You can also emit events or perform other actions as needed.
+
+    if (!self.onActive) {
+        return;
+      }
+
+    self.onActive(@{
+        @"value": @(isActive)
+    });
+}
+
 @end
diff --git a/node_modules/react-native-pinchable/ios/RNPinchableViewManager.m b/node_modules/react-native-pinchable/ios/RNPinchableViewManager.m
index 06764d3..52e8770 100644
--- a/node_modules/react-native-pinchable/ios/RNPinchableViewManager.m
+++ b/node_modules/react-native-pinchable/ios/RNPinchableViewManager.m
@@ -8,6 +8,7 @@

 #import "RNPinchableViewManager.h"
 #import "RNPinchableView.h"
+#import <React/RCTUIManager.h>

 @implementation RNPinchableViewManager

@@ -20,5 +21,6 @@ RCT_EXPORT_MODULE(PinchableView)

 RCT_EXPORT_VIEW_PROPERTY(minimumZoomScale, CGFloat);
 RCT_EXPORT_VIEW_PROPERTY(maximumZoomScale, CGFloat);
+RCT_EXPORT_VIEW_PROPERTY(onActive, RCTBubblingEventBlock)

 @end

usage <Pinchable onActive={x => setIsPinching(x.nativeEvent.value)}>

jordiup commented 4 months ago

This should also fix the issue describe here https://github.com/oblador/react-native-pinchable/issues/17

jordiup commented 4 months ago

@oblador I imagine you're insanely busy, this would be an awesome addition/change to merge in if you find a chance 🙏

Thank you for the great package