@sentry/react-native 6.8.0 → 6.9.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/android/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +35 -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/FeedbackWidget.d.ts +25 -0
- package/dist/js/feedback/FeedbackWidget.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackWidget.js +249 -0
- package/dist/js/feedback/FeedbackWidget.js.map +1 -0
- package/dist/js/feedback/FeedbackWidget.styles.d.ts +8 -0
- package/dist/js/feedback/FeedbackWidget.styles.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackWidget.styles.js +120 -0
- package/dist/js/feedback/FeedbackWidget.styles.js.map +1 -0
- package/dist/js/feedback/FeedbackWidget.types.d.ts +218 -0
- package/dist/js/feedback/FeedbackWidget.types.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackWidget.types.js +2 -0
- package/dist/js/feedback/FeedbackWidget.types.js.map +1 -0
- package/dist/js/feedback/FeedbackWidgetManager.d.ts +33 -0
- package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackWidgetManager.js +188 -0
- package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -0
- package/dist/js/feedback/branding.d.ts +5 -0
- package/dist/js/feedback/branding.d.ts.map +1 -0
- package/dist/js/feedback/branding.js +5 -0
- package/dist/js/feedback/branding.js.map +1 -0
- package/dist/js/feedback/defaults.d.ts +3 -0
- package/dist/js/feedback/defaults.d.ts.map +1 -0
- package/dist/js/feedback/defaults.js +72 -0
- package/dist/js/feedback/defaults.js.map +1 -0
- package/dist/js/feedback/integration.d.ts +10 -0
- package/dist/js/feedback/integration.d.ts.map +1 -0
- package/dist/js/feedback/integration.js +17 -0
- package/dist/js/feedback/integration.js.map +1 -0
- package/dist/js/feedback/lazy.d.ts +10 -0
- package/dist/js/feedback/lazy.d.ts.map +1 -0
- package/dist/js/feedback/lazy.js +26 -0
- package/dist/js/feedback/lazy.js.map +1 -0
- package/dist/js/feedback/utils.d.ts +17 -0
- package/dist/js/feedback/utils.d.ts.map +1 -0
- package/dist/js/feedback/utils.js +38 -0
- package/dist/js/feedback/utils.js.map +1 -0
- package/dist/js/index.d.ts +2 -0
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +2 -0
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/exports.d.ts +1 -0
- package/dist/js/integrations/exports.d.ts.map +1 -1
- package/dist/js/integrations/exports.js +1 -0
- package/dist/js/integrations/exports.js.map +1 -1
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +3 -1
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
- package/dist/js/tracing/integrations/appStart.js +30 -3
- package/dist/js/tracing/integrations/appStart.js.map +1 -1
- package/dist/js/utils/worldwide.d.ts +1 -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 +15 -0
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.mm +29 -0
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +2 -2
- package/src/js/NativeRNSentry.ts +1 -0
- package/ts3.8/dist/js/NativeRNSentry.d.ts +1 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.d.ts +25 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.styles.d.ts +8 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.types.d.ts +218 -0
- package/ts3.8/dist/js/feedback/FeedbackWidgetManager.d.ts +33 -0
- package/ts3.8/dist/js/feedback/branding.d.ts +5 -0
- package/ts3.8/dist/js/feedback/defaults.d.ts +3 -0
- package/ts3.8/dist/js/feedback/integration.d.ts +10 -0
- package/ts3.8/dist/js/feedback/lazy.d.ts +10 -0
- package/ts3.8/dist/js/feedback/utils.d.ts +17 -0
- package/ts3.8/dist/js/index.d.ts +2 -0
- package/ts3.8/dist/js/integrations/exports.d.ts +1 -0
- package/ts3.8/dist/js/utils/worldwide.d.ts +1 -0
- package/ts3.8/dist/js/version.d.ts +1 -1
- package/ts3.8/dist/js/wrapper.d.ts +1 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import type { FeedbackFormData } from '@sentry/core';
|
|
2
|
+
import type { ImageStyle, TextStyle, ViewStyle } from 'react-native';
|
|
3
|
+
/**
|
|
4
|
+
* The props for the feedback form
|
|
5
|
+
*/
|
|
6
|
+
export interface FeedbackWidgetProps extends FeedbackGeneralConfiguration, FeedbackTextConfiguration, FeedbackCallbacks, ImagePickerConfiguration {
|
|
7
|
+
styles?: FeedbackWidgetStyles;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* General feedback configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface FeedbackGeneralConfiguration {
|
|
13
|
+
/**
|
|
14
|
+
* Show the Sentry branding
|
|
15
|
+
*
|
|
16
|
+
* @default true
|
|
17
|
+
*/
|
|
18
|
+
showBranding?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Should the email field be required?
|
|
21
|
+
*/
|
|
22
|
+
isEmailRequired?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Should the email field be validated?
|
|
25
|
+
*/
|
|
26
|
+
shouldValidateEmail?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Should the name field be required?
|
|
29
|
+
*/
|
|
30
|
+
isNameRequired?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Should the email input field be visible? Note: email will still be collected if set via `Sentry.setUser()`
|
|
33
|
+
*/
|
|
34
|
+
showEmail?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Should the name input field be visible? Note: name will still be collected if set via `Sentry.setUser()`
|
|
37
|
+
*/
|
|
38
|
+
showName?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* This flag determines whether the "Add Screenshot" button is displayed
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
enableScreenshot?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Fill in email/name input fields with Sentry user context if it exists.
|
|
46
|
+
* The value of the email/name keys represent the properties of your user context.
|
|
47
|
+
*/
|
|
48
|
+
useSentryUser?: {
|
|
49
|
+
email: string;
|
|
50
|
+
name: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* All of the different text labels that can be customized
|
|
55
|
+
*/
|
|
56
|
+
export interface FeedbackTextConfiguration {
|
|
57
|
+
/**
|
|
58
|
+
* The label for the Feedback form cancel button that closes dialog
|
|
59
|
+
*/
|
|
60
|
+
cancelButtonLabel?: string;
|
|
61
|
+
/**
|
|
62
|
+
* The label for the Feedback form submit button that sends feedback
|
|
63
|
+
*/
|
|
64
|
+
submitButtonLabel?: string;
|
|
65
|
+
/**
|
|
66
|
+
* The title of the Feedback form
|
|
67
|
+
*/
|
|
68
|
+
formTitle?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Label for the email input
|
|
71
|
+
*/
|
|
72
|
+
emailLabel?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Placeholder text for Feedback email input
|
|
75
|
+
*/
|
|
76
|
+
emailPlaceholder?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Label for the message input
|
|
79
|
+
*/
|
|
80
|
+
messageLabel?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Placeholder text for Feedback message input
|
|
83
|
+
*/
|
|
84
|
+
messagePlaceholder?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Label for the name input
|
|
87
|
+
*/
|
|
88
|
+
nameLabel?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Message after feedback was sent successfully
|
|
91
|
+
*/
|
|
92
|
+
successMessageText?: string;
|
|
93
|
+
/**
|
|
94
|
+
* Placeholder text for Feedback name input
|
|
95
|
+
*/
|
|
96
|
+
namePlaceholder?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Text which indicates that a field is required
|
|
99
|
+
*/
|
|
100
|
+
isRequiredLabel?: string;
|
|
101
|
+
/**
|
|
102
|
+
* The label for the button that adds a screenshot and renders the image editor
|
|
103
|
+
*/
|
|
104
|
+
addScreenshotButtonLabel?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The label for the button that removes a screenshot and hides the image editor
|
|
107
|
+
*/
|
|
108
|
+
removeScreenshotButtonLabel?: string;
|
|
109
|
+
/**
|
|
110
|
+
* The title of the error dialog
|
|
111
|
+
*/
|
|
112
|
+
errorTitle?: string;
|
|
113
|
+
/**
|
|
114
|
+
* The error message when the form is invalid
|
|
115
|
+
*/
|
|
116
|
+
formError?: string;
|
|
117
|
+
/**
|
|
118
|
+
* The error message when the email is invalid
|
|
119
|
+
*/
|
|
120
|
+
emailError?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Message when there is a generic error
|
|
123
|
+
*/
|
|
124
|
+
genericError?: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The public callbacks available for the feedback integration
|
|
128
|
+
*/
|
|
129
|
+
export interface FeedbackCallbacks {
|
|
130
|
+
/**
|
|
131
|
+
* Callback when form is opened
|
|
132
|
+
*/
|
|
133
|
+
onFormOpen?: () => void;
|
|
134
|
+
/**
|
|
135
|
+
* Callback when form is closed and not submitted
|
|
136
|
+
*/
|
|
137
|
+
onFormClose?: () => void;
|
|
138
|
+
/**
|
|
139
|
+
* Callback when a screenshot is added
|
|
140
|
+
*/
|
|
141
|
+
onAddScreenshot?: (addScreenshot: (uri: string) => void) => void;
|
|
142
|
+
/**
|
|
143
|
+
* Callback when feedback is successfully submitted
|
|
144
|
+
*
|
|
145
|
+
* After this you'll see a SuccessMessage on the screen for a moment.
|
|
146
|
+
*/
|
|
147
|
+
onSubmitSuccess?: (data: FeedbackFormData) => void;
|
|
148
|
+
/**
|
|
149
|
+
* Callback when feedback is unsuccessfully submitted
|
|
150
|
+
*/
|
|
151
|
+
onSubmitError?: (error: Error) => void;
|
|
152
|
+
/**
|
|
153
|
+
* Callback when the feedback form is submitted successfully, and the SuccessMessage is complete, or dismissed
|
|
154
|
+
*/
|
|
155
|
+
onFormSubmitted?: () => void;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Image Picker configuration interface compatible with:
|
|
159
|
+
* - `react-native-image-picker`: 7.2, 8.0
|
|
160
|
+
* - `expo-image-picker`: 16.0`
|
|
161
|
+
*/
|
|
162
|
+
export interface ImagePickerConfiguration {
|
|
163
|
+
imagePicker?: ImagePicker;
|
|
164
|
+
}
|
|
165
|
+
interface ImagePickerResponse {
|
|
166
|
+
assets?: ImagePickerAsset[];
|
|
167
|
+
}
|
|
168
|
+
interface ImagePickerAsset {
|
|
169
|
+
fileName?: string;
|
|
170
|
+
uri?: string;
|
|
171
|
+
base64?: string;
|
|
172
|
+
}
|
|
173
|
+
interface ExpoImageLibraryOptions {
|
|
174
|
+
mediaTypes?: 'images'[];
|
|
175
|
+
base64?: boolean;
|
|
176
|
+
}
|
|
177
|
+
interface ReactNativeImageLibraryOptions {
|
|
178
|
+
mediaType: 'photo';
|
|
179
|
+
includeBase64?: boolean;
|
|
180
|
+
}
|
|
181
|
+
export interface ImagePicker {
|
|
182
|
+
launchImageLibraryAsync?: (options?: ExpoImageLibraryOptions) => Promise<ImagePickerResponse>;
|
|
183
|
+
launchImageLibrary?: (options: ReactNativeImageLibraryOptions) => Promise<ImagePickerResponse>;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* The styles for the feedback form
|
|
187
|
+
*/
|
|
188
|
+
export interface FeedbackWidgetStyles {
|
|
189
|
+
container?: ViewStyle;
|
|
190
|
+
title?: TextStyle;
|
|
191
|
+
label?: TextStyle;
|
|
192
|
+
input?: TextStyle;
|
|
193
|
+
textArea?: TextStyle;
|
|
194
|
+
submitButton?: ViewStyle;
|
|
195
|
+
submitText?: TextStyle;
|
|
196
|
+
cancelButton?: ViewStyle;
|
|
197
|
+
cancelText?: TextStyle;
|
|
198
|
+
screenshotButton?: ViewStyle;
|
|
199
|
+
screenshotContainer?: ViewStyle;
|
|
200
|
+
screenshotThumbnail?: ImageStyle;
|
|
201
|
+
screenshotText?: TextStyle;
|
|
202
|
+
titleContainer?: ViewStyle;
|
|
203
|
+
sentryLogo?: ImageStyle;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The state of the feedback form
|
|
207
|
+
*/
|
|
208
|
+
export interface FeedbackWidgetState {
|
|
209
|
+
isVisible: boolean;
|
|
210
|
+
name: string;
|
|
211
|
+
email: string;
|
|
212
|
+
description: string;
|
|
213
|
+
filename?: string;
|
|
214
|
+
attachment?: string | Uint8Array;
|
|
215
|
+
attachmentUri?: string;
|
|
216
|
+
}
|
|
217
|
+
export {};
|
|
218
|
+
//# sourceMappingURL=FeedbackWidget.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackWidget.types.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidget.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackWidget.types.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidget.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { FeedbackFormData } from '@sentry/core';\nimport type { ImageStyle, TextStyle, ViewStyle } from 'react-native';\n\n/**\n * The props for the feedback form\n */\nexport interface FeedbackWidgetProps\n extends FeedbackGeneralConfiguration,\n FeedbackTextConfiguration,\n FeedbackCallbacks,\n ImagePickerConfiguration {\n styles?: FeedbackWidgetStyles;\n}\n\n/**\n * General feedback configuration\n */\nexport interface FeedbackGeneralConfiguration {\n /**\n * Show the Sentry branding\n *\n * @default true\n */\n showBranding?: boolean;\n\n /**\n * Should the email field be required?\n */\n isEmailRequired?: boolean;\n\n /**\n * Should the email field be validated?\n */\n shouldValidateEmail?: boolean;\n\n /**\n * Should the name field be required?\n */\n isNameRequired?: boolean;\n\n /**\n * Should the email input field be visible? Note: email will still be collected if set via `Sentry.setUser()`\n */\n showEmail?: boolean;\n\n /**\n * Should the name input field be visible? Note: name will still be collected if set via `Sentry.setUser()`\n */\n showName?: boolean;\n\n /**\n * This flag determines whether the \"Add Screenshot\" button is displayed\n * @default false\n */\n enableScreenshot?: boolean;\n\n /**\n * Fill in email/name input fields with Sentry user context if it exists.\n * The value of the email/name keys represent the properties of your user context.\n */\n useSentryUser?: {\n email: string;\n name: string;\n };\n}\n\n/**\n * All of the different text labels that can be customized\n */\nexport interface FeedbackTextConfiguration {\n /**\n * The label for the Feedback form cancel button that closes dialog\n */\n cancelButtonLabel?: string;\n\n /**\n * The label for the Feedback form submit button that sends feedback\n */\n submitButtonLabel?: string;\n\n /**\n * The title of the Feedback form\n */\n formTitle?: string;\n\n /**\n * Label for the email input\n */\n emailLabel?: string;\n\n /**\n * Placeholder text for Feedback email input\n */\n emailPlaceholder?: string;\n\n /**\n * Label for the message input\n */\n messageLabel?: string;\n\n /**\n * Placeholder text for Feedback message input\n */\n messagePlaceholder?: string;\n\n /**\n * Label for the name input\n */\n nameLabel?: string;\n\n /**\n * Message after feedback was sent successfully\n */\n successMessageText?: string;\n\n /**\n * Placeholder text for Feedback name input\n */\n namePlaceholder?: string;\n\n /**\n * Text which indicates that a field is required\n */\n isRequiredLabel?: string;\n\n /**\n * The label for the button that adds a screenshot and renders the image editor\n */\n addScreenshotButtonLabel?: string;\n\n /**\n * The label for the button that removes a screenshot and hides the image editor\n */\n removeScreenshotButtonLabel?: string;\n\n /**\n * The title of the error dialog\n */\n errorTitle?: string;\n\n /**\n * The error message when the form is invalid\n */\n formError?: string;\n\n /**\n * The error message when the email is invalid\n */\n emailError?: string;\n\n /**\n * Message when there is a generic error\n */\n genericError?: string;\n}\n\n/**\n * The public callbacks available for the feedback integration\n */\nexport interface FeedbackCallbacks {\n /**\n * Callback when form is opened\n */\n onFormOpen?: () => void;\n\n /**\n * Callback when form is closed and not submitted\n */\n onFormClose?: () => void;\n\n /**\n * Callback when a screenshot is added\n */\n onAddScreenshot?: (addScreenshot: (uri: string) => void) => void;\n\n /**\n * Callback when feedback is successfully submitted\n *\n * After this you'll see a SuccessMessage on the screen for a moment.\n */\n onSubmitSuccess?: (data: FeedbackFormData) => void;\n\n /**\n * Callback when feedback is unsuccessfully submitted\n */\n onSubmitError?: (error: Error) => void;\n\n /**\n * Callback when the feedback form is submitted successfully, and the SuccessMessage is complete, or dismissed\n */\n onFormSubmitted?: () => void;\n}\n\n/**\n * Image Picker configuration interface compatible with:\n * - `react-native-image-picker`: 7.2, 8.0\n * - `expo-image-picker`: 16.0`\n */\nexport interface ImagePickerConfiguration {\n imagePicker?: ImagePicker;\n}\n\ninterface ImagePickerResponse {\n assets?: ImagePickerAsset[];\n}\n\ninterface ImagePickerAsset {\n fileName?: string;\n uri?: string;\n base64?: string;\n}\n\ninterface ExpoImageLibraryOptions {\n mediaTypes?: 'images'[];\n base64?: boolean;\n}\n\ninterface ReactNativeImageLibraryOptions {\n mediaType: 'photo';\n includeBase64?: boolean;\n}\n\nexport interface ImagePicker {\n launchImageLibraryAsync?: (options?: ExpoImageLibraryOptions) => Promise<ImagePickerResponse>;\n\n launchImageLibrary?: (options: ReactNativeImageLibraryOptions) => Promise<ImagePickerResponse>;\n}\n\n/**\n * The styles for the feedback form\n */\nexport interface FeedbackWidgetStyles {\n container?: ViewStyle;\n title?: TextStyle;\n label?: TextStyle;\n input?: TextStyle;\n textArea?: TextStyle;\n submitButton?: ViewStyle;\n submitText?: TextStyle;\n cancelButton?: ViewStyle;\n cancelText?: TextStyle;\n screenshotButton?: ViewStyle;\n screenshotContainer?: ViewStyle;\n screenshotThumbnail?: ImageStyle;\n screenshotText?: TextStyle;\n titleContainer?: ViewStyle;\n sentryLogo?: ImageStyle;\n}\n\n/**\n * The state of the feedback form\n */\nexport interface FeedbackWidgetState {\n isVisible: boolean;\n name: string;\n email: string;\n description: string;\n filename?: string;\n attachment?: string | Uint8Array;\n attachmentUri?: string;\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Animated } from 'react-native';
|
|
3
|
+
import type { FeedbackWidgetStyles } from './FeedbackWidget.types';
|
|
4
|
+
interface FeedbackWidgetProviderProps {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
styles?: FeedbackWidgetStyles;
|
|
7
|
+
}
|
|
8
|
+
interface FeedbackWidgetProviderState {
|
|
9
|
+
isVisible: boolean;
|
|
10
|
+
backgroundOpacity: Animated.Value;
|
|
11
|
+
panY: Animated.Value;
|
|
12
|
+
isScrollAtTop: boolean;
|
|
13
|
+
}
|
|
14
|
+
declare class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps> {
|
|
15
|
+
state: FeedbackWidgetProviderState;
|
|
16
|
+
private _panResponder;
|
|
17
|
+
constructor(props: FeedbackWidgetProviderProps);
|
|
18
|
+
/**
|
|
19
|
+
* Animates the background opacity when the modal is shown.
|
|
20
|
+
*/
|
|
21
|
+
componentDidUpdate(_prevProps: any, prevState: FeedbackWidgetProviderState): void;
|
|
22
|
+
/**
|
|
23
|
+
* Renders the feedback form modal.
|
|
24
|
+
*/
|
|
25
|
+
render(): React.ReactNode;
|
|
26
|
+
private _handleScroll;
|
|
27
|
+
private _setVisibilityFunction;
|
|
28
|
+
private _handleClose;
|
|
29
|
+
}
|
|
30
|
+
declare const showFeedbackWidget: () => void;
|
|
31
|
+
declare const resetFeedbackWidgetManager: () => void;
|
|
32
|
+
export { showFeedbackWidget, FeedbackWidgetProvider, resetFeedbackWidgetManager };
|
|
33
|
+
//# sourceMappingURL=FeedbackWidgetManager.d.ts.map
|
|
@@ -0,0 +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;AAoDnE,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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
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 } from './utils';
|
|
10
|
+
const PULL_DOWN_CLOSE_THRESHOLD = 200;
|
|
11
|
+
const SLIDE_ANIMATION_DURATION = 200;
|
|
12
|
+
const BACKGROUND_ANIMATION_DURATION = 200;
|
|
13
|
+
class FeedbackWidgetManager {
|
|
14
|
+
static initialize(setVisibility) {
|
|
15
|
+
this._setVisibility = setVisibility;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* For testing purposes only.
|
|
19
|
+
*/
|
|
20
|
+
static reset() {
|
|
21
|
+
this._isVisible = false;
|
|
22
|
+
this._setVisibility = undefined;
|
|
23
|
+
}
|
|
24
|
+
static show() {
|
|
25
|
+
if (this._setVisibility) {
|
|
26
|
+
this._isVisible = true;
|
|
27
|
+
this._setVisibility(true);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// This message should be always shown otherwise it's not possible to use the widget.
|
|
31
|
+
// eslint-disable-next-line no-console
|
|
32
|
+
console.warn('[Sentry] FeedbackWidget requires `Sentry.wrap(RootComponent)` to be called before `showFeedbackWidget()`.');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
static hide() {
|
|
36
|
+
if (this._setVisibility) {
|
|
37
|
+
this._isVisible = false;
|
|
38
|
+
this._setVisibility(false);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// This message should be always shown otherwise it's not possible to use the widget.
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.warn('[Sentry] FeedbackWidget requires `Sentry.wrap(RootComponent)` before interacting with the widget.');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
static isFormVisible() {
|
|
47
|
+
return this._isVisible;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
FeedbackWidgetManager._isVisible = false;
|
|
51
|
+
class FeedbackWidgetProvider extends React.Component {
|
|
52
|
+
constructor(props) {
|
|
53
|
+
super(props);
|
|
54
|
+
this.state = {
|
|
55
|
+
isVisible: false,
|
|
56
|
+
backgroundOpacity: new Animated.Value(0),
|
|
57
|
+
panY: new Animated.Value(Dimensions.get('screen').height),
|
|
58
|
+
isScrollAtTop: true,
|
|
59
|
+
};
|
|
60
|
+
this._panResponder = PanResponder.create({
|
|
61
|
+
onStartShouldSetPanResponder: (_, gestureState) => {
|
|
62
|
+
return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;
|
|
63
|
+
},
|
|
64
|
+
onMoveShouldSetPanResponder: (_, gestureState) => {
|
|
65
|
+
return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;
|
|
66
|
+
},
|
|
67
|
+
onPanResponderMove: (_, gestureState) => {
|
|
68
|
+
if (gestureState.dy > 0) {
|
|
69
|
+
this.state.panY.setValue(gestureState.dy);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
onPanResponderRelease: (_, gestureState) => {
|
|
73
|
+
if (gestureState.dy > PULL_DOWN_CLOSE_THRESHOLD) {
|
|
74
|
+
// Close on swipe below a certain threshold
|
|
75
|
+
Animated.timing(this.state.panY, {
|
|
76
|
+
toValue: Dimensions.get('screen').height,
|
|
77
|
+
duration: SLIDE_ANIMATION_DURATION,
|
|
78
|
+
useNativeDriver: true,
|
|
79
|
+
}).start(() => {
|
|
80
|
+
this._handleClose();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// Animate it back to the original position
|
|
85
|
+
Animated.spring(this.state.panY, {
|
|
86
|
+
toValue: 0,
|
|
87
|
+
useNativeDriver: true,
|
|
88
|
+
}).start();
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
this._handleScroll = (event) => {
|
|
93
|
+
this.setState({ isScrollAtTop: event.nativeEvent.contentOffset.y <= 0 });
|
|
94
|
+
};
|
|
95
|
+
this._setVisibilityFunction = (visible) => {
|
|
96
|
+
const updateState = () => {
|
|
97
|
+
this.setState({ isVisible: visible });
|
|
98
|
+
};
|
|
99
|
+
if (!visible) {
|
|
100
|
+
Animated.parallel([
|
|
101
|
+
Animated.timing(this.state.panY, {
|
|
102
|
+
toValue: Dimensions.get('screen').height,
|
|
103
|
+
duration: SLIDE_ANIMATION_DURATION,
|
|
104
|
+
useNativeDriver: true,
|
|
105
|
+
easing: Easing.out(Easing.quad),
|
|
106
|
+
}),
|
|
107
|
+
Animated.timing(this.state.backgroundOpacity, {
|
|
108
|
+
toValue: 0,
|
|
109
|
+
duration: BACKGROUND_ANIMATION_DURATION,
|
|
110
|
+
useNativeDriver: true,
|
|
111
|
+
easing: Easing.out(Easing.quad),
|
|
112
|
+
})
|
|
113
|
+
]).start(() => {
|
|
114
|
+
// Change of the state unmount the component
|
|
115
|
+
// which would cancel the animation
|
|
116
|
+
updateState();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
updateState();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
this._handleClose = () => {
|
|
124
|
+
FeedbackWidgetManager.hide();
|
|
125
|
+
};
|
|
126
|
+
FeedbackWidgetManager.initialize(this._setVisibilityFunction);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Animates the background opacity when the modal is shown.
|
|
130
|
+
*/
|
|
131
|
+
componentDidUpdate(_prevProps, prevState) {
|
|
132
|
+
if (!prevState.isVisible && this.state.isVisible) {
|
|
133
|
+
Animated.parallel([
|
|
134
|
+
Animated.timing(this.state.backgroundOpacity, {
|
|
135
|
+
toValue: 1,
|
|
136
|
+
duration: BACKGROUND_ANIMATION_DURATION,
|
|
137
|
+
useNativeDriver: true,
|
|
138
|
+
easing: Easing.in(Easing.quad),
|
|
139
|
+
}),
|
|
140
|
+
Animated.timing(this.state.panY, {
|
|
141
|
+
toValue: 0,
|
|
142
|
+
duration: SLIDE_ANIMATION_DURATION,
|
|
143
|
+
useNativeDriver: true,
|
|
144
|
+
easing: Easing.in(Easing.quad),
|
|
145
|
+
})
|
|
146
|
+
]).start(() => {
|
|
147
|
+
logger.info('FeedbackWidgetProvider componentDidUpdate');
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
else if (prevState.isVisible && !this.state.isVisible) {
|
|
151
|
+
this.state.backgroundOpacity.setValue(0);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Renders the feedback form modal.
|
|
156
|
+
*/
|
|
157
|
+
render() {
|
|
158
|
+
if (!isModalSupported()) {
|
|
159
|
+
logger.error('FeedbackWidget Modal is not supported in React Native < 0.71 with Fabric renderer.');
|
|
160
|
+
return React.createElement(React.Fragment, null, this.props.children);
|
|
161
|
+
}
|
|
162
|
+
const { isVisible, backgroundOpacity } = this.state;
|
|
163
|
+
const backgroundColor = backgroundOpacity.interpolate({
|
|
164
|
+
inputRange: [0, 1],
|
|
165
|
+
outputRange: ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.9)'],
|
|
166
|
+
});
|
|
167
|
+
// Wrapping the `Modal` component in a `View` component is necessary to avoid
|
|
168
|
+
// issues like https://github.com/software-mansion/react-native-reanimated/issues/6035
|
|
169
|
+
return (React.createElement(React.Fragment, null,
|
|
170
|
+
this.props.children,
|
|
171
|
+
isVisible &&
|
|
172
|
+
React.createElement(Animated.View, { style: [modalWrapper, { backgroundColor }] },
|
|
173
|
+
React.createElement(Modal, { visible: isVisible, transparent: true, animationType: "none", onRequestClose: this._handleClose, testID: "feedback-form-modal" },
|
|
174
|
+
React.createElement(View, { style: topSpacer }),
|
|
175
|
+
React.createElement(Animated.View, Object.assign({ style: [modalSheetContainer, { transform: [{ translateY: this.state.panY }] }] }, this._panResponder.panHandlers),
|
|
176
|
+
React.createElement(ScrollView, { bounces: false, keyboardShouldPersistTaps: "handled", automaticallyAdjustKeyboardInsets: Platform.OS === 'ios', onScroll: this._handleScroll },
|
|
177
|
+
React.createElement(FeedbackWidget, Object.assign({}, getFeedbackOptions(), { onFormClose: this._handleClose, onFormSubmitted: this._handleClose }))))))));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const showFeedbackWidget = () => {
|
|
181
|
+
lazyLoadAutoInjectFeedbackIntegration();
|
|
182
|
+
FeedbackWidgetManager.show();
|
|
183
|
+
};
|
|
184
|
+
const resetFeedbackWidgetManager = () => {
|
|
185
|
+
FeedbackWidgetManager.reset();
|
|
186
|
+
};
|
|
187
|
+
export { showFeedbackWidget, FeedbackWidgetProvider, resetFeedbackWidgetManager };
|
|
188
|
+
//# sourceMappingURL=FeedbackWidgetManager.js.map
|
|
@@ -0,0 +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 } from './utils';\n\nconst PULL_DOWN_CLOSE_THRESHOLD = 200;\nconst SLIDE_ANIMATION_DURATION = 200;\nconst BACKGROUND_ANIMATION_DURATION = 200;\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: true,\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: true,\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"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base64 encoded PNG image of the Sentry logo (source https://sentry.io/branding/)
|
|
3
|
+
*/
|
|
4
|
+
export declare const sentryLogo = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAC4BAMAAABUVL5sAAAAD1BMVEUAAAA2Llo3LVk4LFg2LVmgcvrUAAAABHRSTlMAgL9ARyeO/QAAA7pJREFUeNrtWltynDAQFBIHIFUcgCQ6AIk5AAjd/0ypxFk3ouUCNJofl/rHy75a09MzI7Q2DQ0NDQ0NDQ0NDQ0N9eF+xPh9MKpwPv6FLss7R9yMImz8j8nowb9IglFDF6N+KCNIdqMFcGjpBbVUXdzHqKsXUhJGNb2g1vz6azRgX8XulUwMtVZjFsWkvFz10s0ooEO+9Vpxj/6rp9eI5VsdE6eJcDCxilqICiZWMHBSMkBVA2vq1SVrVyr6Ea5VMjHqjytTwcAgRVJ0DAy9VoWUTNT3tQysZGIYmGNTKHfK0q6oFkysYWCuHB0DaxX9yHLx5JKrhVC0TGwjWNRMvNAuW6PoR4TCepnqLLuiicEyKJq4g2C6Rc+hsInlgtHCF41OrD65INisObksbKy2/YJg9U08sGBTbRN3YaBQQu2i74/mcQil6vZr5C0dQpGbGKJvdOA1VDVxd5LHooPR5BJPdwql5vaLeq9FQZKJpa1kOoUSKpq45+m+ZK93aUpSwRyuafslUguCIZRZamKoBYQT80QmlqnF38p6bSIDcyg2q5fw/uo8dx0upZMLLdadQ1kgkNDEOOGiYYXjVKGJ8V00rEggcErurxAKCwQTi9RCAW7UFcUm5vPAOFNXFBY9DggQyp76jnIkOyBwaeqtyMScEu7w4JRNLnyQOjyvACcWpR145g6PV1fp9mvE0jMd3tWZXDR3/Ud2cSXZfmHhvNpEoFlgYsjFHX4AJc3kXXSTyEfDTrz94ptE1qvS9ouG1Ud2sQT5PVcHg3FL78FIYUpqxWK1yLzMxNzhHVaLzItMzB0eB/S4CDRHC+AzFTjhAiSSHx9tpgJXqnmhXi7VizM/F5v4V5oVqOIp81PpEW4Xt7PUA0kEe5WZ2PLt7ZopDg8Seue9GpxoU0WrHyFPgYlzmyrKPDxcpFeX3YRS5mGvxybmsC2tPhLJQxPzdsfliwMeLjAx9wcujoFIaEAX/KSYXz0s+9TE/E7LX0yF8lQvitl99sVjSgITl/yk6Lk48JjfGadnanHml8xjMvFTA+eL42CRwDKEZwbm4rBMyAmdH6UEz8HDTPj4d4ie1EJxJCQg56DXaxKOl0iGz0jcdebZluzhbFSA1yEZ2JzbHZKQe3I/EK4CErTHbwn84ZP+8Poxqrd/+I2cXJAw0v9VAkBiI3DhLryZEe6SXNeJk5HcHFu+Aom5wiIn2a7niZiE1WKMUhIOhNFJSQZzh0VG8tPcQufLSQI46sO9vcM0NDQ0NDQ0NDQ0NHxF/AFGJOBYBWrb5gAAAABJRU5ErkJggg==";
|
|
5
|
+
//# sourceMappingURL=branding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/branding.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,UAAU,25CACm4C,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base64 encoded PNG image of the Sentry logo (source https://sentry.io/branding/)
|
|
3
|
+
*/
|
|
4
|
+
export const sentryLogo = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAC4BAMAAABUVL5sAAAAD1BMVEUAAAA2Llo3LVk4LFg2LVmgcvrUAAAABHRSTlMAgL9ARyeO/QAAA7pJREFUeNrtWltynDAQFBIHIFUcgCQ6AIk5AAjd/0ypxFk3ouUCNJofl/rHy75a09MzI7Q2DQ0NDQ0NDQ0NDQ0N9eF+xPh9MKpwPv6FLss7R9yMImz8j8nowb9IglFDF6N+KCNIdqMFcGjpBbVUXdzHqKsXUhJGNb2g1vz6azRgX8XulUwMtVZjFsWkvFz10s0ooEO+9Vpxj/6rp9eI5VsdE6eJcDCxilqICiZWMHBSMkBVA2vq1SVrVyr6Ea5VMjHqjytTwcAgRVJ0DAy9VoWUTNT3tQysZGIYmGNTKHfK0q6oFkysYWCuHB0DaxX9yHLx5JKrhVC0TGwjWNRMvNAuW6PoR4TCepnqLLuiicEyKJq4g2C6Rc+hsInlgtHCF41OrD65INisObksbKy2/YJg9U08sGBTbRN3YaBQQu2i74/mcQil6vZr5C0dQpGbGKJvdOA1VDVxd5LHooPR5BJPdwql5vaLeq9FQZKJpa1kOoUSKpq45+m+ZK93aUpSwRyuafslUguCIZRZamKoBYQT80QmlqnF38p6bSIDcyg2q5fw/uo8dx0upZMLLdadQ1kgkNDEOOGiYYXjVKGJ8V00rEggcErurxAKCwQTi9RCAW7UFcUm5vPAOFNXFBY9DggQyp76jnIkOyBwaeqtyMScEu7w4JRNLnyQOjyvACcWpR145g6PV1fp9mvE0jMd3tWZXDR3/Ud2cSXZfmHhvNpEoFlgYsjFHX4AJc3kXXSTyEfDTrz94ptE1qvS9ouG1Ud2sQT5PVcHg3FL78FIYUpqxWK1yLzMxNzhHVaLzItMzB0eB/S4CDRHC+AzFTjhAiSSHx9tpgJXqnmhXi7VizM/F5v4V5oVqOIp81PpEW4Xt7PUA0kEe5WZ2PLt7ZopDg8Seue9GpxoU0WrHyFPgYlzmyrKPDxcpFeX3YRS5mGvxybmsC2tPhLJQxPzdsfliwMeLjAx9wcujoFIaEAX/KSYXz0s+9TE/E7LX0yF8lQvitl99sVjSgITl/yk6Lk48JjfGadnanHml8xjMvFTA+eL42CRwDKEZwbm4rBMyAmdH6UEz8HDTPj4d4ie1EJxJCQg56DXaxKOl0iGz0jcdebZluzhbFSA1yEZ2JzbHZKQe3I/EK4CErTHbwn84ZP+8Poxqrd/+I2cXJAw0v9VAkBiI3DhLryZEe6SXNeJk5HcHFu+Aom5wiIn2a7niZiE1WKMUhIOhNFJSQZzh0VG8tPcQufLSQI46sO9vcM0NDQ0NDQ0NDQ0NHxF/AFGJOBYBWrb5gAAAABJRU5ErkJggg==';
|
|
5
|
+
//# sourceMappingURL=branding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branding.js","sourceRoot":"","sources":["../../../src/js/feedback/branding.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GACrB,w5CAAw5C,CAAC","sourcesContent":["/**\n * Base64 encoded PNG image of the Sentry logo (source https://sentry.io/branding/)\n */\nexport const sentryLogo =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAC4BAMAAABUVL5sAAAAD1BMVEUAAAA2Llo3LVk4LFg2LVmgcvrUAAAABHRSTlMAgL9ARyeO/QAAA7pJREFUeNrtWltynDAQFBIHIFUcgCQ6AIk5AAjd/0ypxFk3ouUCNJofl/rHy75a09MzI7Q2DQ0NDQ0NDQ0NDQ0N9eF+xPh9MKpwPv6FLss7R9yMImz8j8nowb9IglFDF6N+KCNIdqMFcGjpBbVUXdzHqKsXUhJGNb2g1vz6azRgX8XulUwMtVZjFsWkvFz10s0ooEO+9Vpxj/6rp9eI5VsdE6eJcDCxilqICiZWMHBSMkBVA2vq1SVrVyr6Ea5VMjHqjytTwcAgRVJ0DAy9VoWUTNT3tQysZGIYmGNTKHfK0q6oFkysYWCuHB0DaxX9yHLx5JKrhVC0TGwjWNRMvNAuW6PoR4TCepnqLLuiicEyKJq4g2C6Rc+hsInlgtHCF41OrD65INisObksbKy2/YJg9U08sGBTbRN3YaBQQu2i74/mcQil6vZr5C0dQpGbGKJvdOA1VDVxd5LHooPR5BJPdwql5vaLeq9FQZKJpa1kOoUSKpq45+m+ZK93aUpSwRyuafslUguCIZRZamKoBYQT80QmlqnF38p6bSIDcyg2q5fw/uo8dx0upZMLLdadQ1kgkNDEOOGiYYXjVKGJ8V00rEggcErurxAKCwQTi9RCAW7UFcUm5vPAOFNXFBY9DggQyp76jnIkOyBwaeqtyMScEu7w4JRNLnyQOjyvACcWpR145g6PV1fp9mvE0jMd3tWZXDR3/Ud2cSXZfmHhvNpEoFlgYsjFHX4AJc3kXXSTyEfDTrz94ptE1qvS9ouG1Ud2sQT5PVcHg3FL78FIYUpqxWK1yLzMxNzhHVaLzItMzB0eB/S4CDRHC+AzFTjhAiSSHx9tpgJXqnmhXi7VizM/F5v4V5oVqOIp81PpEW4Xt7PUA0kEe5WZ2PLt7ZopDg8Seue9GpxoU0WrHyFPgYlzmyrKPDxcpFeX3YRS5mGvxybmsC2tPhLJQxPzdsfliwMeLjAx9wcujoFIaEAX/KSYXz0s+9TE/E7LX0yF8lQvitl99sVjSgITl/yk6Lk48JjfGadnanHml8xjMvFTA+eL42CRwDKEZwbm4rBMyAmdH6UEz8HDTPj4d4ie1EJxJCQg56DXaxKOl0iGz0jcdebZluzhbFSA1yEZ2JzbHZKQe3I/EK4CErTHbwn84ZP+8Poxqrd/+I2cXJAw0v9VAkBiI3DhLryZEe6SXNeJk5HcHFu+Aom5wiIn2a7niZiE1WKMUhIOhNFJSQZzh0VG8tPcQufLSQI46sO9vcM0NDQ0NDQ0NDQ0NHxF/AFGJOBYBWrb5gAAAABJRU5ErkJggg==';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAqBlE,eAAO,MAAM,oBAAoB,EAAE,OAAO,CAAC,mBAAmB,CA4D7D,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { feedbackAlertDialog } from './utils';
|
|
2
|
+
const FORM_TITLE = 'Report a Bug';
|
|
3
|
+
const NAME_PLACEHOLDER = 'Your Name';
|
|
4
|
+
const NAME_LABEL = 'Name';
|
|
5
|
+
const EMAIL_PLACEHOLDER = 'your.email@example.org';
|
|
6
|
+
const EMAIL_LABEL = 'Email';
|
|
7
|
+
const MESSAGE_PLACEHOLDER = "What's the bug? What did you expect?";
|
|
8
|
+
const MESSAGE_LABEL = 'Description';
|
|
9
|
+
const IS_REQUIRED_LABEL = '(required)';
|
|
10
|
+
const SUBMIT_BUTTON_LABEL = 'Send Bug Report';
|
|
11
|
+
const CANCEL_BUTTON_LABEL = 'Cancel';
|
|
12
|
+
const ERROR_TITLE = 'Error';
|
|
13
|
+
const FORM_ERROR = 'Please fill out all required fields.';
|
|
14
|
+
const EMAIL_ERROR = 'Please enter a valid email address.';
|
|
15
|
+
const SUCCESS_MESSAGE_TEXT = 'Thank you for your report!';
|
|
16
|
+
const ADD_SCREENSHOT_LABEL = 'Add a screenshot';
|
|
17
|
+
const REMOVE_SCREENSHOT_LABEL = 'Remove screenshot';
|
|
18
|
+
const GENERIC_ERROR_TEXT = 'Unable to send feedback due to an unexpected error.';
|
|
19
|
+
export const defaultConfiguration = {
|
|
20
|
+
// FeedbackCallbacks
|
|
21
|
+
onFormOpen: () => {
|
|
22
|
+
// Does nothing by default
|
|
23
|
+
},
|
|
24
|
+
onFormClose: () => {
|
|
25
|
+
if (__DEV__) {
|
|
26
|
+
feedbackAlertDialog('Development note', 'onFormClose callback is not implemented. By default the form is just unmounted.');
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
onAddScreenshot: (_) => {
|
|
30
|
+
if (__DEV__) {
|
|
31
|
+
feedbackAlertDialog('Development note', 'onAddScreenshot callback is not implemented.');
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
onSubmitSuccess: () => {
|
|
35
|
+
// Does nothing by default
|
|
36
|
+
},
|
|
37
|
+
onSubmitError: () => {
|
|
38
|
+
// Does nothing by default
|
|
39
|
+
},
|
|
40
|
+
onFormSubmitted: () => {
|
|
41
|
+
if (__DEV__) {
|
|
42
|
+
feedbackAlertDialog('Development note', 'onFormSubmitted callback is not implemented. By default the form is just unmounted.');
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
// FeedbackGeneralConfiguration
|
|
46
|
+
showBranding: true,
|
|
47
|
+
isEmailRequired: false,
|
|
48
|
+
shouldValidateEmail: true,
|
|
49
|
+
isNameRequired: false,
|
|
50
|
+
showEmail: true,
|
|
51
|
+
showName: true,
|
|
52
|
+
enableScreenshot: false,
|
|
53
|
+
// FeedbackTextConfiguration
|
|
54
|
+
cancelButtonLabel: CANCEL_BUTTON_LABEL,
|
|
55
|
+
emailLabel: EMAIL_LABEL,
|
|
56
|
+
emailPlaceholder: EMAIL_PLACEHOLDER,
|
|
57
|
+
formTitle: FORM_TITLE,
|
|
58
|
+
isRequiredLabel: IS_REQUIRED_LABEL,
|
|
59
|
+
messageLabel: MESSAGE_LABEL,
|
|
60
|
+
messagePlaceholder: MESSAGE_PLACEHOLDER,
|
|
61
|
+
nameLabel: NAME_LABEL,
|
|
62
|
+
namePlaceholder: NAME_PLACEHOLDER,
|
|
63
|
+
submitButtonLabel: SUBMIT_BUTTON_LABEL,
|
|
64
|
+
errorTitle: ERROR_TITLE,
|
|
65
|
+
formError: FORM_ERROR,
|
|
66
|
+
emailError: EMAIL_ERROR,
|
|
67
|
+
successMessageText: SUCCESS_MESSAGE_TEXT,
|
|
68
|
+
addScreenshotButtonLabel: ADD_SCREENSHOT_LABEL,
|
|
69
|
+
removeScreenshotButtonLabel: REMOVE_SCREENSHOT_LABEL,
|
|
70
|
+
genericError: GENERIC_ERROR_TEXT,
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../src/js/feedback/defaults.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,UAAU,GAAG,cAAc,CAAC;AAClC,MAAM,gBAAgB,GAAG,WAAW,CAAC;AACrC,MAAM,UAAU,GAAG,MAAM,CAAC;AAC1B,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AACnD,MAAM,WAAW,GAAG,OAAO,CAAC;AAC5B,MAAM,mBAAmB,GAAG,sCAAsC,CAAC;AACnE,MAAM,aAAa,GAAG,aAAa,CAAC;AACpC,MAAM,iBAAiB,GAAG,YAAY,CAAC;AACvC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAC9C,MAAM,mBAAmB,GAAG,QAAQ,CAAC;AACrC,MAAM,WAAW,GAAG,OAAO,CAAC;AAC5B,MAAM,UAAU,GAAG,sCAAsC,CAAC;AAC1D,MAAM,WAAW,GAAG,qCAAqC,CAAC;AAC1D,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AAC1D,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAChD,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AACpD,MAAM,kBAAkB,GAAG,qDAAqD,CAAC;AAEjF,MAAM,CAAC,MAAM,oBAAoB,GAAiC;IAChE,oBAAoB;IACpB,UAAU,EAAE,GAAG,EAAE;QACf,0BAA0B;IAC5B,CAAC;IACD,WAAW,EAAE,GAAG,EAAE;QAChB,IAAI,OAAO,EAAE;YACX,mBAAmB,CACjB,kBAAkB,EAClB,iFAAiF,CAClF,CAAC;SACH;IACH,CAAC;IACD,eAAe,EAAE,CAAC,CAAwB,EAAE,EAAE;QAC5C,IAAI,OAAO,EAAE;YACX,mBAAmB,CAAC,kBAAkB,EAAE,8CAA8C,CAAC,CAAC;SACzF;IACH,CAAC;IACD,eAAe,EAAE,GAAG,EAAE;QACpB,0BAA0B;IAC5B,CAAC;IACD,aAAa,EAAE,GAAG,EAAE;QAClB,0BAA0B;IAC5B,CAAC;IACD,eAAe,EAAE,GAAG,EAAE;QACpB,IAAI,OAAO,EAAE;YACX,mBAAmB,CACjB,kBAAkB,EAClB,qFAAqF,CACtF,CAAC;SACH;IACH,CAAC;IAED,+BAA+B;IAC/B,YAAY,EAAE,IAAI;IAClB,eAAe,EAAE,KAAK;IACtB,mBAAmB,EAAE,IAAI;IACzB,cAAc,EAAE,KAAK;IACrB,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,gBAAgB,EAAE,KAAK;IAEvB,4BAA4B;IAC5B,iBAAiB,EAAE,mBAAmB;IACtC,UAAU,EAAE,WAAW;IACvB,gBAAgB,EAAE,iBAAiB;IACnC,SAAS,EAAE,UAAU;IACrB,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,aAAa;IAC3B,kBAAkB,EAAE,mBAAmB;IACvC,SAAS,EAAE,UAAU;IACrB,eAAe,EAAE,gBAAgB;IACjC,iBAAiB,EAAE,mBAAmB;IACtC,UAAU,EAAE,WAAW;IACvB,SAAS,EAAE,UAAU;IACrB,UAAU,EAAE,WAAW;IACvB,kBAAkB,EAAE,oBAAoB;IACxC,wBAAwB,EAAE,oBAAoB;IAC9C,2BAA2B,EAAE,uBAAuB;IACpD,YAAY,EAAE,kBAAkB;CACjC,CAAC","sourcesContent":["import type { FeedbackWidgetProps } from './FeedbackWidget.types';\nimport { feedbackAlertDialog } from './utils';\n\nconst FORM_TITLE = 'Report a Bug';\nconst NAME_PLACEHOLDER = 'Your Name';\nconst NAME_LABEL = 'Name';\nconst EMAIL_PLACEHOLDER = 'your.email@example.org';\nconst EMAIL_LABEL = 'Email';\nconst MESSAGE_PLACEHOLDER = \"What's the bug? What did you expect?\";\nconst MESSAGE_LABEL = 'Description';\nconst IS_REQUIRED_LABEL = '(required)';\nconst SUBMIT_BUTTON_LABEL = 'Send Bug Report';\nconst CANCEL_BUTTON_LABEL = 'Cancel';\nconst ERROR_TITLE = 'Error';\nconst FORM_ERROR = 'Please fill out all required fields.';\nconst EMAIL_ERROR = 'Please enter a valid email address.';\nconst SUCCESS_MESSAGE_TEXT = 'Thank you for your report!';\nconst ADD_SCREENSHOT_LABEL = 'Add a screenshot';\nconst REMOVE_SCREENSHOT_LABEL = 'Remove screenshot';\nconst GENERIC_ERROR_TEXT = 'Unable to send feedback due to an unexpected error.';\n\nexport const defaultConfiguration: Partial<FeedbackWidgetProps> = {\n // FeedbackCallbacks\n onFormOpen: () => {\n // Does nothing by default\n },\n onFormClose: () => {\n if (__DEV__) {\n feedbackAlertDialog(\n 'Development note',\n 'onFormClose callback is not implemented. By default the form is just unmounted.',\n );\n }\n },\n onAddScreenshot: (_: (uri: string) => void) => {\n if (__DEV__) {\n feedbackAlertDialog('Development note', 'onAddScreenshot callback is not implemented.');\n }\n },\n onSubmitSuccess: () => {\n // Does nothing by default\n },\n onSubmitError: () => {\n // Does nothing by default\n },\n onFormSubmitted: () => {\n if (__DEV__) {\n feedbackAlertDialog(\n 'Development note',\n 'onFormSubmitted callback is not implemented. By default the form is just unmounted.',\n );\n }\n },\n\n // FeedbackGeneralConfiguration\n showBranding: true,\n isEmailRequired: false,\n shouldValidateEmail: true,\n isNameRequired: false,\n showEmail: true,\n showName: true,\n enableScreenshot: false,\n\n // FeedbackTextConfiguration\n cancelButtonLabel: CANCEL_BUTTON_LABEL,\n emailLabel: EMAIL_LABEL,\n emailPlaceholder: EMAIL_PLACEHOLDER,\n formTitle: FORM_TITLE,\n isRequiredLabel: IS_REQUIRED_LABEL,\n messageLabel: MESSAGE_LABEL,\n messagePlaceholder: MESSAGE_PLACEHOLDER,\n nameLabel: NAME_LABEL,\n namePlaceholder: NAME_PLACEHOLDER,\n submitButtonLabel: SUBMIT_BUTTON_LABEL,\n errorTitle: ERROR_TITLE,\n formError: FORM_ERROR,\n emailError: EMAIL_ERROR,\n successMessageText: SUCCESS_MESSAGE_TEXT,\n addScreenshotButtonLabel: ADD_SCREENSHOT_LABEL,\n removeScreenshotButtonLabel: REMOVE_SCREENSHOT_LABEL,\n genericError: GENERIC_ERROR_TEXT,\n};\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Integration } from '@sentry/core';
|
|
2
|
+
import type { FeedbackWidgetProps } from './FeedbackWidget.types';
|
|
3
|
+
export declare const MOBILE_FEEDBACK_INTEGRATION_NAME = "MobileFeedback";
|
|
4
|
+
type FeedbackIntegration = Integration & {
|
|
5
|
+
options: Partial<FeedbackWidgetProps>;
|
|
6
|
+
};
|
|
7
|
+
export declare const feedbackIntegration: (initOptions?: FeedbackWidgetProps) => FeedbackIntegration;
|
|
8
|
+
export declare const getFeedbackOptions: () => Partial<FeedbackWidgetProps>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAa,MAAM,cAAc,CAAC;AAE3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAElE,eAAO,MAAM,gCAAgC,mBAAmB,CAAC;AAEjE,KAAK,mBAAmB,GAAG,WAAW,GAAG;IACvC,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,mBAAmB,iBAAiB,mBAAmB,KAAQ,mBAK3E,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAO,QAAQ,mBAAmB,CAShE,CAAC"}
|