Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions packages/core/src/js/feedback/FeedbackWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ export class FeedbackWidget extends React.Component<FeedbackWidgetProps, Feedbac
};

try {
this.setState({ isVisible: false });
if (!onFormSubmitted) {
this.setState({ isVisible: false });
}
captureFeedback(userFeedback, attachments ? { attachments } : undefined);
onSubmitSuccess({ name: trimmedName, email: trimmedEmail, message: trimmedDescription, attachments: undefined });
Alert.alert(text.successMessageText);
Expand Down Expand Up @@ -161,8 +163,11 @@ export class FeedbackWidget extends React.Component<FeedbackWidgetProps, Feedbac
const text: FeedbackTextConfiguration = this.props;
const styles: FeedbackWidgetStyles = { ...defaultStyles, ...this.props.styles };
const onCancel = (): void => {
onFormClose();
this.setState({ isVisible: false });
if (onFormClose) {
onFormClose();
} else {
this.setState({ isVisible: false });
}
}

if (!this.state.isVisible) {
Expand Down
61 changes: 47 additions & 14 deletions packages/core/src/js/feedback/FeedbackWidgetManager.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { logger } from '@sentry/core';
import * as React from 'react';
import { Animated, KeyboardAvoidingView, Modal, PanResponder, Platform } from 'react-native';
import { Animated, Dimensions, Easing, KeyboardAvoidingView, Modal, PanResponder, Platform } from 'react-native';

import { FeedbackWidget } from './FeedbackWidget';
import { modalBackground, modalSheetContainer, modalWrapper } from './FeedbackWidget.styles';
Expand All @@ -10,6 +10,8 @@ import { isModalSupported } from './utils';

const PULL_DOWN_CLOSE_THREESHOLD = 200;
const PULL_DOWN_ANDROID_ACTIVATION_HEIGHT = 150;
const SLIDE_ANIMATION_DURATION = 200;
const BACKGROUND_ANIMATION_DURATION = 200;

class FeedbackWidgetManager {
private static _isVisible = false;
Expand Down Expand Up @@ -53,7 +55,7 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
public state: FeedbackWidgetProviderState = {
isVisible: false,
backgroundOpacity: new Animated.Value(0),
panY: new Animated.Value(0),
panY: new Animated.Value(Dimensions.get('screen').height),
};

private _panResponder = PanResponder.create({
Expand All @@ -72,8 +74,8 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
onPanResponderRelease: (_, gestureState) => {
if (gestureState.dy > PULL_DOWN_CLOSE_THREESHOLD) { // Close on swipe below a certain threshold
Animated.timing(this.state.panY, {
toValue: 600,
duration: 200,
toValue: Dimensions.get('screen').height,
duration: SLIDE_ANIMATION_DURATION,
useNativeDriver: true,
}).start(() => {
this._handleClose();
Expand All @@ -97,11 +99,22 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
*/
public componentDidUpdate(_prevProps: any, prevState: FeedbackWidgetProviderState): void {
if (!prevState.isVisible && this.state.isVisible) {
Animated.timing(this.state.backgroundOpacity, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}).start();
Animated.parallel([
Animated.timing(this.state.backgroundOpacity, {
toValue: 1,
duration: BACKGROUND_ANIMATION_DURATION,
useNativeDriver: true,
easing: Easing.in(Easing.quad),
}),
Animated.timing(this.state.panY, {
toValue: 0,
duration: SLIDE_ANIMATION_DURATION,
useNativeDriver: true,
easing: Easing.in(Easing.quad),
})
]).start(() => {
logger.info('FeedbackWidgetProvider componentDidUpdate');
});
} else if (prevState.isVisible && !this.state.isVisible) {
this.state.backgroundOpacity.setValue(0);
}
Expand Down Expand Up @@ -130,7 +143,7 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
{this.props.children}
{isVisible && (
<Animated.View style={[modalWrapper, { backgroundColor }]} >
<Modal visible={isVisible} transparent animationType="slide" onRequestClose={this._handleClose} testID="feedback-form-modal">
<Modal visible={isVisible} transparent animationType="none" onRequestClose={this._handleClose} testID="feedback-form-modal">
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={modalBackground}
Expand All @@ -153,15 +166,35 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
}

private _setVisibilityFunction = (visible: boolean): void => {
this.setState({ isVisible: visible });
if (visible) {
this.state.panY.setValue(0);
const updateState = (): void => {
this.setState({ isVisible: visible });
};
if (!visible) {
Animated.parallel([
Animated.timing(this.state.panY, {
toValue: Dimensions.get('screen').height,
duration: SLIDE_ANIMATION_DURATION,
useNativeDriver: true,
easing: Easing.out(Easing.quad),
}),
Animated.timing(this.state.backgroundOpacity, {
toValue: 0,
duration: BACKGROUND_ANIMATION_DURATION,
useNativeDriver: true,
easing: Easing.out(Easing.quad),
})
]).start(() => {
// Change of the state unmount the component
// which would cancel the animation
updateState();
});
} else {
updateState();
}
};

private _handleClose = (): void => {
FeedbackWidgetManager.hide();
this.setState({ isVisible: false });
};
}

Expand Down
Loading