Skip to content

Commit 638377d

Browse files
committed
Auto-inject feedback form
1 parent f3c3563 commit 638377d

File tree

4 files changed

+103
-1
lines changed

4 files changed

+103
-1
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import * as React from 'react';
2+
import { Modal, StyleSheet,View } from 'react-native';
3+
4+
import { FeedbackForm } from './FeedbackForm';
5+
6+
class FeedbackFormManager {
7+
private static _isVisible = false;
8+
private static _setVisibility: (visible: boolean) => void;
9+
10+
public static initialize(setVisibility: (visible: boolean) => void): void {
11+
this._setVisibility = setVisibility;
12+
}
13+
14+
public static show(): void {
15+
if (this._setVisibility) {
16+
this._isVisible = true;
17+
this._setVisibility(true);
18+
}
19+
}
20+
21+
public static hide(): void {
22+
if (this._setVisibility) {
23+
this._isVisible = false;
24+
this._setVisibility(false);
25+
}
26+
}
27+
28+
public static isFormVisible(): boolean {
29+
return this._isVisible;
30+
}
31+
}
32+
33+
interface FeedbackFormProviderProps {
34+
children: React.ReactNode;
35+
}
36+
37+
class FeedbackFormProvider extends React.Component<FeedbackFormProviderProps> {
38+
public state = {
39+
isVisible: false,
40+
};
41+
42+
public constructor(props: FeedbackFormProviderProps) {
43+
super(props);
44+
FeedbackFormManager.initialize(this._setVisibilityFunction);
45+
}
46+
47+
/**
48+
* Renders the feedback form modal.
49+
*/
50+
public render(): React.ReactNode {
51+
const { isVisible } = this.state;
52+
53+
return (
54+
<>
55+
{this.props.children}
56+
{isVisible && (
57+
<Modal visible={isVisible} transparent animationType="slide">
58+
<View style={styles.modalBackground}>
59+
<FeedbackForm
60+
onFormClose={this._handleClose}
61+
onFormSubmitted={this._handleClose}
62+
/>
63+
</View>
64+
</Modal>
65+
)}
66+
</>
67+
);
68+
}
69+
70+
private _setVisibilityFunction = (visible: boolean): void => {
71+
this.setState({ isVisible: visible });
72+
};
73+
74+
private _handleClose = (): void => {
75+
FeedbackFormManager.hide();
76+
this.setState({ isVisible: false });
77+
};
78+
}
79+
80+
const showFeedbackForm = (): void => {
81+
FeedbackFormManager.show();
82+
};
83+
84+
const styles = StyleSheet.create({
85+
modalBackground: {
86+
flex: 1,
87+
justifyContent: 'center',
88+
backgroundColor: 'rgba(0,0,0,0.5)',
89+
},
90+
});
91+
92+
export { showFeedbackForm, FeedbackFormProvider };

packages/core/src/js/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,4 @@ export type { TimeToDisplayProps } from './tracing';
8686
export { Mask, Unmask } from './replay/CustomMask';
8787

8888
export { FeedbackForm } from './feedback/FeedbackForm';
89+
export { showFeedbackForm } from './feedback/FeedbackFormManager';

packages/core/src/js/sdk.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
import * as React from 'react';
99

1010
import { ReactNativeClient } from './client';
11+
import { FeedbackFormProvider } from './feedback/FeedbackFormManager';
1112
import { getDevServer } from './integrations/debugsymbolicatorutils';
1213
import { getDefaultIntegrations } from './integrations/default';
1314
import type { ReactNativeClientOptions, ReactNativeOptions, ReactNativeWrapperOptions } from './options';
@@ -163,7 +164,9 @@ export function wrap<P extends Record<string, unknown>>(
163164
return (
164165
<TouchEventBoundary {...(options?.touchEventBoundaryProps ?? {})}>
165166
<ReactNativeProfiler {...profilerProps}>
166-
<RootComponent {...appProps} />
167+
<FeedbackFormProvider>
168+
<RootComponent {...appProps} />
169+
</FeedbackFormProvider>
167170
</ReactNativeProfiler>
168171
</TouchEventBoundary>
169172
);

samples/react-native/src/Screens/ErrorsScreen.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,12 @@ const ErrorsScreen = (_props: Props) => {
226226
_props.navigation.navigate('FeedbackForm');
227227
}}
228228
/>
229+
<Button
230+
title="Feedback form (auto)"
231+
onPress={() => {
232+
Sentry.showFeedbackForm();
233+
}}
234+
/>
229235
<Button
230236
title="Send user feedback"
231237
onPress={() => {

0 commit comments

Comments
 (0)