@@ -5,17 +5,44 @@ import {
55 TouchableOpacity ,
66 Dimensions ,
77} from 'react-native' ;
8- import React from 'react' ;
9- import Animated , {
10- useSharedValue ,
11- useAnimatedStyle ,
12- withSpring ,
13- } from 'react-native-reanimated' ;
14- import { Gesture , GestureDetector } from 'react-native-gesture-handler' ;
8+ import React , { useEffect } from 'react' ;
159import Icon from './Icon' ;
16-
10+ import NonFloatingButton from './NonFloatingButton' ;
1711const { width : screenWidth , height : screenHeight } = Dimensions . get ( 'window' ) ;
1812
13+ let Animated : any = null ;
14+ let Reanimated : any = null ;
15+ let useSharedValue : any = null ;
16+ let useAnimatedStyle : any = null ;
17+ let withSpring : any = null ;
18+ let Gesture : any = null ;
19+ let GestureDetector : any = null ;
20+
21+ let librariesAvailable = false ;
22+
23+ try {
24+ Animated = require ( 'react-native-reanimated' ) . default ;
25+ Reanimated = require ( 'react-native-reanimated' ) ;
26+ useSharedValue = Reanimated . useSharedValue ;
27+ useAnimatedStyle = Reanimated . useAnimatedStyle ;
28+ withSpring = Reanimated . withSpring ;
29+
30+ const gestureHandler = require ( 'react-native-gesture-handler' ) ;
31+ Gesture = gestureHandler . Gesture ;
32+ GestureDetector = gestureHandler . GestureDetector ;
33+
34+ librariesAvailable = ! ! (
35+ Animated &&
36+ useSharedValue &&
37+ useAnimatedStyle &&
38+ withSpring &&
39+ Gesture &&
40+ GestureDetector
41+ ) ;
42+ } catch ( error ) {
43+ librariesAvailable = false ;
44+ }
45+
1946const BUTTON_SIZE = 58 ;
2047const CLOSE_BUTTON_SIZE = 58 ;
2148const PADDING = 20 ;
@@ -24,21 +51,20 @@ interface FloatingButtonProps {
2451 openModal : ( ) => void ;
2552 hideIcon : ( ) => void ;
2653 logsLength : number ;
54+ draggable ?: boolean ;
2755 enableDeviceShake ?: boolean ;
2856}
2957
30- const FloatingButton : React . FunctionComponent < FloatingButtonProps > = ( {
58+ const AnimatedFloatingButton : React . FC < FloatingButtonProps > = ( {
3159 hideIcon,
32- logsLength,
3360 openModal,
61+ logsLength,
3462 enableDeviceShake,
3563} ) => {
3664 const positionX = useSharedValue ( screenWidth - BUTTON_SIZE - PADDING ) ;
3765 const positionY = useSharedValue ( screenHeight - 150 ) ;
38-
3966 const startPositionX = useSharedValue ( 0 ) ;
4067 const startPositionY = useSharedValue ( 0 ) ;
41-
4268 const isDragging = useSharedValue ( false ) ;
4369
4470 const panGesture = Gesture . Pan ( )
@@ -47,7 +73,7 @@ const FloatingButton: React.FunctionComponent<FloatingButtonProps> = ({
4773 startPositionX . value = positionX . value ;
4874 startPositionY . value = positionY . value ;
4975 } )
50- . onUpdate ( ( event ) => {
76+ . onUpdate ( ( event : { translationX : any ; translationY : any } ) => {
5177 const newX = startPositionX . value + event . translationX ;
5278 const newY = startPositionY . value + event . translationY ;
5379
@@ -111,6 +137,24 @@ const FloatingButton: React.FunctionComponent<FloatingButtonProps> = ({
111137 ) ;
112138} ;
113139
140+ const FloatingButton : React . FC < FloatingButtonProps > = ( props ) => {
141+ const { draggable } = props ;
142+
143+ useEffect ( ( ) => {
144+ if ( draggable && ! librariesAvailable ) {
145+ throw new Error (
146+ `Missing Libraries: Required libraries "react-native-reanimated" and "react-native-gesture-handler" are not installed. Please install them to enable this feature.\n\nRun:\n\nnpm install react-native-reanimated react-native-gesture-handler\n\nand rebuild your app.`
147+ ) ;
148+ }
149+ } , [ draggable ] ) ;
150+
151+ if ( ! librariesAvailable || ! draggable ) {
152+ return < NonFloatingButton { ...props } /> ;
153+ }
154+
155+ return < AnimatedFloatingButton { ...props } /> ;
156+ } ;
157+
114158const styles = StyleSheet . create ( {
115159 gestureRoot : {
116160 flex : 1 ,
@@ -134,6 +178,10 @@ const styles = StyleSheet.create({
134178 position : 'absolute' ,
135179 zIndex : 1000 ,
136180 } ,
181+ staticPosition : {
182+ left : screenWidth - BUTTON_SIZE - PADDING ,
183+ top : screenHeight - 150 ,
184+ } ,
137185 buttonTouchable : {
138186 backgroundColor : '#007AFF' ,
139187 padding : 16 ,
@@ -149,6 +197,10 @@ const styles = StyleSheet.create({
149197 position : 'absolute' ,
150198 zIndex : 1001 ,
151199 } ,
200+ staticClosePosition : {
201+ left : screenWidth - BUTTON_SIZE - PADDING + 4 ,
202+ top : screenHeight - 150 - 50 ,
203+ } ,
152204 closeButton : {
153205 padding : 16 ,
154206 borderRadius : 70 ,
0 commit comments