diff --git a/native/components/full-screen-view-modal.react.js b/native/components/full-screen-view-modal.react.js
--- a/native/components/full-screen-view-modal.react.js
+++ b/native/components/full-screen-view-modal.react.js
@@ -21,7 +21,7 @@
   Gesture,
 } from 'react-native-gesture-handler';
 import Orientation from 'react-native-orientation-locker';
-import Animated from 'react-native-reanimated';
+import Animated, { useSharedValue } from 'react-native-reanimated';
 import type { EventResult } from 'react-native-reanimated';
 import { SafeAreaView } from 'react-native-safe-area-context';
 
@@ -67,7 +67,6 @@
   eq,
   neq,
   greaterThan,
-  lessThan,
   add,
   sub,
   multiply,
@@ -144,6 +143,13 @@
   NativeMethods,
 >;
 
+type ButtonDimensions = {
+  +x: number,
+  +y: number,
+  +width: number,
+  +height: number,
+};
+
 type BaseProps = {
   +navigation:
     | AppNavigationProp<'ImageModal'>
@@ -168,20 +174,14 @@
   +updateCloseButtonEnabled: ([number]) => void,
   +updateActionLinksEnabled: ([number]) => void,
   +gesture: ExclusiveGesture,
+  +closeButtonRef: { current: ?React.ElementRef<TouchableOpacityInstance> },
+  +mediaIconsRef: { current: ?React.ElementRef<typeof View> },
+  +onCloseButtonLayout: () => void,
+  +onMediaIconsLayout: () => void,
 };
 
 class FullScreenViewModal extends React.PureComponent<Props> {
-  closeButton: ?React.ElementRef<TouchableOpacityInstance>;
-  mediaIconsContainer: ?React.ElementRef<typeof View>;
-  closeButtonX: Value = new Value(-1);
-  closeButtonY: Value = new Value(-1);
-  closeButtonWidth: Value = new Value(0);
-  closeButtonHeight: Value = new Value(0);
   closeButtonLastState: Value = new Value(1);
-  mediaIconsX: Value = new Value(-1);
-  mediaIconsY: Value = new Value(-1);
-  mediaIconsWidth: Value = new Value(0);
-  mediaIconsHeight: Value = new Value(0);
   actionLinksLastState: Value = new Value(1);
 
   centerX: Value;
@@ -282,10 +282,12 @@
       cond(
         and(
           gestureJustStarted(panState),
-          this.outsideButtons(
-            sub(panAbsoluteX, panTranslationX),
-            sub(panAbsoluteY, panTranslationY),
-          ),
+          // TODO: migrate this in the next diffs
+          // this.outsideButtons(
+          //   sub(panAbsoluteX, panTranslationX),
+          //   sub(panAbsoluteY, panTranslationY),
+          // ),
+          1,
         ),
         set(curPanActive, 1),
       ),
@@ -532,37 +534,6 @@
     );
   }
 
