@sentry/react-native 6.14.0 → 6.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RNSentry.podspec +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +10 -0
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +5 -0
- package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +5 -0
- package/dist/js/NativeRNSentry.d.ts +1 -0
- package/dist/js/NativeRNSentry.d.ts.map +1 -1
- package/dist/js/NativeRNSentry.js.map +1 -1
- package/dist/js/feedback/FeedbackButton.d.ts +23 -0
- package/dist/js/feedback/FeedbackButton.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackButton.js +51 -0
- package/dist/js/feedback/FeedbackButton.js.map +1 -0
- package/dist/js/feedback/FeedbackWidget.d.ts +12 -1
- package/dist/js/feedback/FeedbackWidget.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.js +78 -13
- package/dist/js/feedback/FeedbackWidget.js.map +1 -1
- package/dist/js/feedback/FeedbackWidget.styles.d.ts +6 -3
- package/dist/js/feedback/FeedbackWidget.styles.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.styles.js +155 -106
- package/dist/js/feedback/FeedbackWidget.styles.js.map +1 -1
- package/dist/js/feedback/FeedbackWidget.theme.d.ts +37 -0
- package/dist/js/feedback/FeedbackWidget.theme.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackWidget.theme.js +31 -0
- package/dist/js/feedback/FeedbackWidget.theme.js.map +1 -0
- package/dist/js/feedback/FeedbackWidget.types.d.ts +71 -2
- package/dist/js/feedback/FeedbackWidget.types.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.types.js.map +1 -1
- package/dist/js/feedback/FeedbackWidgetManager.d.ts +43 -23
- package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidgetManager.js +62 -138
- package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -1
- package/dist/js/feedback/FeedbackWidgetProvider.d.ts +48 -0
- package/dist/js/feedback/FeedbackWidgetProvider.d.ts.map +1 -0
- package/dist/js/feedback/FeedbackWidgetProvider.js +177 -0
- package/dist/js/feedback/FeedbackWidgetProvider.js.map +1 -0
- package/dist/js/feedback/ScreenshotButton.d.ts +25 -0
- package/dist/js/feedback/ScreenshotButton.d.ts.map +1 -0
- package/dist/js/feedback/ScreenshotButton.js +80 -0
- package/dist/js/feedback/ScreenshotButton.js.map +1 -0
- package/dist/js/feedback/defaults.d.ts +3 -1
- package/dist/js/feedback/defaults.d.ts.map +1 -1
- package/dist/js/feedback/defaults.js +15 -0
- package/dist/js/feedback/defaults.js.map +1 -1
- package/dist/js/feedback/icons.d.ts +30 -0
- package/dist/js/feedback/icons.d.ts.map +1 -0
- package/dist/js/feedback/icons.js +30 -0
- package/dist/js/feedback/icons.js.map +1 -0
- package/dist/js/feedback/integration.d.ts +19 -2
- package/dist/js/feedback/integration.d.ts.map +1 -1
- package/dist/js/feedback/integration.js +58 -3
- package/dist/js/feedback/integration.js.map +1 -1
- package/dist/js/feedback/lazy.d.ts +10 -0
- package/dist/js/feedback/lazy.d.ts.map +1 -1
- package/dist/js/feedback/lazy.js +24 -0
- package/dist/js/feedback/lazy.js.map +1 -1
- package/dist/js/index.d.ts +3 -2
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +2 -1
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js +65 -31
- package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
- package/dist/js/sdk.js +1 -1
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/utils/worldwide.d.ts +7 -0
- package/dist/js/utils/worldwide.d.ts.map +1 -1
- package/dist/js/utils/worldwide.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts +1 -0
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +17 -1
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.mm +24 -0
- package/ios/RNSentryOnDrawReporter.m +4 -0
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +4 -4
- package/src/js/NativeRNSentry.ts +1 -0
- package/ts3.8/dist/js/NativeRNSentry.d.ts +1 -0
- package/ts3.8/dist/js/feedback/FeedbackButton.d.ts +23 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.d.ts +12 -1
- package/ts3.8/dist/js/feedback/FeedbackWidget.styles.d.ts +6 -3
- package/ts3.8/dist/js/feedback/FeedbackWidget.theme.d.ts +37 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.types.d.ts +71 -2
- package/ts3.8/dist/js/feedback/FeedbackWidgetManager.d.ts +43 -23
- package/ts3.8/dist/js/feedback/FeedbackWidgetProvider.d.ts +48 -0
- package/ts3.8/dist/js/feedback/ScreenshotButton.d.ts +25 -0
- package/ts3.8/dist/js/feedback/defaults.d.ts +3 -1
- package/ts3.8/dist/js/feedback/icons.d.ts +30 -0
- package/ts3.8/dist/js/feedback/integration.d.ts +19 -2
- package/ts3.8/dist/js/feedback/lazy.d.ts +10 -0
- package/ts3.8/dist/js/index.d.ts +3 -2
- package/ts3.8/dist/js/utils/worldwide.d.ts +7 -0
- package/ts3.8/dist/js/version.d.ts +1 -1
- package/ts3.8/dist/js/wrapper.d.ts +1 -0
package/RNSentry.podspec
CHANGED
|
@@ -37,7 +37,7 @@ Pod::Spec.new do |s|
|
|
|
37
37
|
|
|
38
38
|
s.compiler_flags = other_cflags
|
|
39
39
|
|
|
40
|
-
s.dependency 'Sentry/HybridSDK', '8.
|
|
40
|
+
s.dependency 'Sentry/HybridSDK', '8.52.0'
|
|
41
41
|
|
|
42
42
|
if defined? install_modules_dependencies
|
|
43
43
|
# Default React Native dependencies for 0.71 and above (new and legacy architecture)
|
|
@@ -20,6 +20,7 @@ import com.facebook.hermes.instrumentation.HermesSamplingProfiler;
|
|
|
20
20
|
import com.facebook.react.bridge.Arguments;
|
|
21
21
|
import com.facebook.react.bridge.Promise;
|
|
22
22
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
23
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
23
24
|
import com.facebook.react.bridge.ReadableMap;
|
|
24
25
|
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
25
26
|
import com.facebook.react.bridge.ReadableType;
|
|
@@ -1038,6 +1039,15 @@ public class RNSentryModuleImpl {
|
|
|
1038
1039
|
}
|
|
1039
1040
|
}
|
|
1040
1041
|
|
|
1042
|
+
public void encodeToBase64(ReadableArray array, Promise promise) {
|
|
1043
|
+
byte[] bytes = new byte[array.size()];
|
|
1044
|
+
for (int i = 0; i < array.size(); i++) {
|
|
1045
|
+
bytes[i] = (byte) array.getInt(i);
|
|
1046
|
+
}
|
|
1047
|
+
String base64String = android.util.Base64.encodeToString(bytes, android.util.Base64.DEFAULT);
|
|
1048
|
+
promise.resolve(base64String);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1041
1051
|
public void crashedLastRun(Promise promise) {
|
|
1042
1052
|
promise.resolve(Sentry.isCrashedLastRun());
|
|
1043
1053
|
}
|
|
@@ -2,7 +2,7 @@ package io.sentry.react;
|
|
|
2
2
|
|
|
3
3
|
class RNSentryVersion {
|
|
4
4
|
static final String REACT_NATIVE_SDK_PACKAGE_NAME = "npm:@sentry/react-native";
|
|
5
|
-
static final String REACT_NATIVE_SDK_PACKAGE_VERSION = "6.
|
|
5
|
+
static final String REACT_NATIVE_SDK_PACKAGE_VERSION = "6.15.0";
|
|
6
6
|
static final String NATIVE_SDK_NAME = "sentry.native.android.react-native";
|
|
7
7
|
static final String ANDROID_SDK_NAME = "sentry.java.android.react-native";
|
|
8
8
|
static final String REACT_NATIVE_SDK_NAME = "sentry.javascript.react-native";
|
|
@@ -183,6 +183,11 @@ public class RNSentryModule extends NativeRNSentrySpec {
|
|
|
183
183
|
this.impl.getDataFromUri(uri, promise);
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
@Override
|
|
187
|
+
public void encodeToBase64(ReadableArray array, Promise promise) {
|
|
188
|
+
this.impl.encodeToBase64(array, promise);
|
|
189
|
+
}
|
|
190
|
+
|
|
186
191
|
@Override
|
|
187
192
|
public void popTimeToDisplayFor(String key, Promise promise) {
|
|
188
193
|
this.impl.popTimeToDisplayFor(key, promise);
|
|
@@ -183,6 +183,11 @@ public class RNSentryModule extends ReactContextBaseJavaModule {
|
|
|
183
183
|
this.impl.getDataFromUri(uri, promise);
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
@ReactMethod
|
|
187
|
+
public void encodeToBase64(ReadableArray array, Promise promise) {
|
|
188
|
+
this.impl.encodeToBase64(array, promise);
|
|
189
|
+
}
|
|
190
|
+
|
|
186
191
|
@ReactMethod
|
|
187
192
|
public void popTimeToDisplayFor(String key, Promise promise) {
|
|
188
193
|
this.impl.popTimeToDisplayFor(key, promise);
|
|
@@ -46,6 +46,7 @@ export interface Spec extends TurboModule {
|
|
|
46
46
|
getDataFromUri(uri: string): Promise<number[]>;
|
|
47
47
|
popTimeToDisplayFor(key: string): Promise<number | undefined | null>;
|
|
48
48
|
setActiveSpanId(spanId: string): boolean;
|
|
49
|
+
encodeToBase64(data: number[]): Promise<string | undefined | null>;
|
|
49
50
|
}
|
|
50
51
|
export type NativeStackFrame = {
|
|
51
52
|
platform: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeRNSentry.d.ts","sourceRoot":"","sources":["../../src/js/NativeRNSentry.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"NativeRNSentry.d.ts","sourceRoot":"","sources":["../../src/js/NativeRNSentry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeRNSentry.js","sourceRoot":"","sources":["../../src/js/NativeRNSentry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeRNSentry.js","sourceRoot":"","sources":["../../src/js/NativeRNSentry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AA8JnD,2DAA2D;AAC3D,eAAe,mBAAmB,CAAC,YAAY,CAAO,UAAU,CAAC,CAAC","sourcesContent":["import type { Package } from '@sentry/core';\nimport type { TurboModule } from 'react-native';\nimport { TurboModuleRegistry } from 'react-native';\n\nimport type { UnsafeObject } from './utils/rnlibrariesinterface';\n\n// There has to be only one interface and it has to be named `Spec`\n// Only extra allowed definitions are types (probably codegen bug)\nexport interface Spec extends TurboModule {\n addListener: (eventType: string) => void;\n removeListeners: (id: number) => void;\n getNewScreenTimeToDisplay(): Promise<number | undefined | null>;\n addBreadcrumb(breadcrumb: UnsafeObject): void;\n captureEnvelope(\n bytes: string,\n options: {\n hardCrashed: boolean;\n },\n ): Promise<boolean>;\n captureScreenshot(): Promise<NativeScreenshot[] | undefined | null>;\n clearBreadcrumbs(): void;\n crash(): void;\n closeNativeSdk(): Promise<void>;\n disableNativeFramesTracking(): void;\n fetchNativeRelease(): Promise<NativeReleaseResponse>;\n fetchNativeSdkInfo(): Promise<Package | null>;\n fetchNativeDeviceContexts(): Promise<NativeDeviceContextsResponse | null>;\n fetchNativeAppStart(): Promise<NativeAppStartResponse | null>;\n fetchNativeFrames(): Promise<NativeFramesResponse | null>;\n initNativeSdk(options: UnsafeObject): Promise<boolean>;\n setUser(defaultUserKeys: UnsafeObject | null, otherUserKeys: UnsafeObject | null): void;\n setContext(key: string, value: UnsafeObject | null): void;\n setExtra(key: string, value: string): void;\n setTag(key: string, value: string): void;\n enableNativeFramesTracking(): void;\n fetchModules(): Promise<string | undefined | null>;\n fetchViewHierarchy(): Promise<number[] | undefined | null>;\n startProfiling(platformProfilers: boolean): { started?: boolean; error?: string };\n stopProfiling(): {\n profile?: string;\n nativeProfile?: UnsafeObject;\n androidProfile?: UnsafeObject;\n error?: string;\n };\n fetchNativePackageName(): string | undefined | null;\n fetchNativeStackFramesBy(instructionsAddr: number[]): NativeStackFrames | undefined | null;\n initNativeReactNavigationNewFrameTracking(): Promise<void>;\n captureReplay(isHardCrash: boolean): Promise<string | undefined | null>;\n getCurrentReplayId(): string | undefined | null;\n crashedLastRun(): Promise<boolean | undefined | null>;\n getDataFromUri(uri: string): Promise<number[]>;\n popTimeToDisplayFor(key: string): Promise<number | undefined | null>;\n setActiveSpanId(spanId: string): boolean;\n encodeToBase64(data: number[]): Promise<string | undefined | null>;\n}\n\nexport type NativeStackFrame = {\n platform: string;\n /**\n * The instruction address of this frame.\n * Formatted as hex with 0x prefix.\n */\n instruction_addr: string;\n package?: string;\n /**\n * The debug image address of this frame.\n * Formatted as hex with 0x prefix.\n */\n image_addr?: string;\n in_app?: boolean;\n /**\n * The symbol name of this frame.\n * If symbolicated locally.\n */\n function?: string;\n /**\n * The symbol address of this frame.\n * If symbolicated locally.\n * Formatted as hex with 0x prefix.\n */\n symbol_addr?: string;\n};\n\nexport type NativeDebugImage = {\n name?: string;\n type?: string;\n uuid?: string;\n debug_id?: string;\n image_addr?: string;\n image_size?: number;\n code_file?: string;\n image_vmaddr?: string;\n};\n\nexport type NativeStackFrames = {\n frames: NativeStackFrame[];\n debugMetaImages?: NativeDebugImage[];\n};\n\nexport type NativeAppStartResponse = {\n type: 'cold' | 'warm' | 'unknown';\n has_fetched: boolean;\n app_start_timestamp_ms?: number;\n spans: {\n description: string;\n start_timestamp_ms: number;\n end_timestamp_ms: number;\n }[];\n};\n\nexport type NativeFramesResponse = {\n totalFrames: number;\n slowFrames: number;\n frozenFrames: number;\n};\n\nexport type NativeReleaseResponse = {\n build: string;\n id: string;\n version: string;\n};\n\n/**\n * This type describes serialized scope from sentry-cocoa and sentry-android\n * https://github.com/getsentry/sentry-cocoa/blob/master/Sources/Sentry/SentryScope.m\n * https://github.com/getsentry/sentry-java/blob/a461f7e125b65240004e6162b341f383ce2e1394/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java#L32\n */\nexport type NativeDeviceContextsResponse = {\n [key: string]: unknown;\n tags?: Record<string, string>;\n extra?: Record<string, unknown>;\n contexts?: Record<string, Record<string, unknown>>;\n user?: {\n userId?: string;\n email?: string;\n username?: string;\n ipAddress?: string;\n segment?: string;\n data?: Record<string, unknown>;\n };\n dist?: string;\n environment?: string;\n fingerprint?: string[];\n level?: string;\n breadcrumbs?: {\n level?: string;\n timestamp?: string;\n category?: string;\n type?: string;\n message?: string;\n data?: Record<string, unknown>;\n }[];\n};\n\nexport type NativeScreenshot = {\n data: number[];\n contentType: string;\n filename: string;\n};\n\n// The export must be here to pass codegen even if not used\nexport default TurboModuleRegistry.getEnforcing<Spec>('RNSentry');\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { FeedbackButtonProps } from './FeedbackWidget.types';
|
|
3
|
+
/**
|
|
4
|
+
* @beta
|
|
5
|
+
* Implements a feedback button that opens the FeedbackForm.
|
|
6
|
+
*/
|
|
7
|
+
export declare class FeedbackButton extends React.Component<FeedbackButtonProps> {
|
|
8
|
+
private _themeListener;
|
|
9
|
+
constructor(props: FeedbackButtonProps);
|
|
10
|
+
/**
|
|
11
|
+
* Adds a listener for theme changes.
|
|
12
|
+
*/
|
|
13
|
+
componentDidMount(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Removes the theme listener.
|
|
16
|
+
*/
|
|
17
|
+
componentWillUnmount(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Renders the feedback button.
|
|
20
|
+
*/
|
|
21
|
+
render(): React.ReactNode;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=FeedbackButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackButton.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,mBAAmB,EAAyD,MAAM,wBAAwB,CAAC;AAKzH;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC;IACtE,OAAO,CAAC,cAAc,CAA0B;gBAE7B,KAAK,EAAE,mBAAmB;IAK7C;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAMhC;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAMnC;;OAEG;IACI,MAAM,IAAI,KAAK,CAAC,SAAS;CAoBjC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Appearance, Image, Text, TouchableOpacity } from 'react-native';
|
|
3
|
+
import { defaultButtonConfiguration } from './defaults';
|
|
4
|
+
import { defaultButtonStyles } from './FeedbackWidget.styles';
|
|
5
|
+
import { getTheme } from './FeedbackWidget.theme';
|
|
6
|
+
import { showFeedbackWidget } from './FeedbackWidgetManager';
|
|
7
|
+
import { feedbackIcon } from './icons';
|
|
8
|
+
import { lazyLoadFeedbackIntegration } from './lazy';
|
|
9
|
+
/**
|
|
10
|
+
* @beta
|
|
11
|
+
* Implements a feedback button that opens the FeedbackForm.
|
|
12
|
+
*/
|
|
13
|
+
export class FeedbackButton extends React.Component {
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(props);
|
|
16
|
+
lazyLoadFeedbackIntegration();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Adds a listener for theme changes.
|
|
20
|
+
*/
|
|
21
|
+
componentDidMount() {
|
|
22
|
+
this._themeListener = Appearance.addChangeListener(() => {
|
|
23
|
+
this.forceUpdate();
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Removes the theme listener.
|
|
28
|
+
*/
|
|
29
|
+
componentWillUnmount() {
|
|
30
|
+
if (this._themeListener) {
|
|
31
|
+
this._themeListener.remove();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Renders the feedback button.
|
|
36
|
+
*/
|
|
37
|
+
render() {
|
|
38
|
+
var _a, _b, _c;
|
|
39
|
+
const theme = getTheme();
|
|
40
|
+
const text = Object.assign(Object.assign({}, defaultButtonConfiguration), this.props);
|
|
41
|
+
const styles = {
|
|
42
|
+
triggerButton: Object.assign(Object.assign({}, defaultButtonStyles(theme).triggerButton), (_a = this.props.styles) === null || _a === void 0 ? void 0 : _a.triggerButton),
|
|
43
|
+
triggerText: Object.assign(Object.assign({}, defaultButtonStyles(theme).triggerText), (_b = this.props.styles) === null || _b === void 0 ? void 0 : _b.triggerText),
|
|
44
|
+
triggerIcon: Object.assign(Object.assign({}, defaultButtonStyles(theme).triggerIcon), (_c = this.props.styles) === null || _c === void 0 ? void 0 : _c.triggerIcon),
|
|
45
|
+
};
|
|
46
|
+
return (React.createElement(TouchableOpacity, { style: styles.triggerButton, onPress: showFeedbackWidget, accessibilityLabel: text.triggerAriaLabel },
|
|
47
|
+
React.createElement(Image, { source: { uri: feedbackIcon }, style: styles.triggerIcon }),
|
|
48
|
+
React.createElement(Text, { style: styles.triggerText, testID: 'sentry-feedback-button' }, text.triggerLabel)));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=FeedbackButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackButton.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,2BAA2B,EAAE,MAAM,QAAQ,CAAC;AAErD;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK,CAAC,SAA8B;IAGtE,YAAmB,KAA0B;QAC3C,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,2BAA2B,EAAE,CAAC;IAChC,CAAC;IAED;;OAEG;IACI,iBAAiB;QACtB,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE;YACtD,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,oBAAoB;QACzB,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;SAC9B;IACH,CAAC;IAED;;OAEG;IACI,MAAM;;QACX,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,mCAAyC,0BAA0B,GAAK,IAAI,CAAC,KAAK,CAAE,CAAC;QAC/F,MAAM,MAAM,GAAyB;YACnC,aAAa,kCAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,aAAa,GAAK,MAAA,IAAI,CAAC,KAAK,CAAC,MAAM,0CAAE,aAAa,CAAE;YACnG,WAAW,kCAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,WAAW,GAAK,MAAA,IAAI,CAAC,KAAK,CAAC,MAAM,0CAAE,WAAW,CAAE;YAC7F,WAAW,kCAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,WAAW,GAAK,MAAA,IAAI,CAAC,KAAK,CAAC,MAAM,0CAAE,WAAW,CAAE;SAC9F,CAAC;QAEF,OAAO,CACL,oBAAC,gBAAgB,IACf,KAAK,EAAE,MAAM,CAAC,aAAa,EAC3B,OAAO,EAAE,kBAAkB,EAC3B,kBAAkB,EAAE,IAAI,CAAC,gBAAgB;YAEzC,oBAAC,KAAK,IAAC,MAAM,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,GAAG;YAClE,oBAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAC,wBAAwB,IAAE,IAAI,CAAC,YAAY,CAAQ,CAC1E,CACpB,CAAC;IACJ,CAAC;CACF","sourcesContent":["import * as React from 'react';\nimport type { NativeEventSubscription} from 'react-native';\nimport { Appearance, Image, Text, TouchableOpacity } from 'react-native';\n\nimport { defaultButtonConfiguration } from './defaults';\nimport { defaultButtonStyles } from './FeedbackWidget.styles';\nimport { getTheme } from './FeedbackWidget.theme';\nimport type { FeedbackButtonProps, FeedbackButtonStyles, FeedbackButtonTextConfiguration } from './FeedbackWidget.types';\nimport { showFeedbackWidget } from './FeedbackWidgetManager';\nimport { feedbackIcon } from './icons';\nimport { lazyLoadFeedbackIntegration } from './lazy';\n\n/**\n * @beta\n * Implements a feedback button that opens the FeedbackForm.\n */\nexport class FeedbackButton extends React.Component<FeedbackButtonProps> {\n private _themeListener: NativeEventSubscription;\n\n public constructor(props: FeedbackButtonProps) {\n super(props);\n lazyLoadFeedbackIntegration();\n }\n\n /**\n * Adds a listener for theme changes.\n */\n public componentDidMount(): void {\n this._themeListener = Appearance.addChangeListener(() => {\n this.forceUpdate();\n });\n }\n\n /**\n * Removes the theme listener.\n */\n public componentWillUnmount(): void {\n if (this._themeListener) {\n this._themeListener.remove();\n }\n }\n\n /**\n * Renders the feedback button.\n */\n public render(): React.ReactNode {\n const theme = getTheme();\n const text: FeedbackButtonTextConfiguration = { ...defaultButtonConfiguration, ...this.props };\n const styles: FeedbackButtonStyles = {\n triggerButton: { ...defaultButtonStyles(theme).triggerButton, ...this.props.styles?.triggerButton },\n triggerText: { ...defaultButtonStyles(theme).triggerText, ...this.props.styles?.triggerText },\n triggerIcon: { ...defaultButtonStyles(theme).triggerIcon, ...this.props.styles?.triggerIcon },\n };\n\n return (\n <TouchableOpacity\n style={styles.triggerButton}\n onPress={showFeedbackWidget}\n accessibilityLabel={text.triggerAriaLabel}\n >\n <Image source={{ uri: feedbackIcon }} style={styles.triggerIcon}/>\n <Text style={styles.triggerText} testID='sentry-feedback-button'>{text.triggerLabel}</Text>\n </TouchableOpacity>\n );\n }\n}\n"]}
|
|
@@ -7,19 +7,30 @@ import type { FeedbackWidgetProps, FeedbackWidgetState } from './FeedbackWidget.
|
|
|
7
7
|
export declare class FeedbackWidget extends React.Component<FeedbackWidgetProps, FeedbackWidgetState> {
|
|
8
8
|
static defaultProps: Partial<FeedbackWidgetProps>;
|
|
9
9
|
private static _savedState;
|
|
10
|
+
private _themeListener;
|
|
10
11
|
private _didSubmitForm;
|
|
11
12
|
constructor(props: FeedbackWidgetProps);
|
|
13
|
+
/**
|
|
14
|
+
* For testing purposes only.
|
|
15
|
+
*/
|
|
16
|
+
static reset(): void;
|
|
12
17
|
handleFeedbackSubmit: () => void;
|
|
13
18
|
onScreenshotButtonPress: () => void;
|
|
14
19
|
/**
|
|
15
|
-
*
|
|
20
|
+
* Add a listener to the theme change event.
|
|
21
|
+
*/
|
|
22
|
+
componentDidMount(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Save the state before unmounting the component and remove the theme listener.
|
|
16
25
|
*/
|
|
17
26
|
componentWillUnmount(): void;
|
|
18
27
|
/**
|
|
19
28
|
* Renders the feedback form screen.
|
|
20
29
|
*/
|
|
21
30
|
render(): React.ReactNode;
|
|
31
|
+
private _setCapturedScreenshot;
|
|
22
32
|
private _saveFormState;
|
|
23
33
|
private _clearFormState;
|
|
34
|
+
private _hasScreenshot;
|
|
24
35
|
}
|
|
25
36
|
//# sourceMappingURL=FeedbackWidget.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackWidget.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidget.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FeedbackWidget.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidget.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAqB/B,OAAO,KAAK,EAA2D,mBAAmB,EAAE,mBAAmB,EAAkD,MAAM,wBAAwB,CAAC;AAMhM;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK,CAAC,SAAS,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAC3F,OAAc,YAAY,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAEvD;IAED,OAAO,CAAC,MAAM,CAAC,WAAW,CAOxB;IAEF,OAAO,CAAC,cAAc,CAA0B;IAEhD,OAAO,CAAC,cAAc,CAAkB;gBAErB,KAAK,EAAE,mBAAmB;IAuB7C;;OAEG;WACW,KAAK,IAAI,IAAI;IAWpB,oBAAoB,EAAE,MAAM,IAAI,CAmDrC;IAEK,uBAAuB,EAAE,MAAM,IAAI,CAmEzC;IAED;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAMhC;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAYnC;;OAEG;IACI,MAAM,IAAI,KAAK,CAAC,SAAS;IAkIhC,OAAO,CAAC,sBAAsB,CAgB7B;IAED,OAAO,CAAC,cAAc,CAEpB;IAEF,OAAO,CAAC,eAAe,CASrB;IAEF,OAAO,CAAC,cAAc,CAErB;CACF"}
|
|
@@ -9,13 +9,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { captureFeedback, getCurrentScope, lastEventId, logger } from '@sentry/core';
|
|
11
11
|
import * as React from 'react';
|
|
12
|
-
import { Image, Keyboard, Text, TextInput, TouchableOpacity, TouchableWithoutFeedback, View } from 'react-native';
|
|
12
|
+
import { Appearance, Image, Keyboard, Text, TextInput, TouchableOpacity, TouchableWithoutFeedback, View } from 'react-native';
|
|
13
13
|
import { isWeb, notWeb } from '../utils/environment';
|
|
14
|
-
import { getDataFromUri } from '../wrapper';
|
|
14
|
+
import { getDataFromUri, NATIVE } from '../wrapper';
|
|
15
15
|
import { sentryLogo } from './branding';
|
|
16
16
|
import { defaultConfiguration } from './defaults';
|
|
17
17
|
import defaultStyles from './FeedbackWidget.styles';
|
|
18
|
+
import { getTheme } from './FeedbackWidget.theme';
|
|
19
|
+
import { hideFeedbackButton, showScreenshotButton } from './FeedbackWidgetManager';
|
|
18
20
|
import { lazyLoadFeedbackIntegration } from './lazy';
|
|
21
|
+
import { getCapturedScreenshot } from './ScreenshotButton';
|
|
19
22
|
import { base64ToUint8Array, feedbackAlertDialog, isValidEmail } from './utils';
|
|
20
23
|
/**
|
|
21
24
|
* @beta
|
|
@@ -74,7 +77,7 @@ export class FeedbackWidget extends React.Component {
|
|
|
74
77
|
}
|
|
75
78
|
};
|
|
76
79
|
this.onScreenshotButtonPress = () => __awaiter(this, void 0, void 0, function* () {
|
|
77
|
-
if (!this.
|
|
80
|
+
if (!this._hasScreenshot()) {
|
|
78
81
|
const imagePickerConfiguration = this.props;
|
|
79
82
|
if (imagePickerConfiguration.imagePicker) {
|
|
80
83
|
const launchImageLibrary = imagePickerConfiguration.imagePicker.launchImageLibraryAsync
|
|
@@ -143,6 +146,25 @@ export class FeedbackWidget extends React.Component {
|
|
|
143
146
|
this.setState({ filename: undefined, attachment: undefined, attachmentUri: undefined });
|
|
144
147
|
}
|
|
145
148
|
});
|
|
149
|
+
this._setCapturedScreenshot = (screenshot) => {
|
|
150
|
+
if (screenshot.data != null) {
|
|
151
|
+
logger.debug('Setting captured screenshot:', screenshot.filename);
|
|
152
|
+
NATIVE.encodeToBase64(screenshot.data).then((base64String) => {
|
|
153
|
+
if (base64String != null) {
|
|
154
|
+
const dataUri = `data:${screenshot.contentType};base64,${base64String}`;
|
|
155
|
+
this.setState({ filename: screenshot.filename, attachment: screenshot.data, attachmentUri: dataUri });
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
logger.error('Failed to read image data from:', screenshot.filename);
|
|
159
|
+
}
|
|
160
|
+
}).catch((error) => {
|
|
161
|
+
logger.error('Failed to read image data from:', screenshot.filename, 'error: ', error);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
logger.error('Failed to read image data from:', screenshot.filename);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
146
168
|
this._saveFormState = () => {
|
|
147
169
|
FeedbackWidget._savedState = Object.assign({}, this.state);
|
|
148
170
|
};
|
|
@@ -156,6 +178,9 @@ export class FeedbackWidget extends React.Component {
|
|
|
156
178
|
attachmentUri: undefined,
|
|
157
179
|
};
|
|
158
180
|
};
|
|
181
|
+
this._hasScreenshot = () => {
|
|
182
|
+
return this.state.filename !== undefined && this.state.attachment !== undefined && this.state.attachmentUri !== undefined;
|
|
183
|
+
};
|
|
159
184
|
const currentUser = {
|
|
160
185
|
useSentryUser: {
|
|
161
186
|
email: ((_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.useSentryUser) === null || _b === void 0 ? void 0 : _b.email) || ((_d = (_c = getCurrentScope()) === null || _c === void 0 ? void 0 : _c.getUser()) === null || _d === void 0 ? void 0 : _d.email) || '',
|
|
@@ -174,7 +199,28 @@ export class FeedbackWidget extends React.Component {
|
|
|
174
199
|
lazyLoadFeedbackIntegration();
|
|
175
200
|
}
|
|
176
201
|
/**
|
|
177
|
-
*
|
|
202
|
+
* For testing purposes only.
|
|
203
|
+
*/
|
|
204
|
+
static reset() {
|
|
205
|
+
FeedbackWidget._savedState = {
|
|
206
|
+
name: '',
|
|
207
|
+
email: '',
|
|
208
|
+
description: '',
|
|
209
|
+
filename: undefined,
|
|
210
|
+
attachment: undefined,
|
|
211
|
+
attachmentUri: undefined,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Add a listener to the theme change event.
|
|
216
|
+
*/
|
|
217
|
+
componentDidMount() {
|
|
218
|
+
this._themeListener = Appearance.addChangeListener(() => {
|
|
219
|
+
this.forceUpdate();
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Save the state before unmounting the component and remove the theme listener.
|
|
178
224
|
*/
|
|
179
225
|
componentWillUnmount() {
|
|
180
226
|
if (this._didSubmitForm) {
|
|
@@ -184,17 +230,21 @@ export class FeedbackWidget extends React.Component {
|
|
|
184
230
|
else {
|
|
185
231
|
this._saveFormState();
|
|
186
232
|
}
|
|
233
|
+
if (this._themeListener) {
|
|
234
|
+
this._themeListener.remove();
|
|
235
|
+
}
|
|
187
236
|
}
|
|
188
237
|
/**
|
|
189
238
|
* Renders the feedback form screen.
|
|
190
239
|
*/
|
|
191
240
|
render() {
|
|
241
|
+
const theme = getTheme();
|
|
192
242
|
const { name, email, description } = this.state;
|
|
193
243
|
const { onFormClose } = this.props;
|
|
194
244
|
const config = this.props;
|
|
195
245
|
const imagePickerConfiguration = this.props;
|
|
196
246
|
const text = this.props;
|
|
197
|
-
const styles = Object.assign(Object.assign({}, defaultStyles), this.props.styles);
|
|
247
|
+
const styles = Object.assign(Object.assign({}, defaultStyles(theme)), this.props.styles);
|
|
198
248
|
const onCancel = () => {
|
|
199
249
|
if (onFormClose) {
|
|
200
250
|
onFormClose();
|
|
@@ -206,33 +256,48 @@ export class FeedbackWidget extends React.Component {
|
|
|
206
256
|
if (!this.state.isVisible) {
|
|
207
257
|
return null;
|
|
208
258
|
}
|
|
209
|
-
|
|
259
|
+
const screenshot = getCapturedScreenshot();
|
|
260
|
+
if (screenshot === 'ErrorCapturingScreenshot') {
|
|
261
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
262
|
+
feedbackAlertDialog(text.errorTitle, text.captureScreenshotError);
|
|
263
|
+
}), 100);
|
|
264
|
+
}
|
|
265
|
+
else if (screenshot) {
|
|
266
|
+
this._setCapturedScreenshot(screenshot);
|
|
267
|
+
}
|
|
268
|
+
return (React.createElement(TouchableWithoutFeedback, { onPress: notWeb() ? Keyboard.dismiss : undefined, accessible: false, accessibilityElementsHidden: false },
|
|
210
269
|
React.createElement(View, { style: styles.container },
|
|
211
270
|
React.createElement(View, { style: styles.titleContainer },
|
|
212
|
-
React.createElement(Text, { style: styles.title }, text.formTitle),
|
|
271
|
+
React.createElement(Text, { style: styles.title, testID: 'sentry-feedback-form-title' }, text.formTitle),
|
|
213
272
|
config.showBranding && (React.createElement(Image, { source: { uri: sentryLogo }, style: styles.sentryLogo, testID: 'sentry-logo' }))),
|
|
214
273
|
config.showName && (React.createElement(React.Fragment, null,
|
|
215
274
|
React.createElement(Text, { style: styles.label },
|
|
216
275
|
text.nameLabel,
|
|
217
276
|
config.isNameRequired && ` ${text.isRequiredLabel}`),
|
|
218
|
-
React.createElement(TextInput, { style: styles.input, placeholder: text.namePlaceholder, value: name, onChangeText: (value) => this.setState({ name: value }) }))),
|
|
277
|
+
React.createElement(TextInput, { style: styles.input, testID: 'sentry-feedback-name-input', placeholder: text.namePlaceholder, value: name, onChangeText: (value) => this.setState({ name: value }) }))),
|
|
219
278
|
config.showEmail && (React.createElement(React.Fragment, null,
|
|
220
279
|
React.createElement(Text, { style: styles.label },
|
|
221
280
|
text.emailLabel,
|
|
222
281
|
config.isEmailRequired && ` ${text.isRequiredLabel}`),
|
|
223
|
-
React.createElement(TextInput, { style: styles.input, placeholder: text.emailPlaceholder, keyboardType: 'email-address', value: email, onChangeText: (value) => this.setState({ email: value }) }))),
|
|
282
|
+
React.createElement(TextInput, { style: styles.input, testID: 'sentry-feedback-email-input', placeholder: text.emailPlaceholder, keyboardType: 'email-address', value: email, onChangeText: (value) => this.setState({ email: value }) }))),
|
|
224
283
|
React.createElement(Text, { style: styles.label },
|
|
225
284
|
text.messageLabel,
|
|
226
285
|
` ${text.isRequiredLabel}`),
|
|
227
|
-
React.createElement(TextInput, { style: [styles.input, styles.textArea], placeholder: text.messagePlaceholder, value: description, onChangeText: (value) => this.setState({ description: value }), multiline: true }),
|
|
228
|
-
(config.enableScreenshot || imagePickerConfiguration.imagePicker) && (React.createElement(View, { style: styles.screenshotContainer },
|
|
286
|
+
React.createElement(TextInput, { style: [styles.input, styles.textArea], testID: 'sentry-feedback-message-input', placeholder: text.messagePlaceholder, value: description, onChangeText: (value) => this.setState({ description: value }), multiline: true }),
|
|
287
|
+
(config.enableScreenshot || imagePickerConfiguration.imagePicker || this._hasScreenshot()) && (React.createElement(View, { style: styles.screenshotContainer },
|
|
229
288
|
this.state.attachmentUri && (React.createElement(Image, { source: { uri: this.state.attachmentUri }, style: styles.screenshotThumbnail })),
|
|
230
289
|
React.createElement(TouchableOpacity, { style: styles.screenshotButton, onPress: this.onScreenshotButtonPress },
|
|
231
|
-
React.createElement(Text, { style: styles.screenshotText }, !this.
|
|
290
|
+
React.createElement(Text, { style: styles.screenshotText }, !this._hasScreenshot()
|
|
232
291
|
? text.addScreenshotButtonLabel
|
|
233
292
|
: text.removeScreenshotButtonLabel)))),
|
|
293
|
+
notWeb() && config.enableTakeScreenshot && !this.state.attachmentUri && (React.createElement(TouchableOpacity, { style: styles.takeScreenshotButton, onPress: () => {
|
|
294
|
+
hideFeedbackButton();
|
|
295
|
+
onCancel();
|
|
296
|
+
showScreenshotButton();
|
|
297
|
+
} },
|
|
298
|
+
React.createElement(Text, { style: styles.takeScreenshotText }, text.captureScreenshotButtonLabel))),
|
|
234
299
|
React.createElement(TouchableOpacity, { style: styles.submitButton, onPress: this.handleFeedbackSubmit },
|
|
235
|
-
React.createElement(Text, { style: styles.submitText }, text.submitButtonLabel)),
|
|
300
|
+
React.createElement(Text, { style: styles.submitText, testID: 'sentry-feedback-submit-button' }, text.submitButtonLabel)),
|
|
236
301
|
React.createElement(TouchableOpacity, { style: styles.cancelButton, onPress: onCancel },
|
|
237
302
|
React.createElement(Text, { style: styles.cancelText }, text.cancelButtonLabel)))));
|
|
238
303
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackWidget.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidget.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { SendFeedbackParams } from '@sentry/core';\nimport { captureFeedback, getCurrentScope, lastEventId, logger } from '@sentry/core';\nimport * as React from 'react';\nimport type { KeyboardTypeOptions } from 'react-native';\nimport {\n Image,\n Keyboard,\n Text,\n TextInput,\n TouchableOpacity,\n TouchableWithoutFeedback,\n View\n} from 'react-native';\n\nimport { isWeb, notWeb } from '../utils/environment';\nimport { getDataFromUri } from '../wrapper';\nimport { sentryLogo } from './branding';\nimport { defaultConfiguration } from './defaults';\nimport defaultStyles from './FeedbackWidget.styles';\nimport type { FeedbackGeneralConfiguration, FeedbackTextConfiguration, FeedbackWidgetProps, FeedbackWidgetState, FeedbackWidgetStyles, ImagePickerConfiguration } from './FeedbackWidget.types';\nimport { lazyLoadFeedbackIntegration } from './lazy';\nimport { base64ToUint8Array, feedbackAlertDialog, isValidEmail } from './utils';\n\n/**\n * @beta\n * Implements a feedback form screen that sends feedback to Sentry using Sentry.captureFeedback.\n */\nexport class FeedbackWidget extends React.Component<FeedbackWidgetProps, FeedbackWidgetState> {\n public static defaultProps: Partial<FeedbackWidgetProps> = {\n ...defaultConfiguration\n }\n\n private static _savedState: Omit<FeedbackWidgetState, 'isVisible'> = {\n name: '',\n email: '',\n description: '',\n filename: undefined,\n attachment: undefined,\n attachmentUri: undefined,\n };\n\n private _didSubmitForm: boolean = false;\n\n public constructor(props: FeedbackWidgetProps) {\n super(props);\n\n const currentUser = {\n useSentryUser: {\n email: this.props?.useSentryUser?.email || getCurrentScope()?.getUser()?.email || '',\n name: this.props?.useSentryUser?.name || getCurrentScope()?.getUser()?.name || '',\n }\n }\n\n this.state = {\n isVisible: true,\n name: FeedbackWidget._savedState.name || currentUser.useSentryUser.name,\n email: FeedbackWidget._savedState.email || currentUser.useSentryUser.email,\n description: FeedbackWidget._savedState.description || '',\n filename: FeedbackWidget._savedState.filename || undefined,\n attachment: FeedbackWidget._savedState.attachment || undefined,\n attachmentUri: FeedbackWidget._savedState.attachmentUri || undefined,\n };\n\n lazyLoadFeedbackIntegration();\n }\n\n public handleFeedbackSubmit: () => void = () => {\n const { name, email, description } = this.state;\n const { onSubmitSuccess, onSubmitError, onFormSubmitted } = this.props;\n const text: FeedbackTextConfiguration = this.props;\n\n const trimmedName = name?.trim();\n const trimmedEmail = email?.trim();\n const trimmedDescription = description?.trim();\n\n if ((this.props.isNameRequired && !trimmedName) || (this.props.isEmailRequired && !trimmedEmail) || !trimmedDescription) {\n feedbackAlertDialog(text.errorTitle, text.formError);\n return;\n }\n\n if (this.props.shouldValidateEmail && (this.props.isEmailRequired || trimmedEmail.length > 0) && !isValidEmail(trimmedEmail)) {\n feedbackAlertDialog(text.errorTitle, text.emailError);\n return;\n }\n\n const attachments = this.state.filename && this.state.attachment\n ? [\n {\n filename: this.state.filename,\n data: this.state.attachment,\n },\n ]\n : undefined;\n\n const eventId = lastEventId();\n const userFeedback: SendFeedbackParams = {\n message: trimmedDescription,\n name: trimmedName,\n email: trimmedEmail,\n associatedEventId: eventId,\n };\n\n try {\n if (!onFormSubmitted) {\n this.setState({ isVisible: false });\n }\n captureFeedback(userFeedback, attachments ? { attachments } : undefined);\n onSubmitSuccess({ name: trimmedName, email: trimmedEmail, message: trimmedDescription, attachments: attachments });\n feedbackAlertDialog(text.successMessageText , '');\n onFormSubmitted();\n this._didSubmitForm = true;\n } catch (error) {\n const errorString = `Feedback form submission failed: ${error}`;\n onSubmitError(new Error(errorString));\n feedbackAlertDialog(text.errorTitle, text.genericError);\n logger.error(`Feedback form submission failed: ${error}`);\n }\n };\n\n public onScreenshotButtonPress: () => void = async () => {\n if (!this.state.filename && !this.state.attachment) {\n const imagePickerConfiguration: ImagePickerConfiguration = this.props;\n if (imagePickerConfiguration.imagePicker) {\n const launchImageLibrary = imagePickerConfiguration.imagePicker.launchImageLibraryAsync\n // expo-image-picker library is available\n ? () => imagePickerConfiguration.imagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], base64: isWeb() })\n // react-native-image-picker library is available\n : imagePickerConfiguration.imagePicker.launchImageLibrary\n ? () => imagePickerConfiguration.imagePicker.launchImageLibrary({ mediaType: 'photo', includeBase64: isWeb() })\n : null;\n if (!launchImageLibrary) {\n logger.warn('No compatible image picker library found. Please provide a valid image picker library.');\n if (__DEV__) {\n feedbackAlertDialog(\n 'Development note',\n 'No compatible image picker library found. Please provide a compatible version of `expo-image-picker` or `react-native-image-picker`.',\n );\n }\n return;\n }\n\n const result = await launchImageLibrary();\n if (result.assets && result.assets.length > 0) {\n if (isWeb()) {\n const filename = result.assets[0].fileName;\n const imageUri = result.assets[0].uri;\n const base64 = result.assets[0].base64;\n const data = base64ToUint8Array(base64);\n if (data != null) {\n this.setState({ filename, attachment: data, attachmentUri: imageUri });\n } else {\n logger.error('Failed to read image data on the web');\n }\n } else {\n const filename = result.assets[0].fileName;\n const imageUri = result.assets[0].uri;\n getDataFromUri(imageUri).then((data) => {\n if (data != null) {\n this.setState({ filename, attachment: data, attachmentUri: imageUri });\n } else {\n logger.error('Failed to read image data from uri:', imageUri);\n }\n }).catch((error) => {\n logger.error('Failed to read image data from uri:', imageUri, 'error: ', error);\n });\n }\n }\n } else {\n // Defaulting to the onAddScreenshot callback\n const { onAddScreenshot } = { ...defaultConfiguration, ...this.props };\n onAddScreenshot((uri: string) => {\n getDataFromUri(uri).then((data) => {\n if (data != null) {\n this.setState({ filename: 'feedback_screenshot', attachment: data, attachmentUri: uri });\n } else {\n logger.error('Failed to read image data from uri:', uri);\n }\n })\n .catch((error) => {\n logger.error('Failed to read image data from uri:', uri, 'error: ', error);\n });\n });\n }\n } else {\n this.setState({ filename: undefined, attachment: undefined, attachmentUri: undefined });\n }\n }\n\n /**\n * Save the state before unmounting the component.\n */\n public componentWillUnmount(): void {\n if (this._didSubmitForm) {\n this._clearFormState();\n this._didSubmitForm = false;\n } else {\n this._saveFormState();\n }\n }\n\n /**\n * Renders the feedback form screen.\n */\n public render(): React.ReactNode {\n const { name, email, description } = this.state;\n const { onFormClose } = this.props;\n const config: FeedbackGeneralConfiguration = this.props;\n const imagePickerConfiguration: ImagePickerConfiguration = this.props;\n const text: FeedbackTextConfiguration = this.props;\n const styles: FeedbackWidgetStyles = { ...defaultStyles, ...this.props.styles };\n const onCancel = (): void => {\n if (onFormClose) {\n onFormClose();\n } else {\n this.setState({ isVisible: false });\n }\n }\n\n if (!this.state.isVisible) {\n return null;\n }\n\n return (\n <TouchableWithoutFeedback onPress={notWeb() ? Keyboard.dismiss: undefined}>\n <View style={styles.container}>\n <View style={styles.titleContainer}>\n <Text style={styles.title}>{text.formTitle}</Text>\n {config.showBranding && (\n <Image\n source={{ uri: sentryLogo }}\n style={styles.sentryLogo}\n testID='sentry-logo'\n />\n )}\n </View>\n\n {config.showName && (\n <>\n <Text style={styles.label}>\n {text.nameLabel}\n {config.isNameRequired && ` ${text.isRequiredLabel}`}\n </Text>\n <TextInput\n style={styles.input}\n placeholder={text.namePlaceholder}\n value={name}\n onChangeText={(value) => this.setState({ name: value })}\n />\n </>\n )}\n\n {config.showEmail && (\n <>\n <Text style={styles.label}>\n {text.emailLabel}\n {config.isEmailRequired && ` ${text.isRequiredLabel}`}\n </Text>\n <TextInput\n style={styles.input}\n placeholder={text.emailPlaceholder}\n keyboardType={'email-address' as KeyboardTypeOptions}\n value={email}\n onChangeText={(value) => this.setState({ email: value })}\n />\n </>\n )}\n\n <Text style={styles.label}>\n {text.messageLabel}\n {` ${text.isRequiredLabel}`}\n </Text>\n <TextInput\n style={[styles.input, styles.textArea]}\n placeholder={text.messagePlaceholder}\n value={description}\n onChangeText={(value) => this.setState({ description: value })}\n multiline\n />\n {(config.enableScreenshot || imagePickerConfiguration.imagePicker) && (\n <View style={styles.screenshotContainer}>\n {this.state.attachmentUri && (\n <Image\n source={{ uri: this.state.attachmentUri }}\n style={styles.screenshotThumbnail}\n />\n )}\n <TouchableOpacity style={styles.screenshotButton} onPress={this.onScreenshotButtonPress}>\n <Text style={styles.screenshotText}>\n {!this.state.filename && !this.state.attachment\n ? text.addScreenshotButtonLabel\n : text.removeScreenshotButtonLabel}\n </Text>\n </TouchableOpacity>\n </View>\n )}\n <TouchableOpacity style={styles.submitButton} onPress={this.handleFeedbackSubmit}>\n <Text style={styles.submitText}>{text.submitButtonLabel}</Text>\n </TouchableOpacity>\n\n <TouchableOpacity style={styles.cancelButton} onPress={onCancel}>\n <Text style={styles.cancelText}>{text.cancelButtonLabel}</Text>\n </TouchableOpacity>\n </View>\n </TouchableWithoutFeedback>\n );\n }\n\n private _saveFormState = (): void => {\n FeedbackWidget._savedState = { ...this.state };\n };\n\n private _clearFormState = (): void => {\n FeedbackWidget._savedState = {\n name: '',\n email: '',\n description: '',\n filename: undefined,\n attachment: undefined,\n attachmentUri: undefined,\n };\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FeedbackWidget.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidget.tsx"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport type { SendFeedbackParams } from '@sentry/core';\nimport { captureFeedback, getCurrentScope, lastEventId, logger } from '@sentry/core';\nimport * as React from 'react';\nimport type { KeyboardTypeOptions ,\n NativeEventSubscription} from 'react-native';\nimport {\n Appearance,\n Image,\n Keyboard,\n Text,\n TextInput,\n TouchableOpacity,\n TouchableWithoutFeedback,\n View\n} from 'react-native';\n\nimport { isWeb, notWeb } from '../utils/environment';\nimport type { Screenshot } from '../wrapper';\nimport { getDataFromUri, NATIVE } from '../wrapper';\nimport { sentryLogo } from './branding';\nimport { defaultConfiguration } from './defaults';\nimport defaultStyles from './FeedbackWidget.styles';\nimport { getTheme } from './FeedbackWidget.theme';\nimport type { FeedbackGeneralConfiguration, FeedbackTextConfiguration, FeedbackWidgetProps, FeedbackWidgetState, FeedbackWidgetStyles, ImagePickerConfiguration } from './FeedbackWidget.types';\nimport { hideFeedbackButton, showScreenshotButton } from './FeedbackWidgetManager';\nimport { lazyLoadFeedbackIntegration } from './lazy';\nimport { getCapturedScreenshot } from './ScreenshotButton';\nimport { base64ToUint8Array, feedbackAlertDialog, isValidEmail } from './utils';\n\n/**\n * @beta\n * Implements a feedback form screen that sends feedback to Sentry using Sentry.captureFeedback.\n */\nexport class FeedbackWidget extends React.Component<FeedbackWidgetProps, FeedbackWidgetState> {\n public static defaultProps: Partial<FeedbackWidgetProps> = {\n ...defaultConfiguration\n }\n\n private static _savedState: Omit<FeedbackWidgetState, 'isVisible'> = {\n name: '',\n email: '',\n description: '',\n filename: undefined,\n attachment: undefined,\n attachmentUri: undefined,\n };\n\n private _themeListener: NativeEventSubscription;\n\n private _didSubmitForm: boolean = false;\n\n public constructor(props: FeedbackWidgetProps) {\n super(props);\n\n const currentUser = {\n useSentryUser: {\n email: this.props?.useSentryUser?.email || getCurrentScope()?.getUser()?.email || '',\n name: this.props?.useSentryUser?.name || getCurrentScope()?.getUser()?.name || '',\n }\n }\n\n this.state = {\n isVisible: true,\n name: FeedbackWidget._savedState.name || currentUser.useSentryUser.name,\n email: FeedbackWidget._savedState.email || currentUser.useSentryUser.email,\n description: FeedbackWidget._savedState.description || '',\n filename: FeedbackWidget._savedState.filename || undefined,\n attachment: FeedbackWidget._savedState.attachment || undefined,\n attachmentUri: FeedbackWidget._savedState.attachmentUri || undefined,\n };\n\n lazyLoadFeedbackIntegration();\n }\n\n /**\n * For testing purposes only.\n */\n public static reset(): void {\n FeedbackWidget._savedState = {\n name: '',\n email: '',\n description: '',\n filename: undefined,\n attachment: undefined,\n attachmentUri: undefined,\n };\n }\n\n public handleFeedbackSubmit: () => void = () => {\n const { name, email, description } = this.state;\n const { onSubmitSuccess, onSubmitError, onFormSubmitted } = this.props;\n const text: FeedbackTextConfiguration = this.props;\n\n const trimmedName = name?.trim();\n const trimmedEmail = email?.trim();\n const trimmedDescription = description?.trim();\n\n if ((this.props.isNameRequired && !trimmedName) || (this.props.isEmailRequired && !trimmedEmail) || !trimmedDescription) {\n feedbackAlertDialog(text.errorTitle, text.formError);\n return;\n }\n\n if (this.props.shouldValidateEmail && (this.props.isEmailRequired || trimmedEmail.length > 0) && !isValidEmail(trimmedEmail)) {\n feedbackAlertDialog(text.errorTitle, text.emailError);\n return;\n }\n\n const attachments = this.state.filename && this.state.attachment\n ? [\n {\n filename: this.state.filename,\n data: this.state.attachment,\n },\n ]\n : undefined;\n\n const eventId = lastEventId();\n const userFeedback: SendFeedbackParams = {\n message: trimmedDescription,\n name: trimmedName,\n email: trimmedEmail,\n associatedEventId: eventId,\n };\n\n try {\n if (!onFormSubmitted) {\n this.setState({ isVisible: false });\n }\n captureFeedback(userFeedback, attachments ? { attachments } : undefined);\n onSubmitSuccess({ name: trimmedName, email: trimmedEmail, message: trimmedDescription, attachments: attachments });\n feedbackAlertDialog(text.successMessageText , '');\n onFormSubmitted();\n this._didSubmitForm = true;\n } catch (error) {\n const errorString = `Feedback form submission failed: ${error}`;\n onSubmitError(new Error(errorString));\n feedbackAlertDialog(text.errorTitle, text.genericError);\n logger.error(`Feedback form submission failed: ${error}`);\n }\n };\n\n public onScreenshotButtonPress: () => void = async () => {\n if (!this._hasScreenshot()) {\n const imagePickerConfiguration: ImagePickerConfiguration = this.props;\n if (imagePickerConfiguration.imagePicker) {\n const launchImageLibrary = imagePickerConfiguration.imagePicker.launchImageLibraryAsync\n // expo-image-picker library is available\n ? () => imagePickerConfiguration.imagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], base64: isWeb() })\n // react-native-image-picker library is available\n : imagePickerConfiguration.imagePicker.launchImageLibrary\n ? () => imagePickerConfiguration.imagePicker.launchImageLibrary({ mediaType: 'photo', includeBase64: isWeb() })\n : null;\n if (!launchImageLibrary) {\n logger.warn('No compatible image picker library found. Please provide a valid image picker library.');\n if (__DEV__) {\n feedbackAlertDialog(\n 'Development note',\n 'No compatible image picker library found. Please provide a compatible version of `expo-image-picker` or `react-native-image-picker`.',\n );\n }\n return;\n }\n\n const result = await launchImageLibrary();\n if (result.assets && result.assets.length > 0) {\n if (isWeb()) {\n const filename = result.assets[0].fileName;\n const imageUri = result.assets[0].uri;\n const base64 = result.assets[0].base64;\n const data = base64ToUint8Array(base64);\n if (data != null) {\n this.setState({ filename, attachment: data, attachmentUri: imageUri });\n } else {\n logger.error('Failed to read image data on the web');\n }\n } else {\n const filename = result.assets[0].fileName;\n const imageUri = result.assets[0].uri;\n getDataFromUri(imageUri).then((data) => {\n if (data != null) {\n this.setState({ filename, attachment: data, attachmentUri: imageUri });\n } else {\n logger.error('Failed to read image data from uri:', imageUri);\n }\n }).catch((error) => {\n logger.error('Failed to read image data from uri:', imageUri, 'error: ', error);\n });\n }\n }\n } else {\n // Defaulting to the onAddScreenshot callback\n const { onAddScreenshot } = { ...defaultConfiguration, ...this.props };\n onAddScreenshot((uri: string) => {\n getDataFromUri(uri).then((data) => {\n if (data != null) {\n this.setState({ filename: 'feedback_screenshot', attachment: data, attachmentUri: uri });\n } else {\n logger.error('Failed to read image data from uri:', uri);\n }\n })\n .catch((error) => {\n logger.error('Failed to read image data from uri:', uri, 'error: ', error);\n });\n });\n }\n } else {\n this.setState({ filename: undefined, attachment: undefined, attachmentUri: undefined });\n }\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 * Save the state before unmounting the component and remove the theme listener.\n */\n public componentWillUnmount(): void {\n if (this._didSubmitForm) {\n this._clearFormState();\n this._didSubmitForm = false;\n } else {\n this._saveFormState();\n }\n if (this._themeListener) {\n this._themeListener.remove();\n }\n }\n\n /**\n * Renders the feedback form screen.\n */\n public render(): React.ReactNode {\n const theme = getTheme();\n const { name, email, description } = this.state;\n const { onFormClose } = this.props;\n const config: FeedbackGeneralConfiguration = this.props;\n const imagePickerConfiguration: ImagePickerConfiguration = this.props;\n const text: FeedbackTextConfiguration = this.props;\n const styles: FeedbackWidgetStyles = { ...defaultStyles(theme), ...this.props.styles };\n const onCancel = (): void => {\n if (onFormClose) {\n onFormClose();\n } else {\n this.setState({ isVisible: false });\n }\n }\n\n if (!this.state.isVisible) {\n return null;\n }\n\n const screenshot = getCapturedScreenshot();\n if (screenshot === 'ErrorCapturingScreenshot') {\n setTimeout(async () => {\n feedbackAlertDialog(text.errorTitle, text.captureScreenshotError);\n }, 100);\n } else if (screenshot) {\n this._setCapturedScreenshot(screenshot);\n }\n\n return (\n <TouchableWithoutFeedback\n onPress={notWeb() ? Keyboard.dismiss : undefined}\n accessible={false}\n accessibilityElementsHidden={false}\n >\n <View style={styles.container}>\n <View style={styles.titleContainer}>\n <Text style={styles.title} testID='sentry-feedback-form-title'>{text.formTitle}</Text>\n {config.showBranding && (\n <Image\n source={{ uri: sentryLogo }}\n style={styles.sentryLogo}\n testID='sentry-logo'\n />\n )}\n </View>\n\n {config.showName && (\n <>\n <Text style={styles.label}>\n {text.nameLabel}\n {config.isNameRequired && ` ${text.isRequiredLabel}`}\n </Text>\n <TextInput\n style={styles.input}\n testID='sentry-feedback-name-input'\n placeholder={text.namePlaceholder}\n value={name}\n onChangeText={(value) => this.setState({ name: value })}\n />\n </>\n )}\n\n {config.showEmail && (\n <>\n <Text style={styles.label}>\n {text.emailLabel}\n {config.isEmailRequired && ` ${text.isRequiredLabel}`}\n </Text>\n <TextInput\n style={styles.input}\n testID='sentry-feedback-email-input'\n placeholder={text.emailPlaceholder}\n keyboardType={'email-address' as KeyboardTypeOptions}\n value={email}\n onChangeText={(value) => this.setState({ email: value })}\n />\n </>\n )}\n\n <Text style={styles.label}>\n {text.messageLabel}\n {` ${text.isRequiredLabel}`}\n </Text>\n <TextInput\n style={[styles.input, styles.textArea]}\n testID='sentry-feedback-message-input'\n placeholder={text.messagePlaceholder}\n value={description}\n onChangeText={(value) => this.setState({ description: value })}\n multiline\n />\n {(config.enableScreenshot || imagePickerConfiguration.imagePicker || this._hasScreenshot()) && (\n <View style={styles.screenshotContainer}>\n {this.state.attachmentUri && (\n <Image\n source={{ uri: this.state.attachmentUri }}\n style={styles.screenshotThumbnail}\n />\n )}\n <TouchableOpacity style={styles.screenshotButton} onPress={this.onScreenshotButtonPress}>\n <Text style={styles.screenshotText}>\n {!this._hasScreenshot()\n ? text.addScreenshotButtonLabel\n : text.removeScreenshotButtonLabel}\n </Text>\n </TouchableOpacity>\n </View>\n )}\n {notWeb() && config.enableTakeScreenshot && !this.state.attachmentUri && (\n <TouchableOpacity style={styles.takeScreenshotButton} onPress={() => {\n hideFeedbackButton();\n onCancel();\n showScreenshotButton();\n }}>\n <Text style={styles.takeScreenshotText}>{text.captureScreenshotButtonLabel}</Text>\n </TouchableOpacity>\n )}\n <TouchableOpacity style={styles.submitButton} onPress={this.handleFeedbackSubmit}>\n <Text style={styles.submitText} testID='sentry-feedback-submit-button'>{text.submitButtonLabel}</Text>\n </TouchableOpacity>\n\n <TouchableOpacity style={styles.cancelButton} onPress={onCancel}>\n <Text style={styles.cancelText}>{text.cancelButtonLabel}</Text>\n </TouchableOpacity>\n </View>\n </TouchableWithoutFeedback>\n );\n }\n\n private _setCapturedScreenshot = (screenshot: Screenshot): void => {\n if (screenshot.data != null) {\n logger.debug('Setting captured screenshot:', screenshot.filename);\n NATIVE.encodeToBase64(screenshot.data).then((base64String) => {\n if (base64String != null) {\n const dataUri = `data:${screenshot.contentType};base64,${base64String}`;\n this.setState({ filename: screenshot.filename, attachment: screenshot.data, attachmentUri: dataUri });\n } else {\n logger.error('Failed to read image data from:', screenshot.filename);\n }\n }).catch((error) => {\n logger.error('Failed to read image data from:', screenshot.filename, 'error: ', error);\n });\n } else {\n logger.error('Failed to read image data from:', screenshot.filename);\n }\n }\n\n private _saveFormState = (): void => {\n FeedbackWidget._savedState = { ...this.state };\n };\n\n private _clearFormState = (): void => {\n FeedbackWidget._savedState = {\n name: '',\n email: '',\n description: '',\n filename: undefined,\n attachment: undefined,\n attachmentUri: undefined,\n };\n };\n\n private _hasScreenshot = (): boolean => {\n return this.state.filename !== undefined && this.state.attachment !== undefined && this.state.attachmentUri !== undefined;\n }\n}\n"]}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { ViewStyle } from 'react-native';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type { FeedbackWidgetTheme } from './FeedbackWidget.theme';
|
|
3
|
+
import type { FeedbackButtonStyles, FeedbackWidgetStyles } from './FeedbackWidget.types';
|
|
4
|
+
declare const defaultStyles: (theme: FeedbackWidgetTheme) => FeedbackWidgetStyles;
|
|
5
|
+
export declare const defaultButtonStyles: (theme: FeedbackWidgetTheme) => FeedbackButtonStyles;
|
|
6
|
+
export declare const defaultScreenshotButtonStyles: (theme: FeedbackWidgetTheme) => FeedbackButtonStyles;
|
|
4
7
|
export declare const modalWrapper: ViewStyle;
|
|
5
|
-
export declare const modalSheetContainer: ViewStyle;
|
|
8
|
+
export declare const modalSheetContainer: (theme: FeedbackWidgetTheme) => ViewStyle;
|
|
6
9
|
export declare const topSpacer: ViewStyle;
|
|
7
10
|
export default defaultStyles;
|
|
8
11
|
//# sourceMappingURL=FeedbackWidget.styles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackWidget.styles.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidget.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"FeedbackWidget.styles.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidget.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEzF,QAAA,MAAM,aAAa,UAAW,mBAAmB,KAAG,oBA2GnD,CAAC;AAEF,eAAO,MAAM,mBAAmB,UAAW,mBAAmB,KAAG,oBAgChE,CAAC;AAEF,eAAO,MAAM,6BAA6B,UAlCC,mBAAmB,KAAG,oBAkCD,CAAC;AAEjE,eAAO,MAAM,YAAY,EAAE,SAM1B,CAAC;AAEF,eAAO,MAAM,mBAAmB,UAAW,mBAAmB,KAAG,SAchE,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,SAEvB,CAAC;AAEF,eAAe,aAAa,CAAC"}
|