From f45e662116e39b4794aee0c4739339491c2916ca Mon Sep 17 00:00:00 2001 From: someone-here Date: Wed, 10 Jan 2024 20:03:26 +0530 Subject: [PATCH 01/15] [TS migration] AvatarCropModal --- ...AvatarCropModal.js => AvatarCropModal.tsx} | 99 +++++++++---------- .../{ImageCropView.js => ImageCropView.tsx} | 66 +++++++------ .../AvatarCropModal/{Slider.js => Slider.tsx} | 40 ++++---- .../gestureHandlerPropTypes.js | 21 ---- src/components/Button/index.tsx | 2 +- .../Pressable/GenericPressable/types.ts | 2 +- .../Pressable/PressableWithDelayToggle.tsx | 2 +- .../Pressable/PressableWithoutFocus.tsx | 2 +- src/libs/ControlSelection/index.native.ts | 2 +- src/libs/ControlSelection/index.ts | 15 ++- src/libs/ControlSelection/types.ts | 8 +- src/types/utils/CustomRefObject.ts | 5 - 12 files changed, 114 insertions(+), 150 deletions(-) rename src/components/AvatarCropModal/{AvatarCropModal.js => AvatarCropModal.tsx} (87%) rename src/components/AvatarCropModal/{ImageCropView.js => ImageCropView.tsx} (68%) rename src/components/AvatarCropModal/{Slider.js => Slider.tsx} (69%) delete mode 100644 src/components/AvatarCropModal/gestureHandlerPropTypes.js delete mode 100644 src/types/utils/CustomRefObject.ts diff --git a/src/components/AvatarCropModal/AvatarCropModal.js b/src/components/AvatarCropModal/AvatarCropModal.tsx similarity index 87% rename from src/components/AvatarCropModal/AvatarCropModal.js rename to src/components/AvatarCropModal/AvatarCropModal.tsx index eb3e21c3ad9d..2a9174c6d7a3 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.js +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -1,6 +1,5 @@ -import PropTypes from 'prop-types'; import React, {useCallback, useEffect, useState} from 'react'; -import {ActivityIndicator, Image, View} from 'react-native'; +import {ActivityIndicator, Image, LayoutChangeEvent, View} from 'react-native'; import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {interpolate, runOnUI, useAnimatedGestureHandler, useSharedValue, useWorkletCallback} from 'react-native-reanimated'; import Button from '@components/Button'; @@ -8,71 +7,62 @@ import HeaderGap from '@components/HeaderGap'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; -import sourcePropTypes from '@components/Image/sourcePropTypes'; import Modal from '@components/Modal'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; -import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; +import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import cropOrRotateImage from '@libs/cropOrRotateImage'; +import {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; import CONST from '@src/CONST'; +import IconAsset from '@src/types/utils/IconAsset'; import ImageCropView from './ImageCropView'; import Slider from './Slider'; -const propTypes = { +type AvatarCropModalProps = { /** Link to image for cropping */ - imageUri: PropTypes.string, + imageUri: string; /** Name of the image */ - imageName: PropTypes.string, + imageName: string; /** Type of the image file */ - imageType: PropTypes.string, + imageType: string; /** Callback to be called when user closes the modal */ - onClose: PropTypes.func, + onClose: () => void; /** Callback to be called when user saves the image */ - onSave: PropTypes.func, + onSave: (image: File | CustomRNImageManipulatorResult) => void; /** Modal visibility */ - isVisible: PropTypes.bool.isRequired, + isVisible: boolean; /** Image crop vector mask */ - maskImage: sourcePropTypes, - - ...withLocalizePropTypes, - ...windowDimensionsPropTypes, -}; - -const defaultProps = { - imageUri: '', - imageName: '', - imageType: '', - onClose: () => {}, - onSave: () => {}, - maskImage: undefined, + maskImage?: IconAsset; }; // This component can't be written using class since reanimated API uses hooks. -function AvatarCropModal(props) { +function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose = () => {}, onSave = () => {}, ...props}: AvatarCropModalProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); - const originalImageWidth = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); - const originalImageHeight = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); + const originalImageWidth = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); + const originalImageHeight = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); const translateY = useSharedValue(0); const translateX = useSharedValue(0); - const scale = useSharedValue(CONST.AVATAR_CROP_MODAL.MIN_SCALE); + const scale = useSharedValue(CONST.AVATAR_CROP_MODAL.MIN_SCALE); const rotation = useSharedValue(0); const translateSlider = useSharedValue(0); const isPressableEnabled = useSharedValue(true); + const {translate} = useLocalize(); + const {isSmallScreenWidth} = useWindowDimensions(); // Check if image cropping, saving or uploading is in progress const isLoading = useSharedValue(false); @@ -82,13 +72,13 @@ function AvatarCropModal(props) { const prevMaxOffsetX = useSharedValue(0); const prevMaxOffsetY = useSharedValue(0); - const [imageContainerSize, setImageContainerSize] = useState(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); - const [sliderContainerSize, setSliderContainerSize] = useState(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); + const [imageContainerSize, setImageContainerSize] = useState(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); + const [sliderContainerSize, setSliderContainerSize] = useState(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); const [isImageContainerInitialized, setIsImageContainerInitialized] = useState(false); const [isImageInitialized, setIsImageInitialized] = useState(false); // An onLayout callback, that initializes the image container, for proper render of an image - const initializeImageContainer = useCallback((event) => { + const initializeImageContainer = useCallback((event: LayoutChangeEvent) => { setIsImageContainerInitialized(true); const {height, width} = event.nativeEvent.layout; @@ -98,7 +88,7 @@ function AvatarCropModal(props) { }, []); // An onLayout callback, that initializes the slider container size, for proper render of a slider - const initializeSliderContainer = useCallback((event) => { + const initializeSliderContainer = useCallback((event: LayoutChangeEvent) => { setSliderContainerSize(event.nativeEvent.layout.width); }, []); @@ -122,7 +112,6 @@ function AvatarCropModal(props) { // In order to calculate proper image position/size/animation, we have to know its size. // And we have to update image size if image url changes. - const imageUri = props.imageUri; useEffect(() => { if (!imageUri) { return; @@ -148,7 +137,7 @@ function AvatarCropModal(props) { * @param {Array} minMax * @returns {Number} */ - const clamp = useWorkletCallback((value, [min, max]) => interpolate(value, [min, max], [min, max], 'clamp'), []); + const clamp = useWorkletCallback((value: number, [min, max]) => interpolate(value, [min, max], [min, max], 'clamp'), []); /** * Returns current image size taking into account scale and rotation. @@ -177,7 +166,7 @@ function AvatarCropModal(props) { * @param {Number} newY */ const updateImageOffset = useWorkletCallback( - (offsetX, offsetY) => { + (offsetX: number, offsetY: number) => { const {height, width} = getDisplayedImageSize(); const maxOffsetX = (width - imageContainerSize) / 2; const maxOffsetY = (height - imageContainerSize) / 2; @@ -194,7 +183,7 @@ function AvatarCropModal(props) { * @param {Number} containerSize * @returns {Number} */ - const newScaleValue = useWorkletCallback((newSliderValue, containerSize) => { + const newScaleValue = useWorkletCallback((newSliderValue: number, containerSize: number) => { const {MAX_SCALE, MIN_SCALE} = CONST.AVATAR_CROP_MODAL; return (newSliderValue / containerSize) * (MAX_SCALE - MIN_SCALE) + MIN_SCALE; }); @@ -323,14 +312,14 @@ function AvatarCropModal(props) { // Svg images are converted to a png blob to preserve transparency, so we need to update the // image name and type accordingly. - const isSvg = props.imageType.includes('image/svg'); - const imageName = isSvg ? 'fileName.png' : props.imageName; - const imageType = isSvg ? 'image/png' : props.imageType; + const isSvg = imageType.includes('image/svg'); + const imgName = isSvg ? 'fileName.png' : imageName; + const imgType = isSvg ? 'image/png' : imageType; - cropOrRotateImage(props.imageUri, [{rotate: rotation.value % 360}, {crop}], {compress: 1, name: imageName, type: imageType}) + cropOrRotateImage(imageUri, [{rotate: rotation.value % 360}, {crop}], {compress: 1, name: imgName, type: imgType}) .then((newImage) => { - props.onClose(); - props.onSave(newImage); + onClose(); + onSave(newImage); }) .catch(() => { isLoading.value = false; @@ -340,7 +329,7 @@ function AvatarCropModal(props) { /** * @param {Number} locationX */ - const sliderOnPress = (locationX) => { + const sliderOnPress = (locationX: number) => { // We are using the worklet directive here and running on the UI thread to ensure the Reanimated // shared values are updated synchronously, as they update asynchronously on the JS thread. @@ -361,7 +350,7 @@ function AvatarCropModal(props) { return ( - {props.isSmallScreenWidth && } + {isSmallScreenWidth && } - {props.translate('avatarCropModal.description')} + {translate('avatarCropModal.description')} runOnUI(sliderOnPress)(e.nativeEvent.locationX)} + accessible={false} accessibilityLabel="slider" role={CONST.ROLE.SLIDER} > @@ -422,7 +412,7 @@ function AvatarCropModal(props) { /> @@ -444,7 +434,7 @@ function AvatarCropModal(props) { style={[styles.m5]} onPress={cropAndSaveImage} pressOnEnter - text={props.translate('common.save')} + text={translate('common.save')} /> @@ -452,6 +442,5 @@ function AvatarCropModal(props) { } AvatarCropModal.displayName = 'AvatarCropModal'; -AvatarCropModal.propTypes = propTypes; -AvatarCropModal.defaultProps = defaultProps; -export default compose(withWindowDimensions, withLocalize)(AvatarCropModal); + +export default AvatarCropModal; diff --git a/src/components/AvatarCropModal/ImageCropView.js b/src/components/AvatarCropModal/ImageCropView.tsx similarity index 68% rename from src/components/AvatarCropModal/ImageCropView.js rename to src/components/AvatarCropModal/ImageCropView.tsx index 92cbe3a4da04..0f17fb6ba5b3 100644 --- a/src/components/AvatarCropModal/ImageCropView.js +++ b/src/components/AvatarCropModal/ImageCropView.tsx @@ -1,7 +1,7 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import {PanGestureHandler} from 'react-native-gesture-handler'; +import type {GestureEvent, PanGestureHandlerEventPayload} from 'react-native-gesture-handler'; import Animated, {interpolate, useAnimatedStyle} from 'react-native-reanimated'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -9,52 +9,58 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import ControlSelection from '@libs/ControlSelection'; -import gestureHandlerPropTypes from './gestureHandlerPropTypes'; +import {SelectionElement} from '@libs/ControlSelection/types'; +import type IconAsset from '@src/types/utils/IconAsset'; -const propTypes = { +type ImageCropViewProps = { /** Link to image for cropping */ - imageUri: PropTypes.string, + imageUri: string; /** Size of the image container that will be rendered */ - containerSize: PropTypes.number, + containerSize: number; /** The height of the selected image */ - originalImageHeight: PropTypes.shape({value: PropTypes.number}).isRequired, + originalImageHeight: { + value: number; + }; /** The width of the selected image */ - originalImageWidth: PropTypes.shape({value: PropTypes.number}).isRequired, + originalImageWidth: { + value: number; + }; /** The rotation value of the selected image */ - rotation: PropTypes.shape({value: PropTypes.number}).isRequired, + rotation: { + value: number; + }; /** The relative image shift along X-axis */ - translateX: PropTypes.shape({value: PropTypes.number}).isRequired, + translateX: { + value: number; + }; /** The relative image shift along Y-axis */ - translateY: PropTypes.shape({value: PropTypes.number}).isRequired, + translateY: { + value: number; + }; /** The scale factor of the image */ - scale: PropTypes.shape({value: PropTypes.number}).isRequired, + scale: { + value: number; + }; /** React-native-reanimated lib handler which executes when the user is panning image */ - panGestureEventHandler: gestureHandlerPropTypes, + panGestureEventHandler: (event: GestureEvent) => void; /** Image crop vector mask */ - maskImage: PropTypes.func, + maskImage?: IconAsset; }; -const defaultProps = { - imageUri: '', - containerSize: 0, - panGestureEventHandler: () => {}, - maskImage: Expensicons.ImageCropCircleMask, -}; - -function ImageCropView(props) { +function ImageCropView({imageUri = '', containerSize = 0, panGestureEventHandler = () => {}, maskImage = Expensicons.ImageCropCircleMask, ...props}: ImageCropViewProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); - const containerStyle = StyleUtils.getWidthAndHeightStyle(props.containerSize, props.containerSize); + const containerStyle = StyleUtils.getWidthAndHeightStyle(containerSize, containerSize); const originalImageHeight = props.originalImageHeight; const originalImageWidth = props.originalImageWidth; @@ -77,22 +83,24 @@ function ImageCropView(props) { // We're preventing text selection with ControlSelection.blockElement to prevent safari // default behaviour of cursor - I-beam cursor on drag. See https://github.com/Expensify/App/issues/13688 return ( - + { + ControlSelection.blockElement(el as SelectionElement); + }} style={[containerStyle, styles.imageCropContainer]} > @@ -101,8 +109,6 @@ function ImageCropView(props) { } ImageCropView.displayName = 'ImageCropView'; -ImageCropView.propTypes = propTypes; -ImageCropView.defaultProps = defaultProps; // React.memo is needed here to prevent styles recompilation // which sometimes may cause glitches during rerender of the modal diff --git a/src/components/AvatarCropModal/Slider.js b/src/components/AvatarCropModal/Slider.tsx similarity index 69% rename from src/components/AvatarCropModal/Slider.js rename to src/components/AvatarCropModal/Slider.tsx index ba2e1471ce9e..841b8d5bd473 100644 --- a/src/components/AvatarCropModal/Slider.js +++ b/src/components/AvatarCropModal/Slider.tsx @@ -1,34 +1,29 @@ -import PropTypes from 'prop-types'; -import React, {useState} from 'react'; +import React, {useRef, useState} from 'react'; import {View} from 'react-native'; import {PanGestureHandler} from 'react-native-gesture-handler'; +import type {GestureEvent, PanGestureHandlerEventPayload} from 'react-native-gesture-handler'; import Animated, {useAnimatedStyle} from 'react-native-reanimated'; import Tooltip from '@components/Tooltip'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import ControlSelection from '@libs/ControlSelection'; -import gestureHandlerPropTypes from './gestureHandlerPropTypes'; +import {SelectionElement} from '@libs/ControlSelection/types'; -const propTypes = { +type SliderProps = { /** React-native-reanimated lib handler which executes when the user is panning slider */ - onGesture: gestureHandlerPropTypes, + onGesture: (event: GestureEvent) => void; /** X position of the slider knob */ - sliderValue: PropTypes.shape({value: PropTypes.number}), - - ...withLocalizePropTypes, -}; - -const defaultProps = { - onGesture: () => {}, - sliderValue: {}, + sliderValue: { + value: number; + }; }; // This component can't be written using class since reanimated API uses hooks. -function Slider(props) { +function Slider({onGesture = () => {}, sliderValue = {value: 0}}: SliderProps) { const styles = useThemeStyles(); - const sliderValue = props.sliderValue; const [tooltipIsVisible, setTooltipIsVisible] = useState(true); + const {translate} = useLocalize(); // A reanimated memoized style, which tracks // a translateX shared value and updates the slider position. @@ -40,18 +35,20 @@ function Slider(props) { // default behaviour of cursor - I-beam cursor on drag. See https://github.com/Expensify/App/issues/13688 return ( { + ControlSelection.blockElement(el as SelectionElement); + }} style={styles.sliderBar} > setTooltipIsVisible(false)} onEnded={() => setTooltipIsVisible(true)} - onGestureEvent={props.onGesture} + onGestureEvent={onGesture} > {tooltipIsVisible && ( @@ -64,6 +61,5 @@ function Slider(props) { } Slider.displayName = 'Slider'; -Slider.propTypes = propTypes; -Slider.defaultProps = defaultProps; -export default withLocalize(Slider); + +export default Slider; diff --git a/src/components/AvatarCropModal/gestureHandlerPropTypes.js b/src/components/AvatarCropModal/gestureHandlerPropTypes.js deleted file mode 100644 index c473a162ba7e..000000000000 --- a/src/components/AvatarCropModal/gestureHandlerPropTypes.js +++ /dev/null @@ -1,21 +0,0 @@ -import PropTypes from 'prop-types'; - -export default PropTypes.oneOfType([ - // Executes once a gesture is triggered - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - // Array of event names that will be handled by animation handler - eventNames: PropTypes.arrayOf(PropTypes.string), - - // Array of registered event handlers ids - registrations: PropTypes.arrayOf(PropTypes.number), - - // React tag of the node we want to manage - viewTag: PropTypes.number, - - // Executes once a gesture is triggered - worklet: PropTypes.func, - }), - }), -]); diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index fb72f0cc845f..b422f512ca47 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -20,7 +20,7 @@ import validateSubmitShortcut from './validateSubmitShortcut'; type ButtonWithText = { /** The text for the button label */ - text: string; + text?: string; /** Boolean whether to display the right icon */ shouldShowRightIcon?: boolean; diff --git a/src/components/Pressable/GenericPressable/types.ts b/src/components/Pressable/GenericPressable/types.ts index dc04b6fcf329..2dd2e17e0454 100644 --- a/src/components/Pressable/GenericPressable/types.ts +++ b/src/components/Pressable/GenericPressable/types.ts @@ -40,7 +40,7 @@ type PressableProps = RNPressableProps & /** * onPress callback */ - onPress: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; + onPress?: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; /** * Specifies keyboard shortcut to trigger onPressHandler diff --git a/src/components/Pressable/PressableWithDelayToggle.tsx b/src/components/Pressable/PressableWithDelayToggle.tsx index ab1fa95efeb5..86f6c9d8aff8 100644 --- a/src/components/Pressable/PressableWithDelayToggle.tsx +++ b/src/components/Pressable/PressableWithDelayToggle.tsx @@ -78,7 +78,7 @@ function PressableWithDelayToggle( return; } temporarilyDisableInteractions(); - onPress(); + onPress?.(); }; // Due to limitations in RN regarding the vertical text alignment of non-Text elements, diff --git a/src/components/Pressable/PressableWithoutFocus.tsx b/src/components/Pressable/PressableWithoutFocus.tsx index f887b0ea9b7d..240ef4a9873a 100644 --- a/src/components/Pressable/PressableWithoutFocus.tsx +++ b/src/components/Pressable/PressableWithoutFocus.tsx @@ -15,7 +15,7 @@ function PressableWithoutFocus({children, onPress, onLongPress, ...rest}: Pressa const pressAndBlur = () => { ref?.current?.blur(); - onPress(); + onPress?.(); }; return ( diff --git a/src/libs/ControlSelection/index.native.ts b/src/libs/ControlSelection/index.native.ts index b45af6da6441..2bccea946cda 100644 --- a/src/libs/ControlSelection/index.native.ts +++ b/src/libs/ControlSelection/index.native.ts @@ -1,4 +1,4 @@ -import type ControlSelectionModule from './types'; +import type {ControlSelectionModule} from './types'; function block() {} function unblock() {} diff --git a/src/libs/ControlSelection/index.ts b/src/libs/ControlSelection/index.ts index ab11e66bc369..89f1e62aa6f6 100644 --- a/src/libs/ControlSelection/index.ts +++ b/src/libs/ControlSelection/index.ts @@ -1,5 +1,4 @@ -import type CustomRefObject from '@src/types/utils/CustomRefObject'; -import type ControlSelectionModule from './types'; +import type {ControlSelectionModule, SelectionElement} from './types'; /** * Block selection on the whole app @@ -20,25 +19,25 @@ function unblock() { /** * Block selection on particular element */ -function blockElement(ref?: CustomRefObject | null) { - if (!ref) { +function blockElement(element?: SelectionElement | null) { + if (!element) { return; } // eslint-disable-next-line no-param-reassign - ref.onselectstart = () => false; + element.onselectstart = () => false; } /** * Unblock selection on particular element */ -function unblockElement(ref?: CustomRefObject | null) { - if (!ref) { +function unblockElement(element?: SelectionElement | null) { + if (!element) { return; } // eslint-disable-next-line no-param-reassign - ref.onselectstart = () => true; + element.onselectstart = () => true; } const ControlSelection: ControlSelectionModule = { diff --git a/src/libs/ControlSelection/types.ts b/src/libs/ControlSelection/types.ts index fc0b488577ec..8433a366ed91 100644 --- a/src/libs/ControlSelection/types.ts +++ b/src/libs/ControlSelection/types.ts @@ -1,10 +1,10 @@ -import type CustomRefObject from '@src/types/utils/CustomRefObject'; +type SelectionElement = T & {onselectstart: () => boolean}; type ControlSelectionModule = { block: () => void; unblock: () => void; - blockElement: (ref?: CustomRefObject | null) => void; - unblockElement: (ref?: CustomRefObject | null) => void; + blockElement: (element?: SelectionElement | null) => void; + unblockElement: (element?: SelectionElement | null) => void; }; -export default ControlSelectionModule; +export type {ControlSelectionModule, SelectionElement}; diff --git a/src/types/utils/CustomRefObject.ts b/src/types/utils/CustomRefObject.ts deleted file mode 100644 index 13bb0f27a42e..000000000000 --- a/src/types/utils/CustomRefObject.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type {RefObject} from 'react'; - -type CustomRefObject = RefObject & {onselectstart: () => boolean}; - -export default CustomRefObject; From 83c42ab3a9d8ad20df68d90a8816b3bb9a5bda25 Mon Sep 17 00:00:00 2001 From: someone-here Date: Wed, 10 Jan 2024 20:25:29 +0530 Subject: [PATCH 02/15] Fix lint --- .../AvatarCropModal/AvatarCropModal.tsx | 38 ++++++++++++++----- .../AvatarCropModal/ImageCropView.tsx | 2 +- src/components/AvatarCropModal/Slider.tsx | 4 +- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index 2a9174c6d7a3..3f4b7d38451e 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -1,5 +1,6 @@ import React, {useCallback, useEffect, useState} from 'react'; -import {ActivityIndicator, Image, LayoutChangeEvent, View} from 'react-native'; +import {ActivityIndicator, Image, View} from 'react-native'; +import type {LayoutChangeEvent} from 'react-native'; import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {interpolate, runOnUI, useAnimatedGestureHandler, useSharedValue, useWorkletCallback} from 'react-native-reanimated'; import Button from '@components/Button'; @@ -17,11 +18,10 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import compose from '@libs/compose'; import cropOrRotateImage from '@libs/cropOrRotateImage'; -import {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; +import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; import CONST from '@src/CONST'; -import IconAsset from '@src/types/utils/IconAsset'; +import type IconAsset from '@src/types/utils/IconAsset'; import ImageCropView from './ImageCropView'; import Slider from './Slider'; @@ -48,6 +48,12 @@ type AvatarCropModalProps = { maskImage?: IconAsset; }; +type PanHandlerContextType = { + translateX: number; + translateY: number; + translateSliderX: number; +}; + // This component can't be written using class since reanimated API uses hooks. function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose = () => {}, onSave = () => {}, ...props}: AvatarCropModalProps) { const theme = useTheme(); @@ -194,7 +200,7 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose */ const panGestureEventHandler = useAnimatedGestureHandler( { - onStart: (_, context) => { + onStart: (a, context: PanHandlerContextType) => { // we have to assign translate values to a context // since that is required for proper work of turbo modules. // eslint-disable-next-line no-param-reassign @@ -242,7 +248,7 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose */ const panSliderGestureEventHandler = useAnimatedGestureHandler( { - onStart: (_, context) => { + onStart: (a, context: PanHandlerContextType) => { // we have to assign this value to a context // since that is required for proper work of turbo modules. // eslint-disable-next-line no-param-reassign @@ -324,11 +330,23 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose .catch(() => { isLoading.value = false; }); - }, [originalImageHeight.value, originalImageWidth.value, scale.value, translateX.value, imageContainerSize, translateY.value, props, rotation.value, isLoading]); + }, [ + imageName, + imageUri, + imageType, + onSave, + onClose, + originalImageHeight.value, + originalImageWidth.value, + scale.value, + translateX.value, + imageContainerSize, + translateY.value, + props, + rotation.value, + isLoading, + ]); - /** - * @param {Number} locationX - */ const sliderOnPress = (locationX: number) => { // We are using the worklet directive here and running on the UI thread to ensure the Reanimated // shared values are updated synchronously, as they update asynchronously on the JS thread. diff --git a/src/components/AvatarCropModal/ImageCropView.tsx b/src/components/AvatarCropModal/ImageCropView.tsx index 0f17fb6ba5b3..e76ffc2d1f10 100644 --- a/src/components/AvatarCropModal/ImageCropView.tsx +++ b/src/components/AvatarCropModal/ImageCropView.tsx @@ -9,7 +9,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import ControlSelection from '@libs/ControlSelection'; -import {SelectionElement} from '@libs/ControlSelection/types'; +import type {SelectionElement} from '@libs/ControlSelection/types'; import type IconAsset from '@src/types/utils/IconAsset'; type ImageCropViewProps = { diff --git a/src/components/AvatarCropModal/Slider.tsx b/src/components/AvatarCropModal/Slider.tsx index 841b8d5bd473..26e35517f48e 100644 --- a/src/components/AvatarCropModal/Slider.tsx +++ b/src/components/AvatarCropModal/Slider.tsx @@ -1,4 +1,4 @@ -import React, {useRef, useState} from 'react'; +import React, {useState} from 'react'; import {View} from 'react-native'; import {PanGestureHandler} from 'react-native-gesture-handler'; import type {GestureEvent, PanGestureHandlerEventPayload} from 'react-native-gesture-handler'; @@ -7,7 +7,7 @@ import Tooltip from '@components/Tooltip'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import ControlSelection from '@libs/ControlSelection'; -import {SelectionElement} from '@libs/ControlSelection/types'; +import type {SelectionElement} from '@libs/ControlSelection/types'; type SliderProps = { /** React-native-reanimated lib handler which executes when the user is panning slider */ From 3c222b345b5dba0a05c17e75aa91f9510761e087 Mon Sep 17 00:00:00 2001 From: someone-here Date: Wed, 10 Jan 2024 20:34:21 +0530 Subject: [PATCH 03/15] Fix lint --- src/components/AvatarCropModal/AvatarCropModal.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index 3f4b7d38451e..7c9313a6d394 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -342,7 +342,6 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose translateX.value, imageContainerSize, translateY.value, - props, rotation.value, isLoading, ]); From c4929bae75fa1b3211ab91a7f103536daa17c6da Mon Sep 17 00:00:00 2001 From: Esh Tanya Gupta <77237602+esh-g@users.noreply.github.com> Date: Sat, 13 Jan 2024 15:52:22 +0530 Subject: [PATCH 04/15] Update src/components/AvatarCropModal/AvatarCropModal.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Henriques --- src/components/AvatarCropModal/AvatarCropModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index 7c9313a6d394..ec8b87d9f232 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -27,7 +27,7 @@ import Slider from './Slider'; type AvatarCropModalProps = { /** Link to image for cropping */ - imageUri: string; + imageUri?: string; /** Name of the image */ imageName: string; From 5278e70cb628450776f0b8ec31dfe9761991bea5 Mon Sep 17 00:00:00 2001 From: Esh Tanya Gupta <77237602+esh-g@users.noreply.github.com> Date: Sat, 13 Jan 2024 15:52:33 +0530 Subject: [PATCH 05/15] Update src/components/AvatarCropModal/AvatarCropModal.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Henriques --- src/components/AvatarCropModal/AvatarCropModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index ec8b87d9f232..fa2e7fb6a770 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -30,7 +30,7 @@ type AvatarCropModalProps = { imageUri?: string; /** Name of the image */ - imageName: string; + imageName?: string; /** Type of the image file */ imageType: string; From 050e162046df43152186077aed05cb361725aa64 Mon Sep 17 00:00:00 2001 From: Esh Tanya Gupta <77237602+esh-g@users.noreply.github.com> Date: Sat, 13 Jan 2024 15:52:42 +0530 Subject: [PATCH 06/15] Update src/components/AvatarCropModal/AvatarCropModal.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Henriques --- src/components/AvatarCropModal/AvatarCropModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index fa2e7fb6a770..cf26c0e568f2 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -33,7 +33,7 @@ type AvatarCropModalProps = { imageName?: string; /** Type of the image file */ - imageType: string; + imageType?: string; /** Callback to be called when user closes the modal */ onClose: () => void; From 993d3f55882704b8e7e3dc2beb6c937ce28ab5ad Mon Sep 17 00:00:00 2001 From: Esh Tanya Gupta <77237602+esh-g@users.noreply.github.com> Date: Sat, 13 Jan 2024 15:52:53 +0530 Subject: [PATCH 07/15] Update src/components/AvatarCropModal/AvatarCropModal.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Henriques --- src/components/AvatarCropModal/AvatarCropModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index cf26c0e568f2..06aa8e673c4f 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -36,7 +36,7 @@ type AvatarCropModalProps = { imageType?: string; /** Callback to be called when user closes the modal */ - onClose: () => void; + onClose?: () => void; /** Callback to be called when user saves the image */ onSave: (image: File | CustomRNImageManipulatorResult) => void; From f10ab52c44707fed958b82e378d8ac40e7fa0e08 Mon Sep 17 00:00:00 2001 From: Esh Tanya Gupta <77237602+esh-g@users.noreply.github.com> Date: Sat, 13 Jan 2024 15:53:03 +0530 Subject: [PATCH 08/15] Update src/components/AvatarCropModal/AvatarCropModal.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Henriques --- src/components/AvatarCropModal/AvatarCropModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index 06aa8e673c4f..b5dc240f5fbf 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -39,7 +39,7 @@ type AvatarCropModalProps = { onClose?: () => void; /** Callback to be called when user saves the image */ - onSave: (image: File | CustomRNImageManipulatorResult) => void; + onSave?: (image: File | CustomRNImageManipulatorResult) => void; /** Modal visibility */ isVisible: boolean; From 4d3f0be78573d743dc3897354d77adca09e1167f Mon Sep 17 00:00:00 2001 From: Esh Tanya Gupta <77237602+esh-g@users.noreply.github.com> Date: Sat, 13 Jan 2024 15:57:18 +0530 Subject: [PATCH 09/15] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Henriques --- src/components/AvatarCropModal/AvatarCropModal.tsx | 6 ++++++ src/components/AvatarCropModal/ImageCropView.tsx | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index b5dc240f5fbf..ba8b0bc14590 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -143,6 +143,9 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose * @param {Array} minMax * @returns {Number} */ + /** + * Validates that value is within the provided mix/max range. + */ const clamp = useWorkletCallback((value: number, [min, max]) => interpolate(value, [min, max], [min, max], 'clamp'), []); /** @@ -171,6 +174,9 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose * @param {Number} newX * @param {Number} newY */ + /** + * Validates the offset to prevent overflow, and updates the image offset. + */ const updateImageOffset = useWorkletCallback( (offsetX: number, offsetY: number) => { const {height, width} = getDisplayedImageSize(); diff --git a/src/components/AvatarCropModal/ImageCropView.tsx b/src/components/AvatarCropModal/ImageCropView.tsx index e76ffc2d1f10..d6077cd9eb1c 100644 --- a/src/components/AvatarCropModal/ImageCropView.tsx +++ b/src/components/AvatarCropModal/ImageCropView.tsx @@ -14,10 +14,10 @@ import type IconAsset from '@src/types/utils/IconAsset'; type ImageCropViewProps = { /** Link to image for cropping */ - imageUri: string; + imageUri?: string; /** Size of the image container that will be rendered */ - containerSize: number; + containerSize?: number; /** The height of the selected image */ originalImageHeight: { @@ -50,7 +50,7 @@ type ImageCropViewProps = { }; /** React-native-reanimated lib handler which executes when the user is panning image */ - panGestureEventHandler: (event: GestureEvent) => void; + panGestureEventHandler?: (event: GestureEvent) => void; /** Image crop vector mask */ maskImage?: IconAsset; From 7f4e78fe41597a8b0fbc31601436490d82ac1559 Mon Sep 17 00:00:00 2001 From: someone-here Date: Sat, 13 Jan 2024 16:04:28 +0530 Subject: [PATCH 10/15] Remove JS-Doc comments --- .../AvatarCropModal/AvatarCropModal.tsx | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/components/AvatarCropModal/AvatarCropModal.tsx b/src/components/AvatarCropModal/AvatarCropModal.tsx index ba8b0bc14590..3190b9c75fc5 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.tsx +++ b/src/components/AvatarCropModal/AvatarCropModal.tsx @@ -136,13 +136,6 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose }); }, [imageUri, originalImageHeight, originalImageWidth, rotation, translateSlider]); - /** - * Validates that value is within the provided mix/max range. - * - * @param {Number} value - * @param {Array} minMax - * @returns {Number} - */ /** * Validates that value is within the provided mix/max range. */ @@ -150,8 +143,6 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose /** * Returns current image size taking into account scale and rotation. - * - * @returns {Object} */ const getDisplayedImageSize = useWorkletCallback(() => { let height = imageContainerSize * scale.value; @@ -168,12 +159,6 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose return {height, width}; }, [imageContainerSize, scale]); - /** - * Validates the offset to prevent overflow, and updates the image offset. - * - * @param {Number} newX - * @param {Number} newY - */ /** * Validates the offset to prevent overflow, and updates the image offset. */ @@ -190,11 +175,6 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose [imageContainerSize, scale, clamp], ); - /** - * @param {Number} newSliderValue - * @param {Number} containerSize - * @returns {Number} - */ const newScaleValue = useWorkletCallback((newSliderValue: number, containerSize: number) => { const {MAX_SCALE, MIN_SCALE} = CONST.AVATAR_CROP_MODAL; return (newSliderValue / containerSize) * (MAX_SCALE - MIN_SCALE) + MIN_SCALE; From 96d86459d4a5a99eea547c73a2e9dfdcb5360420 Mon Sep 17 00:00:00 2001 From: someone-here Date: Sat, 13 Jan 2024 16:19:35 +0530 Subject: [PATCH 11/15] Use shared value type --- .../AvatarCropModal/ImageCropView.tsx | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/components/AvatarCropModal/ImageCropView.tsx b/src/components/AvatarCropModal/ImageCropView.tsx index d6077cd9eb1c..f086697a3e24 100644 --- a/src/components/AvatarCropModal/ImageCropView.tsx +++ b/src/components/AvatarCropModal/ImageCropView.tsx @@ -3,6 +3,7 @@ import {View} from 'react-native'; import {PanGestureHandler} from 'react-native-gesture-handler'; import type {GestureEvent, PanGestureHandlerEventPayload} from 'react-native-gesture-handler'; import Animated, {interpolate, useAnimatedStyle} from 'react-native-reanimated'; +import type {SharedValue} from 'react-native-reanimated'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -20,34 +21,22 @@ type ImageCropViewProps = { containerSize?: number; /** The height of the selected image */ - originalImageHeight: { - value: number; - }; + originalImageHeight: SharedValue; /** The width of the selected image */ - originalImageWidth: { - value: number; - }; + originalImageWidth: SharedValue; /** The rotation value of the selected image */ - rotation: { - value: number; - }; + rotation: SharedValue; /** The relative image shift along X-axis */ - translateX: { - value: number; - }; + translateX: SharedValue; /** The relative image shift along Y-axis */ - translateY: { - value: number; - }; + translateY: SharedValue; /** The scale factor of the image */ - scale: { - value: number; - }; + scale: SharedValue; /** React-native-reanimated lib handler which executes when the user is panning image */ panGestureEventHandler?: (event: GestureEvent) => void; From e9a397960ca982ae30b5ca0d17442200e62f19b8 Mon Sep 17 00:00:00 2001 From: someone-here Date: Sat, 13 Jan 2024 16:26:59 +0530 Subject: [PATCH 12/15] Remove SelectionElement and use HTMLElement --- src/components/AvatarCropModal/ImageCropView.tsx | 3 +-- src/components/AvatarCropModal/Slider.tsx | 3 +-- src/libs/ControlSelection/index.ts | 6 +++--- src/libs/ControlSelection/types.ts | 8 +++----- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/components/AvatarCropModal/ImageCropView.tsx b/src/components/AvatarCropModal/ImageCropView.tsx index f086697a3e24..b45d7c63b088 100644 --- a/src/components/AvatarCropModal/ImageCropView.tsx +++ b/src/components/AvatarCropModal/ImageCropView.tsx @@ -10,7 +10,6 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import ControlSelection from '@libs/ControlSelection'; -import type {SelectionElement} from '@libs/ControlSelection/types'; import type IconAsset from '@src/types/utils/IconAsset'; type ImageCropViewProps = { @@ -75,7 +74,7 @@ function ImageCropView({imageUri = '', containerSize = 0, panGestureEventHandler { - ControlSelection.blockElement(el as SelectionElement); + ControlSelection.blockElement(el as HTMLElement | null); }} style={[containerStyle, styles.imageCropContainer]} > diff --git a/src/components/AvatarCropModal/Slider.tsx b/src/components/AvatarCropModal/Slider.tsx index 26e35517f48e..686255ac430a 100644 --- a/src/components/AvatarCropModal/Slider.tsx +++ b/src/components/AvatarCropModal/Slider.tsx @@ -7,7 +7,6 @@ import Tooltip from '@components/Tooltip'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import ControlSelection from '@libs/ControlSelection'; -import type {SelectionElement} from '@libs/ControlSelection/types'; type SliderProps = { /** React-native-reanimated lib handler which executes when the user is panning slider */ @@ -36,7 +35,7 @@ function Slider({onGesture = () => {}, sliderValue = {value: 0}}: SliderProps) { return ( { - ControlSelection.blockElement(el as SelectionElement); + ControlSelection.blockElement(el as HTMLElement | null); }} style={styles.sliderBar} > diff --git a/src/libs/ControlSelection/index.ts b/src/libs/ControlSelection/index.ts index 89f1e62aa6f6..61808cfbc1b5 100644 --- a/src/libs/ControlSelection/index.ts +++ b/src/libs/ControlSelection/index.ts @@ -1,4 +1,4 @@ -import type {ControlSelectionModule, SelectionElement} from './types'; +import type {ControlSelectionModule} from './types'; /** * Block selection on the whole app @@ -19,7 +19,7 @@ function unblock() { /** * Block selection on particular element */ -function blockElement(element?: SelectionElement | null) { +function blockElement(element?: HTMLElement | null) { if (!element) { return; } @@ -31,7 +31,7 @@ function blockElement(element?: SelectionElement | null) { /** * Unblock selection on particular element */ -function unblockElement(element?: SelectionElement | null) { +function unblockElement(element?: HTMLElement | null) { if (!element) { return; } diff --git a/src/libs/ControlSelection/types.ts b/src/libs/ControlSelection/types.ts index 8433a366ed91..b40e4d6f7a84 100644 --- a/src/libs/ControlSelection/types.ts +++ b/src/libs/ControlSelection/types.ts @@ -1,10 +1,8 @@ -type SelectionElement = T & {onselectstart: () => boolean}; - type ControlSelectionModule = { block: () => void; unblock: () => void; - blockElement: (element?: SelectionElement | null) => void; - unblockElement: (element?: SelectionElement | null) => void; + blockElement: (element?: HTMLElement | null) => void; + unblockElement: (element?: HTMLElement | null) => void; }; -export type {ControlSelectionModule, SelectionElement}; +export type {ControlSelectionModule}; From 2c25037fcb763a8f79694dd4fbfe82cf73ca6db2 Mon Sep 17 00:00:00 2001 From: someone-here Date: Sat, 13 Jan 2024 16:35:05 +0530 Subject: [PATCH 13/15] Use default export --- src/libs/ControlSelection/index.native.ts | 2 +- src/libs/ControlSelection/index.ts | 2 +- src/libs/ControlSelection/types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/ControlSelection/index.native.ts b/src/libs/ControlSelection/index.native.ts index 2bccea946cda..b45af6da6441 100644 --- a/src/libs/ControlSelection/index.native.ts +++ b/src/libs/ControlSelection/index.native.ts @@ -1,4 +1,4 @@ -import type {ControlSelectionModule} from './types'; +import type ControlSelectionModule from './types'; function block() {} function unblock() {} diff --git a/src/libs/ControlSelection/index.ts b/src/libs/ControlSelection/index.ts index 61808cfbc1b5..44787dc77dbe 100644 --- a/src/libs/ControlSelection/index.ts +++ b/src/libs/ControlSelection/index.ts @@ -1,4 +1,4 @@ -import type {ControlSelectionModule} from './types'; +import type ControlSelectionModule from './types'; /** * Block selection on the whole app diff --git a/src/libs/ControlSelection/types.ts b/src/libs/ControlSelection/types.ts index b40e4d6f7a84..c4ca4b713b9b 100644 --- a/src/libs/ControlSelection/types.ts +++ b/src/libs/ControlSelection/types.ts @@ -5,4 +5,4 @@ type ControlSelectionModule = { unblockElement: (element?: HTMLElement | null) => void; }; -export type {ControlSelectionModule}; +export default ControlSelectionModule; From 32e59df705bc16b4581dc6c554f1bc13b5cd3b87 Mon Sep 17 00:00:00 2001 From: someone-here Date: Sat, 13 Jan 2024 16:40:53 +0530 Subject: [PATCH 14/15] Match the optional props --- src/components/AvatarCropModal/Slider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AvatarCropModal/Slider.tsx b/src/components/AvatarCropModal/Slider.tsx index 686255ac430a..89b470be2cd3 100644 --- a/src/components/AvatarCropModal/Slider.tsx +++ b/src/components/AvatarCropModal/Slider.tsx @@ -10,10 +10,10 @@ import ControlSelection from '@libs/ControlSelection'; type SliderProps = { /** React-native-reanimated lib handler which executes when the user is panning slider */ - onGesture: (event: GestureEvent) => void; + onGesture?: (event: GestureEvent) => void; /** X position of the slider knob */ - sliderValue: { + sliderValue?: { value: number; }; }; From 4971adf81f2236b33ac4f05567a0c8dde9cc65a3 Mon Sep 17 00:00:00 2001 From: someone-here Date: Tue, 23 Jan 2024 21:58:49 +0530 Subject: [PATCH 15/15] Prettify --- src/components/AvatarCropModal/Slider.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/AvatarCropModal/Slider.tsx b/src/components/AvatarCropModal/Slider.tsx index f69fba776718..9a9da65befa0 100644 --- a/src/components/AvatarCropModal/Slider.tsx +++ b/src/components/AvatarCropModal/Slider.tsx @@ -10,7 +10,6 @@ import useThemeStyles from '@hooks/useThemeStyles'; import ControlSelection from '@libs/ControlSelection'; type SliderProps = { - /** React-native-reanimated lib handler which executes when the user is panning slider */ gestureCallbacks: { onBegin: () => void;