-  outsideButtons(x: Node, y: Node): Node {
-    const {
-      closeButtonX,
-      closeButtonY,
-      closeButtonWidth,
-      closeButtonHeight,
-      closeButtonLastState,
-      mediaIconsX,
-      mediaIconsY,
-      mediaIconsWidth,
-      mediaIconsHeight,
-      actionLinksLastState,
-    } = this;
-    return and(
-      or(
-        eq(closeButtonLastState, 0),
-        lessThan(x, closeButtonX),
-        greaterThan(x, add(closeButtonX, closeButtonWidth)),
-        lessThan(y, closeButtonY),
-        greaterThan(y, add(closeButtonY, closeButtonHeight)),
-      ),
-      or(
-        eq(actionLinksLastState, 0),
-        lessThan(x, mediaIconsX),
-        greaterThan(x, add(mediaIconsX, mediaIconsWidth)),
-        lessThan(y, mediaIconsY),
-        greaterThan(y, add(mediaIconsY, mediaIconsHeight)),
-      ),
-    );
-  }
-
   panUpdate(
     // Inputs
     panActive: Node,
@@ -594,7 +565,9 @@
     const lastTapY = new Value(0);
     const fingerJustReleased = and(
       gestureJustEnded(singleTapState),
-      this.outsideButtons(lastTapX, lastTapY),
+      // TODO: migrate this in the next diffs
+      //this.outsideButtons(lastTapX, lastTapY),
+      1,
     );
 
     const wasZoomed = new Value(0);
@@ -718,7 +691,9 @@
 
     const fingerJustReleased = and(
       gestureJustEnded(doubleTapState),
-      this.outsideButtons(doubleTapX, doubleTapY),
+      // TODO: migrate this in the next diffs
+      // this.outsideButtons(doubleTapX, doubleTapY),
+      1,
     );
 
     return cond(
@@ -1024,8 +999,8 @@
         >
           <View
             style={styles.mediaIconsRow}
-            onLayout={this.onMediaIconsLayout}
-            ref={this.mediaIconsRef}
+            onLayout={this.props.onMediaIconsLayout}
+            ref={this.props.mediaIconsRef}
           >
             {saveButton}
             {copyButton}
@@ -1051,8 +1026,8 @@
               <TouchableOpacity
                 onPress={this.close}
                 disabled={!this.props.closeButtonEnabled}
-                onLayout={this.onCloseButtonLayout}
-                ref={this.closeButtonRef}
+                onLayout={this.props.onCloseButtonLayout}
+                ref={this.props.closeButtonRef}
               >
                 <Text style={styles.closeButton}>×</Text>
               </TouchableOpacity>
@@ -1070,43 +1045,6 @@
   close = () => {
     this.props.navigation.goBackOnce();
   };
-
-  closeButtonRef = (
-    closeButton: ?React.ElementRef<typeof TouchableOpacity>,
-  ) => {
-    this.closeButton = (closeButton: any);
-  };
-
-  mediaIconsRef = (mediaIconsContainer: ?React.ElementRef<typeof View>) => {
-    this.mediaIconsContainer = mediaIconsContainer;
-  };
-
-  onCloseButtonLayout = () => {
-    const { closeButton } = this;
-    if (!closeButton) {
-      return;
-    }
-    closeButton.measure((x, y, width, height, pageX, pageY) => {
-      this.closeButtonX.setValue(pageX);
-      this.closeButtonY.setValue(pageY);
-      this.closeButtonWidth.setValue(width);
-      this.closeButtonHeight.setValue(height);
-    });
-  };
-
-  onMediaIconsLayout = () => {
-    const { mediaIconsContainer } = this;
-    if (!mediaIconsContainer) {
-      return;
-    }
-
-    mediaIconsContainer.measure((x, y, width, height, pageX, pageY) => {
-      this.mediaIconsX.setValue(pageX);
-      this.mediaIconsY.setValue(pageY);
-      this.mediaIconsWidth.setValue(width);
-      this.mediaIconsHeight.setValue(height);
-    });
-  };
 }
 
 const styles = StyleSheet.create({
@@ -1228,6 +1166,80 @@
       [actionLinksEnabled],
     );
 
+    const closeButtonRef =
+      React.useRef<?React.ElementRef<TouchableOpacityInstance>>();
+    const mediaIconsRef = React.useRef<?React.ElementRef<typeof View>>();
+
+    const closeButtonDimensions = useSharedValue({
+      x: -1,
+      y: -1,
+      width: 0,
+      height: 0,
+    });
+
+    const mediaIconsDimensions = useSharedValue({
+      x: -1,
+      y: -1,
+      width: 0,
+      height: 0,
+    });
+
+    const closeButtonLastState = useSharedValue<boolean>(true);
+    const actionLinksLastState = useSharedValue<boolean>(true);
+
+    const onCloseButtonLayout = React.useCallback(() => {
+      const closeButton = closeButtonRef.current;
+      if (!closeButton) {
+        return;
+      }
+      closeButton.measure((x, y, width, height, pageX, pageY) => {
+        closeButtonDimensions.value = { x: pageX, y: pageY, width, height };
+      });
+    }, [closeButtonDimensions]);
+
+    const onMediaIconsLayout = React.useCallback(() => {
+      const mediaIconsContainer = mediaIconsRef.current;
+      if (!mediaIconsContainer) {
+        return;
+      }
+
+      mediaIconsContainer.measure((x, y, width, height, pageX, pageY) => {
+        mediaIconsDimensions.value = { x: pageX, y: pageY, width, height };
+      });
+    }, [mediaIconsDimensions]);
+
+    // TODO: use this in the next diffs
+    // eslint-disable-next-line no-unused-vars
+    const outsideButtons = React.useCallback(
+      (x: number, y: number): boolean => {
+        'worklet';
+        const isOutsideButton = (dim: ButtonDimensions) => {
+          return (
+            x < dim.x ||
+            x > dim.x + dim.width ||
+            y < dim.y ||
+            y > dim.y + dim.height
+          );
+        };
+
+        const isOutsideCloseButton = isOutsideButton(
+          closeButtonDimensions.value,
+        );
+        const isOutsideMediaIcons = isOutsideButton(mediaIconsDimensions.value);
+
+        return (
+          (closeButtonLastState.value === false || isOutsideCloseButton) &&
+          (actionLinksLastState.value === false || isOutsideMediaIcons)
+        );
+      },
+      [
+        actionLinksLastState,
+        closeButtonDimensions,
+        closeButtonLastState,
+        mediaIconsDimensions,
+      ],
+    );
+
     const gesture = React.useMemo(() => {
       const pinchGesture = Gesture.Pinch();
       const panGesture = Gesture.Pan().averageTouches(true);
@@ -1252,6 +1264,10 @@
         updateCloseButtonEnabled={updateCloseButtonEnabled}
         updateActionLinksEnabled={updateActionLinksEnabled}
         gesture={gesture}
+        closeButtonRef={closeButtonRef}
+        mediaIconsRef={mediaIconsRef}
+        onCloseButtonLayout={onCloseButtonLayout}
+        onMediaIconsLayout={onMediaIconsLayout}
       />
     );
   });