1
1
import { logger } from '@sentry/core' ;
2
2
import * as React from 'react' ;
3
- import { Animated , KeyboardAvoidingView , Modal , PanResponder , Platform } from 'react-native' ;
3
+ import { Animated , Dimensions , KeyboardAvoidingView , Modal , PanResponder , Platform } from 'react-native' ;
4
4
5
5
import { FeedbackWidget } from './FeedbackWidget' ;
6
6
import { modalBackground , modalSheetContainer , modalWrapper } from './FeedbackWidget.styles' ;
@@ -10,6 +10,8 @@ import { isModalSupported } from './utils';
10
10
11
11
const PULL_DOWN_CLOSE_THREESHOLD = 200 ;
12
12
const PULL_DOWN_ANDROID_ACTIVATION_HEIGHT = 150 ;
13
+ const SLIDE_ANIMATION_DURATION = 150 ;
14
+ const BACKGROUND_ANIMATION_DURATION = 200 ;
13
15
14
16
class FeedbackWidgetManager {
15
17
private static _isVisible = false ;
@@ -53,7 +55,7 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
53
55
public state : FeedbackWidgetProviderState = {
54
56
isVisible : false ,
55
57
backgroundOpacity : new Animated . Value ( 0 ) ,
56
- panY : new Animated . Value ( 0 ) ,
58
+ panY : new Animated . Value ( Dimensions . get ( 'screen' ) . height ) ,
57
59
} ;
58
60
59
61
private _panResponder = PanResponder . create ( {
@@ -72,8 +74,8 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
72
74
onPanResponderRelease : ( _ , gestureState ) => {
73
75
if ( gestureState . dy > PULL_DOWN_CLOSE_THREESHOLD ) { // Close on swipe below a certain threshold
74
76
Animated . timing ( this . state . panY , {
75
- toValue : 600 ,
76
- duration : 200 ,
77
+ toValue : Dimensions . get ( 'screen' ) . height ,
78
+ duration : SLIDE_ANIMATION_DURATION ,
77
79
useNativeDriver : true ,
78
80
} ) . start ( ( ) => {
79
81
this . _handleClose ( ) ;
@@ -97,11 +99,20 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
97
99
*/
98
100
public componentDidUpdate ( _prevProps : any , prevState : FeedbackWidgetProviderState ) : void {
99
101
if ( ! prevState . isVisible && this . state . isVisible ) {
100
- Animated . timing ( this . state . backgroundOpacity , {
101
- toValue : 1 ,
102
- duration : 300 ,
103
- useNativeDriver : true ,
104
- } ) . start ( ) ;
102
+ Animated . parallel ( [
103
+ Animated . timing ( this . state . backgroundOpacity , {
104
+ toValue : 1 ,
105
+ duration : BACKGROUND_ANIMATION_DURATION ,
106
+ useNativeDriver : true ,
107
+ } ) ,
108
+ Animated . timing ( this . state . panY , {
109
+ toValue : 0 ,
110
+ duration : SLIDE_ANIMATION_DURATION ,
111
+ useNativeDriver : true ,
112
+ } )
113
+ ] ) . start ( ( ) => {
114
+ logger . info ( 'FeedbackWidgetProvider componentDidUpdate' ) ;
115
+ } ) ;
105
116
} else if ( prevState . isVisible && ! this . state . isVisible ) {
106
117
this . state . backgroundOpacity . setValue ( 0 ) ;
107
118
}
@@ -130,7 +141,7 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
130
141
{ this . props . children }
131
142
{ isVisible && (
132
143
< Animated . View style = { [ modalWrapper , { backgroundColor } ] } >
133
- < Modal visible = { isVisible } transparent animationType = "slide " onRequestClose = { this . _handleClose } testID = "feedback-form-modal" >
144
+ < Modal visible = { isVisible } transparent animationType = "none " onRequestClose = { this . _handleClose } testID = "feedback-form-modal" >
134
145
< KeyboardAvoidingView
135
146
behavior = { Platform . OS === 'ios' ? 'padding' : 'height' }
136
147
style = { modalBackground }
@@ -153,15 +164,28 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
153
164
}
154
165
155
166
private _setVisibilityFunction = ( visible : boolean ) : void => {
156
- this . setState ( { isVisible : visible } ) ;
157
- if ( visible ) {
158
- this . state . panY . setValue ( 0 ) ;
159
- }
167
+ const updateState = ( ) => {
168
+ this . setState ( { isVisible : visible } ) ;
169
+ } ;
170
+
171
+ Animated . parallel ( [
172
+ Animated . timing ( this . state . panY , {
173
+ toValue : Dimensions . get ( 'screen' ) . height ,
174
+ duration : SLIDE_ANIMATION_DURATION ,
175
+ useNativeDriver : true ,
176
+ } ) ,
177
+ Animated . timing ( this . state . backgroundOpacity , {
178
+ toValue : 0 ,
179
+ duration : BACKGROUND_ANIMATION_DURATION ,
180
+ useNativeDriver : true ,
181
+ } )
182
+ ] ) . start ( ( ) => {
183
+ updateState ( ) ;
184
+ } ) ;
160
185
} ;
161
186
162
187
private _handleClose = ( ) : void => {
163
188
FeedbackWidgetManager . hide ( ) ;
164
- this . setState ( { isVisible : false } ) ;
165
189
} ;
166
190
}
167
191
0 commit comments