@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.
Files changed (96) hide show
  1. package/RNSentry.podspec +1 -1
  2. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +10 -0
  3. package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
  4. package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +5 -0
  5. package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +5 -0
  6. package/dist/js/NativeRNSentry.d.ts +1 -0
  7. package/dist/js/NativeRNSentry.d.ts.map +1 -1
  8. package/dist/js/NativeRNSentry.js.map +1 -1
  9. package/dist/js/feedback/FeedbackButton.d.ts +23 -0
  10. package/dist/js/feedback/FeedbackButton.d.ts.map +1 -0
  11. package/dist/js/feedback/FeedbackButton.js +51 -0
  12. package/dist/js/feedback/FeedbackButton.js.map +1 -0
  13. package/dist/js/feedback/FeedbackWidget.d.ts +13 -1
  14. package/dist/js/feedback/FeedbackWidget.d.ts.map +1 -1
  15. package/dist/js/feedback/FeedbackWidget.js +89 -16
  16. package/dist/js/feedback/FeedbackWidget.js.map +1 -1
  17. package/dist/js/feedback/FeedbackWidget.styles.d.ts +6 -3
  18. package/dist/js/feedback/FeedbackWidget.styles.d.ts.map +1 -1
  19. package/dist/js/feedback/FeedbackWidget.styles.js +155 -106
  20. package/dist/js/feedback/FeedbackWidget.styles.js.map +1 -1
  21. package/dist/js/feedback/FeedbackWidget.theme.d.ts +37 -0
  22. package/dist/js/feedback/FeedbackWidget.theme.d.ts.map +1 -0
  23. package/dist/js/feedback/FeedbackWidget.theme.js +31 -0
  24. package/dist/js/feedback/FeedbackWidget.theme.js.map +1 -0
  25. package/dist/js/feedback/FeedbackWidget.types.d.ts +71 -2
  26. package/dist/js/feedback/FeedbackWidget.types.d.ts.map +1 -1
  27. package/dist/js/feedback/FeedbackWidget.types.js.map +1 -1
  28. package/dist/js/feedback/FeedbackWidgetManager.d.ts +43 -23
  29. package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -1
  30. package/dist/js/feedback/FeedbackWidgetManager.js +62 -138
  31. package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -1
  32. package/dist/js/feedback/FeedbackWidgetProvider.d.ts +48 -0
  33. package/dist/js/feedback/FeedbackWidgetProvider.d.ts.map +1 -0
  34. package/dist/js/feedback/FeedbackWidgetProvider.js +177 -0
  35. package/dist/js/feedback/FeedbackWidgetProvider.js.map +1 -0
  36. package/dist/js/feedback/ScreenshotButton.d.ts +25 -0
  37. package/dist/js/feedback/ScreenshotButton.d.ts.map +1 -0
  38. package/dist/js/feedback/ScreenshotButton.js +80 -0
  39. package/dist/js/feedback/ScreenshotButton.js.map +1 -0
  40. package/dist/js/feedback/defaults.d.ts +3 -1
  41. package/dist/js/feedback/defaults.d.ts.map +1 -1
  42. package/dist/js/feedback/defaults.js +15 -0
  43. package/dist/js/feedback/defaults.js.map +1 -1
  44. package/dist/js/feedback/icons.d.ts +30 -0
  45. package/dist/js/feedback/icons.d.ts.map +1 -0
  46. package/dist/js/feedback/icons.js +30 -0
  47. package/dist/js/feedback/icons.js.map +1 -0
  48. package/dist/js/feedback/integration.d.ts +19 -2
  49. package/dist/js/feedback/integration.d.ts.map +1 -1
  50. package/dist/js/feedback/integration.js +58 -3
  51. package/dist/js/feedback/integration.js.map +1 -1
  52. package/dist/js/feedback/lazy.d.ts +10 -0
  53. package/dist/js/feedback/lazy.d.ts.map +1 -1
  54. package/dist/js/feedback/lazy.js +24 -0
  55. package/dist/js/feedback/lazy.js.map +1 -1
  56. package/dist/js/index.d.ts +3 -2
  57. package/dist/js/index.d.ts.map +1 -1
  58. package/dist/js/index.js +2 -1
  59. package/dist/js/index.js.map +1 -1
  60. package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
  61. package/dist/js/integrations/reactnativeerrorhandlers.js +65 -31
  62. package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
  63. package/dist/js/sdk.js +1 -1
  64. package/dist/js/sdk.js.map +1 -1
  65. package/dist/js/utils/worldwide.d.ts +7 -0
  66. package/dist/js/utils/worldwide.d.ts.map +1 -1
  67. package/dist/js/utils/worldwide.js.map +1 -1
  68. package/dist/js/version.d.ts +1 -1
  69. package/dist/js/version.js +1 -1
  70. package/dist/js/version.js.map +1 -1
  71. package/dist/js/wrapper.d.ts +1 -0
  72. package/dist/js/wrapper.d.ts.map +1 -1
  73. package/dist/js/wrapper.js +17 -1
  74. package/dist/js/wrapper.js.map +1 -1
  75. package/ios/RNSentry.mm +24 -0
  76. package/ios/RNSentryOnDrawReporter.m +4 -0
  77. package/ios/RNSentryVersion.m +1 -1
  78. package/package.json +4 -4
  79. package/src/js/NativeRNSentry.ts +1 -0
  80. package/ts3.8/dist/js/NativeRNSentry.d.ts +1 -0
  81. package/ts3.8/dist/js/feedback/FeedbackButton.d.ts +23 -0
  82. package/ts3.8/dist/js/feedback/FeedbackWidget.d.ts +13 -1
  83. package/ts3.8/dist/js/feedback/FeedbackWidget.styles.d.ts +6 -3
  84. package/ts3.8/dist/js/feedback/FeedbackWidget.theme.d.ts +37 -0
  85. package/ts3.8/dist/js/feedback/FeedbackWidget.types.d.ts +71 -2
  86. package/ts3.8/dist/js/feedback/FeedbackWidgetManager.d.ts +43 -23
  87. package/ts3.8/dist/js/feedback/FeedbackWidgetProvider.d.ts +48 -0
  88. package/ts3.8/dist/js/feedback/ScreenshotButton.d.ts +25 -0
  89. package/ts3.8/dist/js/feedback/defaults.d.ts +3 -1
  90. package/ts3.8/dist/js/feedback/icons.d.ts +30 -0
  91. package/ts3.8/dist/js/feedback/integration.d.ts +19 -2
  92. package/ts3.8/dist/js/feedback/lazy.d.ts +10 -0
  93. package/ts3.8/dist/js/index.d.ts +3 -2
  94. package/ts3.8/dist/js/utils/worldwide.d.ts +7 -0
  95. package/ts3.8/dist/js/version.d.ts +1 -1
  96. 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":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,QAAQ,EAAuE,MAAM,cAAc,CAAC;AAK7G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAsDnE,UAAU,2BAA2B;IACnC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,UAAU,2BAA2B;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,cAAM,sBAAuB,SAAQ,KAAK,CAAC,SAAS,CAAC,2BAA2B,CAAC;IACxE,KAAK,EAAE,2BAA2B,CAKvC;IAEF,OAAO,CAAC,aAAa,CA8BlB;gBAEgB,KAAK,EAAE,2BAA2B;IAKrD;;OAEG;IACI,kBAAkB,CAAC,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,2BAA2B,GAAG,IAAI;IAuBxF;;OAEG;IACI,MAAM,IAAI,KAAK,CAAC,SAAS;IA2ChC,OAAO,CAAC,aAAa,CAEnB;IAEF,OAAO,CAAC,sBAAsB,CA0B5B;IAEF,OAAO,CAAC,YAAY,CAElB;CACH;AAED,QAAA,MAAM,kBAAkB,QAAO,IAG9B,CAAC;AAEF,QAAA,MAAM,0BAA0B,QAAO,IAEtC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,CAAC"}
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 * as React from 'react';
3
- import { Animated, Dimensions, Easing, Modal, PanResponder, Platform, ScrollView, View } from 'react-native';
4
- import { notWeb } from '../utils/environment';
5
- import { FeedbackWidget } from './FeedbackWidget';
6
- import { modalSheetContainer, modalWrapper, topSpacer } from './FeedbackWidget.styles';
7
- import { getFeedbackOptions } from './integration';
8
- import { lazyLoadAutoInjectFeedbackIntegration } from './lazy';
9
- import { isModalSupported, isNativeDriverSupportedForColorAnimations } from './utils';
10
- const PULL_DOWN_CLOSE_THRESHOLD = 200;
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('[Sentry] FeedbackWidget requires `Sentry.wrap(RootComponent)` to be called before `showFeedbackWidget()`.');
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('[Sentry] FeedbackWidget requires `Sentry.wrap(RootComponent)` before interacting with the widget.');
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
- FeedbackWidgetManager._isVisible = false;
52
- class FeedbackWidgetProvider extends React.Component {
53
- constructor(props) {
54
- super(props);
55
- this.state = {
56
- isVisible: false,
57
- backgroundOpacity: new Animated.Value(0),
58
- panY: new Animated.Value(Dimensions.get('screen').height),
59
- isScrollAtTop: true,
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
- * Animates the background opacity when the modal is shown.
64
+ * Returns the name of the feedback component.
131
65
  */
132
- componentDidUpdate(_prevProps, prevState) {
133
- if (!prevState.isVisible && this.state.isVisible) {
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
- * Renders the feedback form modal.
75
+ * Returns the name of the feedback component.
157
76
  */
158
- render() {
159
- if (!isModalSupported()) {
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
- export { showFeedbackWidget, FeedbackWidgetProvider, resetFeedbackWidgetManager };
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":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAG,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,2CAA2C,EAAC,qCAAqC,EAAE,6CAA6C,EAAE,MAAM,QAAQ,CAAC;AAE1J,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAC7C,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAC5C,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAEjD,MAAe,eAAe;IAIlB,MAAM,KAAK,sBAAsB;QACzC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAEM,MAAM,CAAC,UAAU,CAAC,aAAyC;QAChE,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;IACtC,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK;QACjB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,CAAC;IAEM,MAAM,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;SAC3B;aAAM;YACL,qFAAqF;YACrF,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,sBAAsB,mEAAmE,IAAI,CAAC,sBAAsB,MAAM,CAAC,CAAC;SAC3J;IACH,CAAC;IAEM,MAAM,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;SAC5B;aAAM;YACL,qFAAqF;YACrF,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,sBAAsB,4EAA4E,CAAC,CAAC;SACnI;IACH,CAAC;IAEM,MAAM,CAAC,aAAa;QACzB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;;AA3CgB,0BAAU,GAAG,KAAK,CAAC;AA8CtC;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,eAAe;IACxD;;OAEG;IACO,MAAM,KAAK,sBAAsB;QACzC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,eAAe;IACxD;;OAEG;IACO,MAAM,KAAK,sBAAsB;QACzC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,uBAAwB,SAAQ,eAAe;IAC1D;;OAEG;IACO,MAAM,KAAK,sBAAsB;QACzC,OAAO,kBAAkB,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,kBAAkB,GAAG,GAAS,EAAE;IACpC,qCAAqC,EAAE,CAAC;IACxC,qBAAqB,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,0BAA0B,GAAG,GAAS,EAAE;IAC5C,qBAAqB,CAAC,KAAK,EAAE,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,GAAS,EAAE;IACpC,2CAA2C,EAAE,CAAC;IAC9C,qBAAqB,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,GAAS,EAAE;IACpC,qBAAqB,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,0BAA0B,GAAG,GAAS,EAAE;IAC5C,qBAAqB,CAAC,KAAK,EAAE,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,GAAS,EAAE;IACtC,IAAI,KAAK,EAAE,EAAE;QACX,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO;KACR;IACD,6CAA6C,EAAE,CAAC;IAChD,uBAAuB,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,GAAS,EAAE;IACtC,uBAAuB,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,4BAA4B,GAAG,GAAS,EAAE;IAC9C,uBAAuB,CAAC,KAAK,EAAE,CAAC;AAClC,CAAC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,CAAC","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"}