From d861c924b66089e833783d91ed6eb4d8614de009 Mon Sep 17 00:00:00 2001 From: Krystof Woldrich Date: Mon, 17 Feb 2025 15:16:11 +0100 Subject: [PATCH 1/3] chore(feedback): Improve widget animations --- .../core/src/js/feedback/FeedbackWidget.tsx | 11 ++-- .../src/js/feedback/FeedbackWidgetManager.tsx | 54 +++++++++++++------ 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/packages/core/src/js/feedback/FeedbackWidget.tsx b/packages/core/src/js/feedback/FeedbackWidget.tsx index 65087ca0a7..a6a4818623 100644 --- a/packages/core/src/js/feedback/FeedbackWidget.tsx +++ b/packages/core/src/js/feedback/FeedbackWidget.tsx @@ -88,7 +88,9 @@ export class FeedbackWidget extends React.Component { - onFormClose(); - this.setState({ isVisible: false }); + if (onFormClose) { + onFormClose(); + } else { + this.setState({ isVisible: false }); + } } if (!this.state.isVisible) { diff --git a/packages/core/src/js/feedback/FeedbackWidgetManager.tsx b/packages/core/src/js/feedback/FeedbackWidgetManager.tsx index 857fc881cb..a17d8d8f92 100644 --- a/packages/core/src/js/feedback/FeedbackWidgetManager.tsx +++ b/packages/core/src/js/feedback/FeedbackWidgetManager.tsx @@ -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, KeyboardAvoidingView, Modal, PanResponder, Platform } from 'react-native'; import { FeedbackWidget } from './FeedbackWidget'; import { modalBackground, modalSheetContainer, modalWrapper } from './FeedbackWidget.styles'; @@ -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 = 150; +const BACKGROUND_ANIMATION_DURATION = 200; class FeedbackWidgetManager { private static _isVisible = false; @@ -53,7 +55,7 @@ class FeedbackWidgetProvider extends React.Component { 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(); @@ -97,11 +99,20 @@ class FeedbackWidgetProvider extends React.Component { + logger.info('FeedbackWidgetProvider componentDidUpdate'); + }); } else if (prevState.isVisible && !this.state.isVisible) { this.state.backgroundOpacity.setValue(0); } @@ -130,7 +141,7 @@ class FeedbackWidgetProvider extends React.Component - + { - this.setState({ isVisible: visible }); - if (visible) { - this.state.panY.setValue(0); - } + const updateState = () => { + this.setState({ isVisible: visible }); + }; + + Animated.parallel([ + Animated.timing(this.state.panY, { + toValue: Dimensions.get('screen').height, + duration: SLIDE_ANIMATION_DURATION, + useNativeDriver: true, + }), + Animated.timing(this.state.backgroundOpacity, { + toValue: 0, + duration: BACKGROUND_ANIMATION_DURATION, + useNativeDriver: true, + }) + ]).start(() => { + updateState(); + }); }; private _handleClose = (): void => { FeedbackWidgetManager.hide(); - this.setState({ isVisible: false }); }; } From b425a047bd28ba7202b95b8e8f74b542b12bc04e Mon Sep 17 00:00:00 2001 From: Krystof Woldrich Date: Mon, 17 Feb 2025 15:20:17 +0100 Subject: [PATCH 2/3] add comment --- packages/core/src/js/feedback/FeedbackWidgetManager.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/core/src/js/feedback/FeedbackWidgetManager.tsx b/packages/core/src/js/feedback/FeedbackWidgetManager.tsx index a17d8d8f92..010114dbd9 100644 --- a/packages/core/src/js/feedback/FeedbackWidgetManager.tsx +++ b/packages/core/src/js/feedback/FeedbackWidgetManager.tsx @@ -164,10 +164,6 @@ class FeedbackWidgetProvider extends React.Component { - const updateState = () => { - this.setState({ isVisible: visible }); - }; - Animated.parallel([ Animated.timing(this.state.panY, { toValue: Dimensions.get('screen').height, @@ -180,7 +176,9 @@ class FeedbackWidgetProvider extends React.Component { - updateState(); + // Change of the state unmount the component + // which would cancel the animation + this.setState({ isVisible: visible }); }); }; From 20d065904a2a6090c675984abb8c27655c04ce81 Mon Sep 17 00:00:00 2001 From: Krystof Woldrich Date: Mon, 17 Feb 2025 15:35:46 +0100 Subject: [PATCH 3/3] when widget is about to be shown it should not animate slide down --- .../src/js/feedback/FeedbackWidgetManager.tsx | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/packages/core/src/js/feedback/FeedbackWidgetManager.tsx b/packages/core/src/js/feedback/FeedbackWidgetManager.tsx index 010114dbd9..11a7c3f8cc 100644 --- a/packages/core/src/js/feedback/FeedbackWidgetManager.tsx +++ b/packages/core/src/js/feedback/FeedbackWidgetManager.tsx @@ -1,6 +1,6 @@ import { logger } from '@sentry/core'; import * as React from 'react'; -import { Animated, Dimensions, 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'; @@ -10,7 +10,7 @@ import { isModalSupported } from './utils'; const PULL_DOWN_CLOSE_THREESHOLD = 200; const PULL_DOWN_ANDROID_ACTIVATION_HEIGHT = 150; -const SLIDE_ANIMATION_DURATION = 150; +const SLIDE_ANIMATION_DURATION = 200; const BACKGROUND_ANIMATION_DURATION = 200; class FeedbackWidgetManager { @@ -104,11 +104,13 @@ class FeedbackWidgetProvider extends React.Component { logger.info('FeedbackWidgetProvider componentDidUpdate'); @@ -164,22 +166,31 @@ class FeedbackWidgetProvider extends React.Component { - Animated.parallel([ - Animated.timing(this.state.panY, { - toValue: Dimensions.get('screen').height, - duration: SLIDE_ANIMATION_DURATION, - useNativeDriver: true, - }), - Animated.timing(this.state.backgroundOpacity, { - toValue: 0, - duration: BACKGROUND_ANIMATION_DURATION, - useNativeDriver: true, - }) - ]).start(() => { - // Change of the state unmount the component - // which would cancel the animation + 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 => {