@sentry/react-native 6.14.0 → 6.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RNSentry.podspec +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +10 -0
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +5 -0
- package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +5 -0
- package/dist/js/NativeRNSentry.d.ts +1 -0
- package/dist/js/NativeRNSentry.d.ts.map +1 -1
- package/dist/js/NativeRNSentry.js.map +1 -1
- package/dist/js/feedback/FeedbackButton.d.ts +23 -0
- package/dist/js/feedback/FeedbackButton.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackButton.js +51 -0
- package/dist/js/feedback/FeedbackButton.js.map +1 -0
- package/dist/js/feedback/FeedbackWidget.d.ts +13 -1
- package/dist/js/feedback/FeedbackWidget.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.js +89 -16
- package/dist/js/feedback/FeedbackWidget.js.map +1 -1
- package/dist/js/feedback/FeedbackWidget.styles.d.ts +6 -3
- package/dist/js/feedback/FeedbackWidget.styles.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.styles.js +155 -106
- package/dist/js/feedback/FeedbackWidget.styles.js.map +1 -1
- package/dist/js/feedback/FeedbackWidget.theme.d.ts +37 -0
- package/dist/js/feedback/FeedbackWidget.theme.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackWidget.theme.js +31 -0
- package/dist/js/feedback/FeedbackWidget.theme.js.map +1 -0
- package/dist/js/feedback/FeedbackWidget.types.d.ts +71 -2
- package/dist/js/feedback/FeedbackWidget.types.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.types.js.map +1 -1
- package/dist/js/feedback/FeedbackWidgetManager.d.ts +43 -23
- package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidgetManager.js +62 -138
- package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -1
- package/dist/js/feedback/FeedbackWidgetProvider.d.ts +48 -0
- package/dist/js/feedback/FeedbackWidgetProvider.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackWidgetProvider.js +177 -0
- package/dist/js/feedback/FeedbackWidgetProvider.js.map +1 -0
- package/dist/js/feedback/ScreenshotButton.d.ts +25 -0
- package/dist/js/feedback/ScreenshotButton.d.ts.map +1 -0
- package/dist/js/feedback/ScreenshotButton.js +80 -0
- package/dist/js/feedback/ScreenshotButton.js.map +1 -0
- package/dist/js/feedback/defaults.d.ts +3 -1
- package/dist/js/feedback/defaults.d.ts.map +1 -1
- package/dist/js/feedback/defaults.js +15 -0
- package/dist/js/feedback/defaults.js.map +1 -1
- package/dist/js/feedback/icons.d.ts +30 -0
- package/dist/js/feedback/icons.d.ts.map +1 -0
- package/dist/js/feedback/icons.js +30 -0
- package/dist/js/feedback/icons.js.map +1 -0
- package/dist/js/feedback/integration.d.ts +19 -2
- package/dist/js/feedback/integration.d.ts.map +1 -1
- package/dist/js/feedback/integration.js +58 -3
- package/dist/js/feedback/integration.js.map +1 -1
- package/dist/js/feedback/lazy.d.ts +10 -0
- package/dist/js/feedback/lazy.d.ts.map +1 -1
- package/dist/js/feedback/lazy.js +24 -0
- package/dist/js/feedback/lazy.js.map +1 -1
- package/dist/js/index.d.ts +3 -2
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +2 -1
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js +65 -31
- package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
- package/dist/js/sdk.js +1 -1
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/utils/worldwide.d.ts +7 -0
- package/dist/js/utils/worldwide.d.ts.map +1 -1
- package/dist/js/utils/worldwide.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts +1 -0
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +17 -1
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.mm +24 -0
- package/ios/RNSentryOnDrawReporter.m +4 -0
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +4 -4
- package/src/js/NativeRNSentry.ts +1 -0
- package/ts3.8/dist/js/NativeRNSentry.d.ts +1 -0
- package/ts3.8/dist/js/feedback/FeedbackButton.d.ts +23 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.d.ts +13 -1
- package/ts3.8/dist/js/feedback/FeedbackWidget.styles.d.ts +6 -3
- package/ts3.8/dist/js/feedback/FeedbackWidget.theme.d.ts +37 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.types.d.ts +71 -2
- package/ts3.8/dist/js/feedback/FeedbackWidgetManager.d.ts +43 -23
- package/ts3.8/dist/js/feedback/FeedbackWidgetProvider.d.ts +48 -0
- package/ts3.8/dist/js/feedback/ScreenshotButton.d.ts +25 -0
- package/ts3.8/dist/js/feedback/defaults.d.ts +3 -1
- package/ts3.8/dist/js/feedback/icons.d.ts +30 -0
- package/ts3.8/dist/js/feedback/integration.d.ts +19 -2
- package/ts3.8/dist/js/feedback/lazy.d.ts +10 -0
- package/ts3.8/dist/js/index.d.ts +3 -2
- package/ts3.8/dist/js/utils/worldwide.d.ts +7 -0
- package/ts3.8/dist/js/version.d.ts +1 -1
- package/ts3.8/dist/js/wrapper.d.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackWidgetManager.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetManager.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FeedbackWidgetManager.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetManager.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,uBAAe,eAAe;IAC5B,SAAS,CAAC,MAAM,CAAC,UAAU,UAAS;IACpC,SAAS,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAE5D,SAAS,CAAC,MAAM,KAAK,sBAAsB,IAAI,MAAM,CAEpD;WAEa,UAAU,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAIzE;;OAEG;WACW,KAAK,IAAI,IAAI;WAKb,IAAI,IAAI,IAAI;WAWZ,IAAI,IAAI,IAAI;WAWZ,aAAa,IAAI,OAAO;CAGvC;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,eAAe;IACxD;;OAEG;IACH,SAAS,CAAC,MAAM,KAAK,sBAAsB,IAAI,MAAM,CAEpD;CACF;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,eAAe;IACxD;;OAEG;IACH,SAAS,CAAC,MAAM,KAAK,sBAAsB,IAAI,MAAM,CAEpD;CACF;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,eAAe;IAC1D;;OAEG;IACH,SAAS,CAAC,MAAM,KAAK,sBAAsB,IAAI,MAAM,CAEpD;CACF;AAED,QAAA,MAAM,kBAAkB,QAAO,IAG9B,CAAC;AAEF,QAAA,MAAM,0BAA0B,QAAO,IAEtC,CAAC;AAEF,QAAA,MAAM,kBAAkB,QAAO,IAG9B,CAAC;AAEF,QAAA,MAAM,kBAAkB,QAAO,IAE9B,CAAC;AAEF,QAAA,MAAM,0BAA0B,QAAO,IAEtC,CAAC;AAEF,QAAA,MAAM,oBAAoB,QAAO,IAOhC,CAAC;AAEF,QAAA,MAAM,oBAAoB,QAAO,IAEhC,CAAC;AAEF,QAAA,MAAM,4BAA4B,QAAO,IAExC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,CAAC"}
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { logger } from '@sentry/core';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const SLIDE_ANIMATION_DURATION = 200;
|
|
12
|
-
const BACKGROUND_ANIMATION_DURATION = 200;
|
|
13
|
-
const useNativeDriverForColorAnimations = isNativeDriverSupportedForColorAnimations();
|
|
14
|
-
class FeedbackWidgetManager {
|
|
2
|
+
import { isWeb } from '../utils/environment';
|
|
3
|
+
import { lazyLoadAutoInjectFeedbackButtonIntegration, lazyLoadAutoInjectFeedbackIntegration, lazyLoadAutoInjectScreenshotButtonIntegration } from './lazy';
|
|
4
|
+
export const PULL_DOWN_CLOSE_THRESHOLD = 200;
|
|
5
|
+
export const SLIDE_ANIMATION_DURATION = 200;
|
|
6
|
+
export const BACKGROUND_ANIMATION_DURATION = 200;
|
|
7
|
+
class FeedbackManager {
|
|
8
|
+
static get _feedbackComponentName() {
|
|
9
|
+
throw new Error('Subclasses must override feedbackComponentName');
|
|
10
|
+
}
|
|
15
11
|
static initialize(setVisibility) {
|
|
16
12
|
this._setVisibility = setVisibility;
|
|
17
13
|
}
|
|
@@ -30,7 +26,7 @@ class FeedbackWidgetManager {
|
|
|
30
26
|
else {
|
|
31
27
|
// This message should be always shown otherwise it's not possible to use the widget.
|
|
32
28
|
// eslint-disable-next-line no-console
|
|
33
|
-
console.warn(
|
|
29
|
+
console.warn(`[Sentry] ${this._feedbackComponentName} requires 'Sentry.wrap(RootComponent)' to be called before 'show${this._feedbackComponentName}()'.`);
|
|
34
30
|
}
|
|
35
31
|
}
|
|
36
32
|
static hide() {
|
|
@@ -41,141 +37,45 @@ class FeedbackWidgetManager {
|
|
|
41
37
|
else {
|
|
42
38
|
// This message should be always shown otherwise it's not possible to use the widget.
|
|
43
39
|
// eslint-disable-next-line no-console
|
|
44
|
-
console.warn(
|
|
40
|
+
console.warn(`[Sentry] ${this._feedbackComponentName} requires 'Sentry.wrap(RootComponent)' before interacting with the widget.`);
|
|
45
41
|
}
|
|
46
42
|
}
|
|
47
43
|
static isFormVisible() {
|
|
48
44
|
return this._isVisible;
|
|
49
45
|
}
|
|
50
46
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this._panResponder = PanResponder.create({
|
|
62
|
-
onStartShouldSetPanResponder: (_, gestureState) => {
|
|
63
|
-
return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;
|
|
64
|
-
},
|
|
65
|
-
onMoveShouldSetPanResponder: (_, gestureState) => {
|
|
66
|
-
return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;
|
|
67
|
-
},
|
|
68
|
-
onPanResponderMove: (_, gestureState) => {
|
|
69
|
-
if (gestureState.dy > 0) {
|
|
70
|
-
this.state.panY.setValue(gestureState.dy);
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
onPanResponderRelease: (_, gestureState) => {
|
|
74
|
-
if (gestureState.dy > PULL_DOWN_CLOSE_THRESHOLD) {
|
|
75
|
-
// Close on swipe below a certain threshold
|
|
76
|
-
Animated.timing(this.state.panY, {
|
|
77
|
-
toValue: Dimensions.get('screen').height,
|
|
78
|
-
duration: SLIDE_ANIMATION_DURATION,
|
|
79
|
-
useNativeDriver: true,
|
|
80
|
-
}).start(() => {
|
|
81
|
-
this._handleClose();
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
// Animate it back to the original position
|
|
86
|
-
Animated.spring(this.state.panY, {
|
|
87
|
-
toValue: 0,
|
|
88
|
-
useNativeDriver: true,
|
|
89
|
-
}).start();
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
this._handleScroll = (event) => {
|
|
94
|
-
this.setState({ isScrollAtTop: event.nativeEvent.contentOffset.y <= 0 });
|
|
95
|
-
};
|
|
96
|
-
this._setVisibilityFunction = (visible) => {
|
|
97
|
-
const updateState = () => {
|
|
98
|
-
this.setState({ isVisible: visible });
|
|
99
|
-
};
|
|
100
|
-
if (!visible) {
|
|
101
|
-
Animated.parallel([
|
|
102
|
-
Animated.timing(this.state.panY, {
|
|
103
|
-
toValue: Dimensions.get('screen').height,
|
|
104
|
-
duration: SLIDE_ANIMATION_DURATION,
|
|
105
|
-
useNativeDriver: true,
|
|
106
|
-
easing: Easing.out(Easing.quad),
|
|
107
|
-
}),
|
|
108
|
-
Animated.timing(this.state.backgroundOpacity, {
|
|
109
|
-
toValue: 0,
|
|
110
|
-
duration: BACKGROUND_ANIMATION_DURATION,
|
|
111
|
-
useNativeDriver: useNativeDriverForColorAnimations,
|
|
112
|
-
easing: Easing.out(Easing.quad),
|
|
113
|
-
})
|
|
114
|
-
]).start(() => {
|
|
115
|
-
// Change of the state unmount the component
|
|
116
|
-
// which would cancel the animation
|
|
117
|
-
updateState();
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
updateState();
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
this._handleClose = () => {
|
|
125
|
-
FeedbackWidgetManager.hide();
|
|
126
|
-
};
|
|
127
|
-
FeedbackWidgetManager.initialize(this._setVisibilityFunction);
|
|
47
|
+
FeedbackManager._isVisible = false;
|
|
48
|
+
/**
|
|
49
|
+
* Provides functionality to show and hide the feedback widget.
|
|
50
|
+
*/
|
|
51
|
+
export class FeedbackWidgetManager extends FeedbackManager {
|
|
52
|
+
/**
|
|
53
|
+
* Returns the name of the feedback component.
|
|
54
|
+
*/
|
|
55
|
+
static get _feedbackComponentName() {
|
|
56
|
+
return 'FeedbackWidget';
|
|
128
57
|
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Provides functionality to show and hide the feedback button.
|
|
61
|
+
*/
|
|
62
|
+
export class FeedbackButtonManager extends FeedbackManager {
|
|
129
63
|
/**
|
|
130
|
-
*
|
|
64
|
+
* Returns the name of the feedback component.
|
|
131
65
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Animated.parallel([
|
|
135
|
-
Animated.timing(this.state.backgroundOpacity, {
|
|
136
|
-
toValue: 1,
|
|
137
|
-
duration: BACKGROUND_ANIMATION_DURATION,
|
|
138
|
-
useNativeDriver: useNativeDriverForColorAnimations,
|
|
139
|
-
easing: Easing.in(Easing.quad),
|
|
140
|
-
}),
|
|
141
|
-
Animated.timing(this.state.panY, {
|
|
142
|
-
toValue: 0,
|
|
143
|
-
duration: SLIDE_ANIMATION_DURATION,
|
|
144
|
-
useNativeDriver: true,
|
|
145
|
-
easing: Easing.in(Easing.quad),
|
|
146
|
-
})
|
|
147
|
-
]).start(() => {
|
|
148
|
-
logger.info('FeedbackWidgetProvider componentDidUpdate');
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
else if (prevState.isVisible && !this.state.isVisible) {
|
|
152
|
-
this.state.backgroundOpacity.setValue(0);
|
|
153
|
-
}
|
|
66
|
+
static get _feedbackComponentName() {
|
|
67
|
+
return 'FeedbackButton';
|
|
154
68
|
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Provides functionality to show and hide the screenshot button.
|
|
72
|
+
*/
|
|
73
|
+
export class ScreenshotButtonManager extends FeedbackManager {
|
|
155
74
|
/**
|
|
156
|
-
*
|
|
75
|
+
* Returns the name of the feedback component.
|
|
157
76
|
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
logger.error('FeedbackWidget Modal is not supported in React Native < 0.71 with Fabric renderer.');
|
|
161
|
-
return React.createElement(React.Fragment, null, this.props.children);
|
|
162
|
-
}
|
|
163
|
-
const { isVisible, backgroundOpacity } = this.state;
|
|
164
|
-
const backgroundColor = backgroundOpacity.interpolate({
|
|
165
|
-
inputRange: [0, 1],
|
|
166
|
-
outputRange: ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.9)'],
|
|
167
|
-
});
|
|
168
|
-
// Wrapping the `Modal` component in a `View` component is necessary to avoid
|
|
169
|
-
// issues like https://github.com/software-mansion/react-native-reanimated/issues/6035
|
|
170
|
-
return (React.createElement(React.Fragment, null,
|
|
171
|
-
this.props.children,
|
|
172
|
-
isVisible &&
|
|
173
|
-
React.createElement(Animated.View, { style: [modalWrapper, { backgroundColor }] },
|
|
174
|
-
React.createElement(Modal, { visible: isVisible, transparent: true, animationType: "none", onRequestClose: this._handleClose, testID: "feedback-form-modal" },
|
|
175
|
-
React.createElement(View, { style: topSpacer }),
|
|
176
|
-
React.createElement(Animated.View, Object.assign({ style: [modalSheetContainer, { transform: [{ translateY: this.state.panY }] }] }, this._panResponder.panHandlers),
|
|
177
|
-
React.createElement(ScrollView, { bounces: false, keyboardShouldPersistTaps: "handled", automaticallyAdjustKeyboardInsets: Platform.OS === 'ios', onScroll: this._handleScroll },
|
|
178
|
-
React.createElement(FeedbackWidget, Object.assign({}, getFeedbackOptions(), { onFormClose: this._handleClose, onFormSubmitted: this._handleClose }))))))));
|
|
77
|
+
static get _feedbackComponentName() {
|
|
78
|
+
return 'ScreenshotButton';
|
|
179
79
|
}
|
|
180
80
|
}
|
|
181
81
|
const showFeedbackWidget = () => {
|
|
@@ -185,5 +85,29 @@ const showFeedbackWidget = () => {
|
|
|
185
85
|
const resetFeedbackWidgetManager = () => {
|
|
186
86
|
FeedbackWidgetManager.reset();
|
|
187
87
|
};
|
|
188
|
-
|
|
88
|
+
const showFeedbackButton = () => {
|
|
89
|
+
lazyLoadAutoInjectFeedbackButtonIntegration();
|
|
90
|
+
FeedbackButtonManager.show();
|
|
91
|
+
};
|
|
92
|
+
const hideFeedbackButton = () => {
|
|
93
|
+
FeedbackButtonManager.hide();
|
|
94
|
+
};
|
|
95
|
+
const resetFeedbackButtonManager = () => {
|
|
96
|
+
FeedbackButtonManager.reset();
|
|
97
|
+
};
|
|
98
|
+
const showScreenshotButton = () => {
|
|
99
|
+
if (isWeb()) {
|
|
100
|
+
logger.warn('ScreenshotButton is not supported on Web.');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
lazyLoadAutoInjectScreenshotButtonIntegration();
|
|
104
|
+
ScreenshotButtonManager.show();
|
|
105
|
+
};
|
|
106
|
+
const hideScreenshotButton = () => {
|
|
107
|
+
ScreenshotButtonManager.hide();
|
|
108
|
+
};
|
|
109
|
+
const resetScreenshotButtonManager = () => {
|
|
110
|
+
ScreenshotButtonManager.reset();
|
|
111
|
+
};
|
|
112
|
+
export { showFeedbackButton, hideFeedbackButton, showFeedbackWidget, showScreenshotButton, hideScreenshotButton, resetFeedbackButtonManager, resetFeedbackWidgetManager, resetScreenshotButtonManager };
|
|
189
113
|
//# sourceMappingURL=FeedbackWidgetManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackWidgetManager.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetManager.tsx"],"names":[],"mappings":"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","sourcesContent":["import { logger } from '@sentry/core';\nimport * as React from 'react';\nimport type { NativeScrollEvent, NativeSyntheticEvent} from 'react-native';\nimport { Animated, Dimensions, Easing, Modal, PanResponder, Platform, ScrollView, View } from 'react-native';\n\nimport { notWeb } from '../utils/environment';\nimport { FeedbackWidget } from './FeedbackWidget';\nimport { modalSheetContainer, modalWrapper, topSpacer } from './FeedbackWidget.styles';\nimport type { FeedbackWidgetStyles } from './FeedbackWidget.types';\nimport { getFeedbackOptions } from './integration';\nimport { lazyLoadAutoInjectFeedbackIntegration } from './lazy';\nimport { isModalSupported, isNativeDriverSupportedForColorAnimations } from './utils';\n\nconst PULL_DOWN_CLOSE_THRESHOLD = 200;\nconst SLIDE_ANIMATION_DURATION = 200;\nconst BACKGROUND_ANIMATION_DURATION = 200;\n\nconst useNativeDriverForColorAnimations = isNativeDriverSupportedForColorAnimations();\n\nclass FeedbackWidgetManager {\n private static _isVisible = false;\n private static _setVisibility: (visible: boolean) => void;\n\n public static initialize(setVisibility: (visible: boolean) => void): void {\n this._setVisibility = setVisibility;\n }\n\n /**\n * For testing purposes only.\n */\n public static reset(): void {\n this._isVisible = false;\n this._setVisibility = undefined;\n }\n\n public static show(): void {\n if (this._setVisibility) {\n this._isVisible = true;\n this._setVisibility(true);\n } else {\n // This message should be always shown otherwise it's not possible to use the widget.\n // eslint-disable-next-line no-console\n console.warn('[Sentry] FeedbackWidget requires `Sentry.wrap(RootComponent)` to be called before `showFeedbackWidget()`.');\n }\n }\n\n public static hide(): void {\n if (this._setVisibility) {\n this._isVisible = false;\n this._setVisibility(false);\n } else {\n // This message should be always shown otherwise it's not possible to use the widget.\n // eslint-disable-next-line no-console\n console.warn('[Sentry] FeedbackWidget requires `Sentry.wrap(RootComponent)` before interacting with the widget.');\n }\n }\n\n public static isFormVisible(): boolean {\n return this._isVisible;\n }\n}\n\ninterface FeedbackWidgetProviderProps {\n children: React.ReactNode;\n styles?: FeedbackWidgetStyles;\n}\n\ninterface FeedbackWidgetProviderState {\n isVisible: boolean;\n backgroundOpacity: Animated.Value;\n panY: Animated.Value;\n isScrollAtTop: boolean;\n}\n\nclass FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps> {\n public state: FeedbackWidgetProviderState = {\n isVisible: false,\n backgroundOpacity: new Animated.Value(0),\n panY: new Animated.Value(Dimensions.get('screen').height),\n isScrollAtTop: true,\n };\n\n private _panResponder = PanResponder.create({\n onStartShouldSetPanResponder: (_, gestureState) => {\n return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;\n },\n onMoveShouldSetPanResponder: (_, gestureState) => {\n return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;\n },\n onPanResponderMove: (_, gestureState) => {\n if (gestureState.dy > 0) {\n this.state.panY.setValue(gestureState.dy);\n }\n },\n onPanResponderRelease: (_, gestureState) => {\n if (gestureState.dy > PULL_DOWN_CLOSE_THRESHOLD) {\n // Close on swipe below a certain threshold\n Animated.timing(this.state.panY, {\n toValue: Dimensions.get('screen').height,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n }).start(() => {\n this._handleClose();\n });\n } else {\n // Animate it back to the original position\n Animated.spring(this.state.panY, {\n toValue: 0,\n useNativeDriver: true,\n }).start();\n }\n },\n });\n\n public constructor(props: FeedbackWidgetProviderProps) {\n super(props);\n FeedbackWidgetManager.initialize(this._setVisibilityFunction);\n }\n\n /**\n * Animates the background opacity when the modal is shown.\n */\n public componentDidUpdate(_prevProps: any, prevState: FeedbackWidgetProviderState): void {\n if (!prevState.isVisible && this.state.isVisible) {\n Animated.parallel([\n Animated.timing(this.state.backgroundOpacity, {\n toValue: 1,\n duration: BACKGROUND_ANIMATION_DURATION,\n useNativeDriver: useNativeDriverForColorAnimations,\n easing: Easing.in(Easing.quad),\n }),\n Animated.timing(this.state.panY, {\n toValue: 0,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n easing: Easing.in(Easing.quad),\n })\n ]).start(() => {\n logger.info('FeedbackWidgetProvider componentDidUpdate');\n });\n } else if (prevState.isVisible && !this.state.isVisible) {\n this.state.backgroundOpacity.setValue(0);\n }\n }\n\n /**\n * Renders the feedback form modal.\n */\n public render(): React.ReactNode {\n if (!isModalSupported()) {\n logger.error('FeedbackWidget Modal is not supported in React Native < 0.71 with Fabric renderer.');\n return <>{this.props.children}</>;\n }\n\n const { isVisible, backgroundOpacity } = this.state;\n\n const backgroundColor = backgroundOpacity.interpolate({\n inputRange: [0, 1],\n outputRange: ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.9)'],\n });\n\n // Wrapping the `Modal` component in a `View` component is necessary to avoid\n // issues like https://github.com/software-mansion/react-native-reanimated/issues/6035\n return (\n <>\n {this.props.children}\n {isVisible &&\n <Animated.View style={[modalWrapper, { backgroundColor }]} >\n <Modal visible={isVisible} transparent animationType=\"none\" onRequestClose={this._handleClose} testID=\"feedback-form-modal\">\n <View style={topSpacer}/>\n <Animated.View\n style={[modalSheetContainer, { transform: [{ translateY: this.state.panY }] }]}\n {...this._panResponder.panHandlers}>\n <ScrollView\n bounces={false}\n keyboardShouldPersistTaps=\"handled\"\n automaticallyAdjustKeyboardInsets={Platform.OS === 'ios'}\n onScroll={this._handleScroll}>\n <FeedbackWidget {...getFeedbackOptions()}\n onFormClose={this._handleClose}\n onFormSubmitted={this._handleClose}\n />\n </ScrollView>\n </Animated.View>\n </Modal>\n </Animated.View>\n }\n </>\n );\n }\n\n private _handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>): void => {\n this.setState({ isScrollAtTop: event.nativeEvent.contentOffset.y <= 0 });\n };\n\n private _setVisibilityFunction = (visible: boolean): void => {\n const updateState = (): void => {\n this.setState({ isVisible: visible });\n };\n if (!visible) {\n Animated.parallel([\n Animated.timing(this.state.panY, {\n toValue: Dimensions.get('screen').height,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n easing: Easing.out(Easing.quad),\n }),\n Animated.timing(this.state.backgroundOpacity, {\n toValue: 0,\n duration: BACKGROUND_ANIMATION_DURATION,\n useNativeDriver: useNativeDriverForColorAnimations,\n easing: Easing.out(Easing.quad),\n })\n ]).start(() => {\n // Change of the state unmount the component\n // which would cancel the animation\n updateState();\n });\n } else {\n updateState();\n }\n };\n\n private _handleClose = (): void => {\n FeedbackWidgetManager.hide();\n };\n}\n\nconst showFeedbackWidget = (): void => {\n lazyLoadAutoInjectFeedbackIntegration();\n FeedbackWidgetManager.show();\n};\n\nconst resetFeedbackWidgetManager = (): void => {\n FeedbackWidgetManager.reset();\n};\n\nexport { showFeedbackWidget, FeedbackWidgetProvider, resetFeedbackWidgetManager };\n"]}
|
|
1
|
+
{"version":3,"file":"FeedbackWidgetManager.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetManager.tsx"],"names":[],"mappings":"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","sourcesContent":["import { logger } from '@sentry/core';\n\nimport { isWeb } from '../utils/environment';\nimport { lazyLoadAutoInjectFeedbackButtonIntegration,lazyLoadAutoInjectFeedbackIntegration, lazyLoadAutoInjectScreenshotButtonIntegration } from './lazy';\n\nexport const PULL_DOWN_CLOSE_THRESHOLD = 200;\nexport const SLIDE_ANIMATION_DURATION = 200;\nexport const BACKGROUND_ANIMATION_DURATION = 200;\n\nabstract class FeedbackManager {\n protected static _isVisible = false;\n protected static _setVisibility: (visible: boolean) => void;\n\n protected static get _feedbackComponentName(): string {\n throw new Error('Subclasses must override feedbackComponentName');\n }\n\n public static initialize(setVisibility: (visible: boolean) => void): void {\n this._setVisibility = setVisibility;\n }\n\n /**\n * For testing purposes only.\n */\n public static reset(): void {\n this._isVisible = false;\n this._setVisibility = undefined;\n }\n\n public static show(): void {\n if (this._setVisibility) {\n this._isVisible = true;\n this._setVisibility(true);\n } else {\n // This message should be always shown otherwise it's not possible to use the widget.\n // eslint-disable-next-line no-console\n console.warn(`[Sentry] ${this._feedbackComponentName} requires 'Sentry.wrap(RootComponent)' to be called before 'show${this._feedbackComponentName}()'.`);\n }\n }\n\n public static hide(): void {\n if (this._setVisibility) {\n this._isVisible = false;\n this._setVisibility(false);\n } else {\n // This message should be always shown otherwise it's not possible to use the widget.\n // eslint-disable-next-line no-console\n console.warn(`[Sentry] ${this._feedbackComponentName} requires 'Sentry.wrap(RootComponent)' before interacting with the widget.`);\n }\n }\n\n public static isFormVisible(): boolean {\n return this._isVisible;\n }\n}\n\n/**\n * Provides functionality to show and hide the feedback widget.\n */\nexport class FeedbackWidgetManager extends FeedbackManager {\n /**\n * Returns the name of the feedback component.\n */\n protected static get _feedbackComponentName(): string {\n return 'FeedbackWidget';\n }\n}\n\n/**\n * Provides functionality to show and hide the feedback button.\n */\nexport class FeedbackButtonManager extends FeedbackManager {\n /**\n * Returns the name of the feedback component.\n */\n protected static get _feedbackComponentName(): string {\n return 'FeedbackButton';\n }\n}\n\n/**\n * Provides functionality to show and hide the screenshot button.\n */\nexport class ScreenshotButtonManager extends FeedbackManager {\n /**\n * Returns the name of the feedback component.\n */\n protected static get _feedbackComponentName(): string {\n return 'ScreenshotButton';\n }\n}\n\nconst showFeedbackWidget = (): void => {\n lazyLoadAutoInjectFeedbackIntegration();\n FeedbackWidgetManager.show();\n};\n\nconst resetFeedbackWidgetManager = (): void => {\n FeedbackWidgetManager.reset();\n};\n\nconst showFeedbackButton = (): void => {\n lazyLoadAutoInjectFeedbackButtonIntegration();\n FeedbackButtonManager.show();\n};\n\nconst hideFeedbackButton = (): void => {\n FeedbackButtonManager.hide();\n};\n\nconst resetFeedbackButtonManager = (): void => {\n FeedbackButtonManager.reset();\n};\n\nconst showScreenshotButton = (): void => {\n if (isWeb()) {\n logger.warn('ScreenshotButton is not supported on Web.');\n return;\n }\n lazyLoadAutoInjectScreenshotButtonIntegration();\n ScreenshotButtonManager.show();\n};\n\nconst hideScreenshotButton = (): void => {\n ScreenshotButtonManager.hide();\n};\n\nconst resetScreenshotButtonManager = (): void => {\n ScreenshotButtonManager.reset();\n};\n\nexport { showFeedbackButton, hideFeedbackButton, showFeedbackWidget, showScreenshotButton, hideScreenshotButton, resetFeedbackButtonManager, resetFeedbackWidgetManager, resetScreenshotButtonManager };\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Animated } from 'react-native';
|
|
3
|
+
import type { FeedbackWidgetStyles } from './FeedbackWidget.types';
|
|
4
|
+
export interface FeedbackWidgetProviderProps {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
styles?: FeedbackWidgetStyles;
|
|
7
|
+
}
|
|
8
|
+
export interface FeedbackWidgetProviderState {
|
|
9
|
+
isButtonVisible: boolean;
|
|
10
|
+
isScreenshotButtonVisible: boolean;
|
|
11
|
+
isVisible: boolean;
|
|
12
|
+
backgroundOpacity: Animated.Value;
|
|
13
|
+
panY: Animated.Value;
|
|
14
|
+
isScrollAtTop: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* FeedbackWidgetProvider is a component that wraps the feedback widget and provides
|
|
18
|
+
* functionality to show and hide the widget. It also manages the visibility of the
|
|
19
|
+
* feedback button and screenshot button.
|
|
20
|
+
*/
|
|
21
|
+
export declare class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps> {
|
|
22
|
+
state: FeedbackWidgetProviderState;
|
|
23
|
+
private _themeListener;
|
|
24
|
+
private _panResponder;
|
|
25
|
+
constructor(props: FeedbackWidgetProviderProps);
|
|
26
|
+
/**
|
|
27
|
+
* Add a listener to the theme change event.
|
|
28
|
+
*/
|
|
29
|
+
componentDidMount(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Clean up the theme listener.
|
|
32
|
+
*/
|
|
33
|
+
componentWillUnmount(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Animates the background opacity when the modal is shown.
|
|
36
|
+
*/
|
|
37
|
+
componentDidUpdate(_prevProps: any, prevState: FeedbackWidgetProviderState): void;
|
|
38
|
+
/**
|
|
39
|
+
* Renders the feedback form modal.
|
|
40
|
+
*/
|
|
41
|
+
render(): React.ReactNode;
|
|
42
|
+
private _handleScroll;
|
|
43
|
+
private _setVisibilityFunction;
|
|
44
|
+
private _setButtonVisibilityFunction;
|
|
45
|
+
private _setScreenshotButtonVisibilityFunction;
|
|
46
|
+
private _handleClose;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=FeedbackWidgetProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackWidgetProvider.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAkF,QAAQ,EAAmF,MAAM,cAAc,CAAC;AAOzM,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAQnE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,MAAM,WAAW,2BAA2B;IAC1C,eAAe,EAAE,OAAO,CAAC;IACzB,yBAAyB,EAAE,OAAO,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC;IAClC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK,CAAC,SAAS,CAAC,2BAA2B,CAAC;IAC/E,KAAK,EAAE,2BAA2B,CAOvC;IAEF,OAAO,CAAC,cAAc,CAA0B;IAEhD,OAAO,CAAC,aAAa,CA8BlB;gBAEgB,KAAK,EAAE,2BAA2B;IAOrD;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAMhC;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAMnC;;OAEG;IACI,kBAAkB,CAAC,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,2BAA2B,GAAG,IAAI;IAuBxF;;OAEG;IACI,MAAM,IAAI,KAAK,CAAC,SAAS;IA6ChC,OAAO,CAAC,aAAa,CAEnB;IAEF,OAAO,CAAC,sBAAsB,CA0B5B;IAEF,OAAO,CAAC,4BAA4B,CAElC;IAEF,OAAO,CAAC,sCAAsC,CAE5C;IAEF,OAAO,CAAC,YAAY,CAElB;CACH"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { logger } from '@sentry/core';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Animated, Appearance, Dimensions, Easing, Modal, PanResponder, Platform, ScrollView, View } from 'react-native';
|
|
4
|
+
import { notWeb } from '../utils/environment';
|
|
5
|
+
import { FeedbackButton } from './FeedbackButton';
|
|
6
|
+
import { FeedbackWidget } from './FeedbackWidget';
|
|
7
|
+
import { modalSheetContainer, modalWrapper, topSpacer } from './FeedbackWidget.styles';
|
|
8
|
+
import { getTheme } from './FeedbackWidget.theme';
|
|
9
|
+
import { BACKGROUND_ANIMATION_DURATION, FeedbackButtonManager, FeedbackWidgetManager, PULL_DOWN_CLOSE_THRESHOLD, ScreenshotButtonManager, SLIDE_ANIMATION_DURATION } from './FeedbackWidgetManager';
|
|
10
|
+
import { getFeedbackButtonOptions, getFeedbackOptions, getScreenshotButtonOptions } from './integration';
|
|
11
|
+
import { ScreenshotButton } from './ScreenshotButton';
|
|
12
|
+
import { isModalSupported, isNativeDriverSupportedForColorAnimations } from './utils';
|
|
13
|
+
const useNativeDriverForColorAnimations = isNativeDriverSupportedForColorAnimations();
|
|
14
|
+
/**
|
|
15
|
+
* FeedbackWidgetProvider is a component that wraps the feedback widget and provides
|
|
16
|
+
* functionality to show and hide the widget. It also manages the visibility of the
|
|
17
|
+
* feedback button and screenshot button.
|
|
18
|
+
*/
|
|
19
|
+
export class FeedbackWidgetProvider extends React.Component {
|
|
20
|
+
constructor(props) {
|
|
21
|
+
super(props);
|
|
22
|
+
this.state = {
|
|
23
|
+
isButtonVisible: false,
|
|
24
|
+
isScreenshotButtonVisible: false,
|
|
25
|
+
isVisible: false,
|
|
26
|
+
backgroundOpacity: new Animated.Value(0),
|
|
27
|
+
panY: new Animated.Value(Dimensions.get('screen').height),
|
|
28
|
+
isScrollAtTop: true,
|
|
29
|
+
};
|
|
30
|
+
this._panResponder = PanResponder.create({
|
|
31
|
+
onStartShouldSetPanResponder: (_, gestureState) => {
|
|
32
|
+
return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;
|
|
33
|
+
},
|
|
34
|
+
onMoveShouldSetPanResponder: (_, gestureState) => {
|
|
35
|
+
return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;
|
|
36
|
+
},
|
|
37
|
+
onPanResponderMove: (_, gestureState) => {
|
|
38
|
+
if (gestureState.dy > 0) {
|
|
39
|
+
this.state.panY.setValue(gestureState.dy);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
onPanResponderRelease: (_, gestureState) => {
|
|
43
|
+
if (gestureState.dy > PULL_DOWN_CLOSE_THRESHOLD) {
|
|
44
|
+
// Close on swipe below a certain threshold
|
|
45
|
+
Animated.timing(this.state.panY, {
|
|
46
|
+
toValue: Dimensions.get('screen').height,
|
|
47
|
+
duration: SLIDE_ANIMATION_DURATION,
|
|
48
|
+
useNativeDriver: true,
|
|
49
|
+
}).start(() => {
|
|
50
|
+
this._handleClose();
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Animate it back to the original position
|
|
55
|
+
Animated.spring(this.state.panY, {
|
|
56
|
+
toValue: 0,
|
|
57
|
+
useNativeDriver: true,
|
|
58
|
+
}).start();
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
this._handleScroll = (event) => {
|
|
63
|
+
this.setState({ isScrollAtTop: event.nativeEvent.contentOffset.y <= 0 });
|
|
64
|
+
};
|
|
65
|
+
this._setVisibilityFunction = (visible) => {
|
|
66
|
+
const updateState = () => {
|
|
67
|
+
this.setState({ isVisible: visible });
|
|
68
|
+
};
|
|
69
|
+
if (!visible) {
|
|
70
|
+
Animated.parallel([
|
|
71
|
+
Animated.timing(this.state.panY, {
|
|
72
|
+
toValue: Dimensions.get('screen').height,
|
|
73
|
+
duration: SLIDE_ANIMATION_DURATION,
|
|
74
|
+
useNativeDriver: true,
|
|
75
|
+
easing: Easing.out(Easing.quad),
|
|
76
|
+
}),
|
|
77
|
+
Animated.timing(this.state.backgroundOpacity, {
|
|
78
|
+
toValue: 0,
|
|
79
|
+
duration: BACKGROUND_ANIMATION_DURATION,
|
|
80
|
+
useNativeDriver: useNativeDriverForColorAnimations,
|
|
81
|
+
easing: Easing.out(Easing.quad),
|
|
82
|
+
})
|
|
83
|
+
]).start(() => {
|
|
84
|
+
// Change of the state unmount the component
|
|
85
|
+
// which would cancel the animation
|
|
86
|
+
updateState();
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
updateState();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
this._setButtonVisibilityFunction = (visible) => {
|
|
94
|
+
this.setState({ isButtonVisible: visible });
|
|
95
|
+
};
|
|
96
|
+
this._setScreenshotButtonVisibilityFunction = (visible) => {
|
|
97
|
+
this.setState({ isScreenshotButtonVisible: visible });
|
|
98
|
+
};
|
|
99
|
+
this._handleClose = () => {
|
|
100
|
+
FeedbackWidgetManager.hide();
|
|
101
|
+
};
|
|
102
|
+
FeedbackButtonManager.initialize(this._setButtonVisibilityFunction);
|
|
103
|
+
ScreenshotButtonManager.initialize(this._setScreenshotButtonVisibilityFunction);
|
|
104
|
+
FeedbackWidgetManager.initialize(this._setVisibilityFunction);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Add a listener to the theme change event.
|
|
108
|
+
*/
|
|
109
|
+
componentDidMount() {
|
|
110
|
+
this._themeListener = Appearance.addChangeListener(() => {
|
|
111
|
+
this.forceUpdate();
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Clean up the theme listener.
|
|
116
|
+
*/
|
|
117
|
+
componentWillUnmount() {
|
|
118
|
+
if (this._themeListener) {
|
|
119
|
+
this._themeListener.remove();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Animates the background opacity when the modal is shown.
|
|
124
|
+
*/
|
|
125
|
+
componentDidUpdate(_prevProps, prevState) {
|
|
126
|
+
if (!prevState.isVisible && this.state.isVisible) {
|
|
127
|
+
Animated.parallel([
|
|
128
|
+
Animated.timing(this.state.backgroundOpacity, {
|
|
129
|
+
toValue: 1,
|
|
130
|
+
duration: BACKGROUND_ANIMATION_DURATION,
|
|
131
|
+
useNativeDriver: useNativeDriverForColorAnimations,
|
|
132
|
+
easing: Easing.in(Easing.quad),
|
|
133
|
+
}),
|
|
134
|
+
Animated.timing(this.state.panY, {
|
|
135
|
+
toValue: 0,
|
|
136
|
+
duration: SLIDE_ANIMATION_DURATION,
|
|
137
|
+
useNativeDriver: true,
|
|
138
|
+
easing: Easing.in(Easing.quad),
|
|
139
|
+
})
|
|
140
|
+
]).start(() => {
|
|
141
|
+
logger.info('FeedbackWidgetProvider componentDidUpdate');
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
else if (prevState.isVisible && !this.state.isVisible) {
|
|
145
|
+
this.state.backgroundOpacity.setValue(0);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Renders the feedback form modal.
|
|
150
|
+
*/
|
|
151
|
+
render() {
|
|
152
|
+
if (!isModalSupported()) {
|
|
153
|
+
logger.error('FeedbackWidget Modal is not supported in React Native < 0.71 with Fabric renderer.');
|
|
154
|
+
return React.createElement(React.Fragment, null, this.props.children);
|
|
155
|
+
}
|
|
156
|
+
const theme = getTheme();
|
|
157
|
+
const { isButtonVisible, isScreenshotButtonVisible, isVisible, backgroundOpacity } = this.state;
|
|
158
|
+
const backgroundColor = backgroundOpacity.interpolate({
|
|
159
|
+
inputRange: [0, 1],
|
|
160
|
+
outputRange: ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.9)'],
|
|
161
|
+
});
|
|
162
|
+
// Wrapping the `Modal` component in a `View` component is necessary to avoid
|
|
163
|
+
// issues like https://github.com/software-mansion/react-native-reanimated/issues/6035
|
|
164
|
+
return (React.createElement(React.Fragment, null,
|
|
165
|
+
this.props.children,
|
|
166
|
+
isButtonVisible && React.createElement(FeedbackButton, Object.assign({}, getFeedbackButtonOptions())),
|
|
167
|
+
isScreenshotButtonVisible && React.createElement(ScreenshotButton, Object.assign({}, getScreenshotButtonOptions())),
|
|
168
|
+
isVisible &&
|
|
169
|
+
React.createElement(Animated.View, { style: [modalWrapper, { backgroundColor }] },
|
|
170
|
+
React.createElement(Modal, { visible: isVisible, transparent: true, animationType: "none", onRequestClose: this._handleClose, testID: "feedback-form-modal" },
|
|
171
|
+
React.createElement(View, { style: topSpacer }),
|
|
172
|
+
React.createElement(Animated.View, Object.assign({ style: [modalSheetContainer(theme), { transform: [{ translateY: this.state.panY }] }] }, this._panResponder.panHandlers),
|
|
173
|
+
React.createElement(ScrollView, { bounces: false, keyboardShouldPersistTaps: "handled", automaticallyAdjustKeyboardInsets: Platform.OS === 'ios', onScroll: this._handleScroll },
|
|
174
|
+
React.createElement(FeedbackWidget, Object.assign({}, getFeedbackOptions(), { onFormClose: this._handleClose, onFormSubmitted: this._handleClose }))))))));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=FeedbackWidgetProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackWidgetProvider.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import { logger } from '@sentry/core';\nimport * as React from 'react';\nimport { type NativeEventSubscription, type NativeScrollEvent,type NativeSyntheticEvent, Animated, Appearance, Dimensions, Easing, Modal, PanResponder, Platform, ScrollView, View } from 'react-native';\n\nimport { notWeb } from '../utils/environment';\nimport { FeedbackButton } from './FeedbackButton';\nimport { FeedbackWidget } from './FeedbackWidget';\nimport { modalSheetContainer,modalWrapper, topSpacer } from './FeedbackWidget.styles';\nimport { getTheme } from './FeedbackWidget.theme';\nimport type { FeedbackWidgetStyles } from './FeedbackWidget.types';\nimport { BACKGROUND_ANIMATION_DURATION,FeedbackButtonManager, FeedbackWidgetManager, PULL_DOWN_CLOSE_THRESHOLD, ScreenshotButtonManager, SLIDE_ANIMATION_DURATION } from './FeedbackWidgetManager';\nimport { getFeedbackButtonOptions, getFeedbackOptions, getScreenshotButtonOptions } from './integration';\nimport { ScreenshotButton } from './ScreenshotButton';\nimport { isModalSupported, isNativeDriverSupportedForColorAnimations } from './utils';\n\nconst useNativeDriverForColorAnimations = isNativeDriverSupportedForColorAnimations();\n\nexport interface FeedbackWidgetProviderProps {\n children: React.ReactNode;\n styles?: FeedbackWidgetStyles;\n}\n\nexport interface FeedbackWidgetProviderState {\n isButtonVisible: boolean;\n isScreenshotButtonVisible: boolean;\n isVisible: boolean;\n backgroundOpacity: Animated.Value;\n panY: Animated.Value;\n isScrollAtTop: boolean;\n}\n\n/**\n * FeedbackWidgetProvider is a component that wraps the feedback widget and provides\n * functionality to show and hide the widget. It also manages the visibility of the\n * feedback button and screenshot button.\n */\nexport class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps> {\n public state: FeedbackWidgetProviderState = {\n isButtonVisible: false,\n isScreenshotButtonVisible: false,\n isVisible: false,\n backgroundOpacity: new Animated.Value(0),\n panY: new Animated.Value(Dimensions.get('screen').height),\n isScrollAtTop: true,\n };\n\n private _themeListener: NativeEventSubscription;\n\n private _panResponder = PanResponder.create({\n onStartShouldSetPanResponder: (_, gestureState) => {\n return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;\n },\n onMoveShouldSetPanResponder: (_, gestureState) => {\n return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;\n },\n onPanResponderMove: (_, gestureState) => {\n if (gestureState.dy > 0) {\n this.state.panY.setValue(gestureState.dy);\n }\n },\n onPanResponderRelease: (_, gestureState) => {\n if (gestureState.dy > PULL_DOWN_CLOSE_THRESHOLD) {\n // Close on swipe below a certain threshold\n Animated.timing(this.state.panY, {\n toValue: Dimensions.get('screen').height,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n }).start(() => {\n this._handleClose();\n });\n } else {\n // Animate it back to the original position\n Animated.spring(this.state.panY, {\n toValue: 0,\n useNativeDriver: true,\n }).start();\n }\n },\n });\n\n public constructor(props: FeedbackWidgetProviderProps) {\n super(props);\n FeedbackButtonManager.initialize(this._setButtonVisibilityFunction);\n ScreenshotButtonManager.initialize(this._setScreenshotButtonVisibilityFunction);\n FeedbackWidgetManager.initialize(this._setVisibilityFunction);\n }\n\n /**\n * Add a listener to the theme change event.\n */\n public componentDidMount(): void {\n this._themeListener = Appearance.addChangeListener(() => {\n this.forceUpdate();\n });\n }\n\n /**\n * Clean up the theme listener.\n */\n public componentWillUnmount(): void {\n if (this._themeListener) {\n this._themeListener.remove();\n }\n }\n\n /**\n * Animates the background opacity when the modal is shown.\n */\n public componentDidUpdate(_prevProps: any, prevState: FeedbackWidgetProviderState): void {\n if (!prevState.isVisible && this.state.isVisible) {\n Animated.parallel([\n Animated.timing(this.state.backgroundOpacity, {\n toValue: 1,\n duration: BACKGROUND_ANIMATION_DURATION,\n useNativeDriver: useNativeDriverForColorAnimations,\n easing: Easing.in(Easing.quad),\n }),\n Animated.timing(this.state.panY, {\n toValue: 0,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n easing: Easing.in(Easing.quad),\n })\n ]).start(() => {\n logger.info('FeedbackWidgetProvider componentDidUpdate');\n });\n } else if (prevState.isVisible && !this.state.isVisible) {\n this.state.backgroundOpacity.setValue(0);\n }\n }\n\n /**\n * Renders the feedback form modal.\n */\n public render(): React.ReactNode {\n if (!isModalSupported()) {\n logger.error('FeedbackWidget Modal is not supported in React Native < 0.71 with Fabric renderer.');\n return <>{this.props.children}</>;\n }\n\n const theme = getTheme();\n\n const { isButtonVisible, isScreenshotButtonVisible, isVisible, backgroundOpacity } = this.state;\n\n const backgroundColor = backgroundOpacity.interpolate({\n inputRange: [0, 1],\n outputRange: ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.9)'],\n });\n\n // Wrapping the `Modal` component in a `View` component is necessary to avoid\n // issues like https://github.com/software-mansion/react-native-reanimated/issues/6035\n return (\n <>\n {this.props.children}\n {isButtonVisible && <FeedbackButton {...getFeedbackButtonOptions()} />}\n {isScreenshotButtonVisible && <ScreenshotButton {...getScreenshotButtonOptions()} />}\n {isVisible &&\n <Animated.View style={[modalWrapper, { backgroundColor }]}>\n <Modal visible={isVisible} transparent animationType=\"none\" onRequestClose={this._handleClose} testID=\"feedback-form-modal\">\n <View style={topSpacer} />\n <Animated.View\n style={[modalSheetContainer(theme), { transform: [{ translateY: this.state.panY }] }]}\n {...this._panResponder.panHandlers}>\n <ScrollView\n bounces={false}\n keyboardShouldPersistTaps=\"handled\"\n automaticallyAdjustKeyboardInsets={Platform.OS === 'ios'}\n onScroll={this._handleScroll}>\n <FeedbackWidget {...getFeedbackOptions()}\n onFormClose={this._handleClose}\n onFormSubmitted={this._handleClose} />\n </ScrollView>\n </Animated.View>\n </Modal>\n </Animated.View>}\n </>\n );\n }\n\n private _handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>): void => {\n this.setState({ isScrollAtTop: event.nativeEvent.contentOffset.y <= 0 });\n };\n\n private _setVisibilityFunction = (visible: boolean): void => {\n const updateState = (): void => {\n this.setState({ isVisible: visible });\n };\n if (!visible) {\n Animated.parallel([\n Animated.timing(this.state.panY, {\n toValue: Dimensions.get('screen').height,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n easing: Easing.out(Easing.quad),\n }),\n Animated.timing(this.state.backgroundOpacity, {\n toValue: 0,\n duration: BACKGROUND_ANIMATION_DURATION,\n useNativeDriver: useNativeDriverForColorAnimations,\n easing: Easing.out(Easing.quad),\n })\n ]).start(() => {\n // Change of the state unmount the component\n // which would cancel the animation\n updateState();\n });\n } else {\n updateState();\n }\n };\n\n private _setButtonVisibilityFunction = (visible: boolean): void => {\n this.setState({ isButtonVisible: visible });\n };\n\n private _setScreenshotButtonVisibilityFunction = (visible: boolean): void => {\n this.setState({ isScreenshotButtonVisible: visible });\n };\n\n private _handleClose = (): void => {\n FeedbackWidgetManager.hide();\n };\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { Screenshot } from '../wrapper';
|
|
3
|
+
import type { ScreenshotButtonProps } from './FeedbackWidget.types';
|
|
4
|
+
export declare const getCapturedScreenshot: () => Screenshot | 'ErrorCapturingScreenshot' | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* @beta
|
|
7
|
+
* Implements a screenshot button that takes a screenshot.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ScreenshotButton extends React.Component<ScreenshotButtonProps> {
|
|
10
|
+
private _themeListener;
|
|
11
|
+
constructor(props: ScreenshotButtonProps);
|
|
12
|
+
/**
|
|
13
|
+
* Adds a listener for theme changes.
|
|
14
|
+
*/
|
|
15
|
+
componentDidMount(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Removes the theme listener.
|
|
18
|
+
*/
|
|
19
|
+
componentWillUnmount(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Renders the screenshot button.
|
|
22
|
+
*/
|
|
23
|
+
render(): React.ReactNode;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=ScreenshotButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenshotButton.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/ScreenshotButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK7C,OAAO,KAAK,EAAE,qBAAqB,EAA6D,MAAM,wBAAwB,CAAC;AAoB/H,eAAO,MAAM,qBAAqB,QAAO,UAAU,GAAG,0BAA0B,GAAG,SAIlF,CAAA;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK,CAAC,SAAS,CAAC,qBAAqB,CAAC;IAC1E,OAAO,CAAC,cAAc,CAA0B;gBAE7B,KAAK,EAAE,qBAAqB;IAK/C;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAMhC;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAMnC;;OAEG;IACI,MAAM,IAAI,KAAK,CAAC,SAAS;CAoBjC"}
|