Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(feedback): Implements Report a Bug button #4378

Open
wants to merge 149 commits into
base: feedback-ui-2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
149 commits
Select commit Hold shift + click to select a range
817eac8
Update the client implementation to use the new capture feedback js api
antonis Nov 27, 2024
5370a99
Updates SDK API
antonis Nov 27, 2024
42e2fa1
Adds new feedback button in the sample
antonis Nov 27, 2024
514b102
Adds changelog
antonis Nov 27, 2024
0935bbd
Removes unused mock
antonis Nov 27, 2024
9ea5496
Update CHANGELOG.md
antonis Nov 28, 2024
da0d4ac
Directly use captureFeedback from sentry/core
antonis Nov 28, 2024
3e36c6d
Use import from core
antonis Nov 28, 2024
5f3df64
Fixes imports order lint issue
antonis Nov 28, 2024
71b28e8
Fixes build issue
antonis Nov 28, 2024
f9d2b59
Adds captureFeedback tests from sentry-javascript
antonis Nov 28, 2024
d05d531
Update CHANGELOG.md
krystofwoldrich Nov 28, 2024
2bb104b
Only deprecate client captureUserFeedback
antonis Nov 28, 2024
4339274
Add simple form UI
antonis Nov 29, 2024
6ce799b
Adds basic form functionality
antonis Nov 29, 2024
f2cefc6
Update imports
antonis Nov 29, 2024
694ee33
Update imports
antonis Dec 2, 2024
18b1c33
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 2, 2024
034efde
Remove useState hook to avoid multiple react instances issues
antonis Dec 2, 2024
67a492d
Move types and styles in different files
antonis Dec 2, 2024
8eaa61d
Removes attachment button to be added back separately along with the …
antonis Dec 2, 2024
0b88cc5
Add basic field validation
antonis Dec 2, 2024
ae11b8d
Adds changelog
antonis Dec 2, 2024
7f2ca06
Updates changelog
antonis Dec 2, 2024
064b6c4
Updates changelog
antonis Dec 2, 2024
e2add4a
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 2, 2024
e21718a
Trim whitespaces from the submitted feedback
antonis Dec 2, 2024
407f179
Adds tests
antonis Dec 2, 2024
14ac005
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 2, 2024
ddade00
Renames FeedbackFormScreen to FeedbackForm
antonis Dec 6, 2024
1bc1e4c
Add beta label
antonis Dec 6, 2024
7934756
Extract default text to constants
antonis Dec 6, 2024
95e1e0f
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 10, 2024
a169362
Moves constant to a separate file and aligns naming with JS
antonis Dec 10, 2024
4b5df7a
Adds input text labels
antonis Dec 10, 2024
4fa81ce
Close screen before sending the feedback to minimise wait time
antonis Dec 10, 2024
4fff82f
Rename file for consistency
antonis Dec 10, 2024
0258bf2
Flatten configuration hierarchy and clean up
antonis Dec 10, 2024
458ebc2
Align required values with JS
antonis Dec 10, 2024
f0e1bef
Use Sentry user email and name when set
antonis Dec 10, 2024
b9235f2
Simplifies email validation
antonis Dec 10, 2024
6717a84
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 11, 2024
39a67bd
Show success alert message
antonis Dec 11, 2024
501a134
Aligns naming with JS and unmounts the form by default
antonis Dec 11, 2024
4b290a2
Use the minimum config without props in the changelog
antonis Dec 11, 2024
7109deb
Adds development not for unimplemented function
antonis Dec 11, 2024
c80c5cb
Show email and name conditionally
antonis Dec 11, 2024
8c56753
Adds sentry branding (png logo)
antonis Dec 11, 2024
d6e9229
Adds sentry logo resource
antonis Dec 11, 2024
5292475
Add assets in module exports
antonis Dec 11, 2024
efd809f
Revert "Add assets in module exports"
antonis Dec 11, 2024
bc7ae65
Revert "Adds sentry logo resource"
antonis Dec 11, 2024
79ee5ba
Revert "Adds sentry branding (png logo)"
antonis Dec 11, 2024
ba13320
Add last event id
antonis Dec 11, 2024
1f5fb56
Mock lastEventId
antonis Dec 11, 2024
439367a
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 13, 2024
9831482
Adds beta note in the changelog
antonis Dec 13, 2024
d92ea89
Autoinject feedback form
antonis Dec 13, 2024
4097347
Updates changelog
antonis Dec 13, 2024
f8a82fd
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 13, 2024
8b9f4d5
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Dec 13, 2024
30a7b10
Align colors with JS
antonis Dec 13, 2024
3eccf25
Update CHANGELOG.md
antonis Dec 13, 2024
bc96fce
Update CHANGELOG.md
antonis Dec 13, 2024
995a9ca
Update CHANGELOG.md
antonis Dec 13, 2024
3aacaf7
Use regular fonts for both buttons
antonis Dec 13, 2024
20e3a6c
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' of https://git…
antonis Dec 13, 2024
78e412c
Handle keyboard properly
antonis Dec 13, 2024
c45a5e6
Adds an option on whether the email should be validated
antonis Dec 13, 2024
6e39119
Merge properties only once
antonis Dec 13, 2024
57d99e9
Loads current user data on form construction
antonis Dec 13, 2024
6fb8ab4
Remove unneeded extra padding
antonis Dec 13, 2024
fd2e317
Fix background color issue
antonis Dec 13, 2024
0261e04
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Dec 13, 2024
d4168c1
Adds feedback button
antonis Dec 16, 2024
5a9c02d
Updates the changelog
antonis Dec 16, 2024
b793937
Fixes changelog typo
antonis Dec 16, 2024
b209ad6
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 16, 2024
4408071
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Dec 16, 2024
bdee51b
Merge branch 'antonis/4358-Feedback-Form-Autoinject' into antonis/435…
antonis Dec 16, 2024
a40fde6
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 17, 2024
2a8f13f
Updates styles background color
antonis Dec 17, 2024
0f3a244
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 17, 2024
9a96e74
Use defaultProps
antonis Dec 17, 2024
10c1c0e
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 17, 2024
2be08a6
Correct defaultProps
antonis Dec 17, 2024
0588552
Adds test to verify when getUser is called
antonis Dec 17, 2024
89c66d3
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Dec 17, 2024
851b63e
Merge branch 'antonis/4358-Feedback-Form-Autoinject' into antonis/435…
antonis Dec 17, 2024
f05497c
Use smaller image
antonis Dec 18, 2024
0eb4f68
Add margin next to the icon
antonis Dec 18, 2024
fbc8f77
Adds bottom spacing in the ErrorScreen so that the feedback button do…
antonis Dec 18, 2024
e0ec92d
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 18, 2024
fada0fb
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Dec 18, 2024
2d30fd7
Merge branch 'antonis/4358-Feedback-Form-Autoinject' into antonis/435…
antonis Dec 18, 2024
265e629
(2.2) feat: Add Feedback Form UI Branding logo (#4357)
antonis Dec 19, 2024
da0e3ea
Autoinject feedback form (#4370)
antonis Dec 19, 2024
a931ba9
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 19, 2024
5de8841
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Dec 19, 2024
5f9dec6
Align changelog entry
antonis Dec 19, 2024
8359696
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 19, 2024
1e8aa8f
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Dec 19, 2024
76518cc
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 23, 2024
cabd570
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Dec 23, 2024
b0384ed
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Dec 30, 2024
61886c2
Merge branch 'main' into antonis/3859-newCaptureFeedbackAPI-Form
antonis Jan 9, 2025
9853630
Update changelog
antonis Jan 9, 2025
209a29b
Merge branch 'antonis/3859-newCaptureFeedbackAPI-Form' into antonis/4…
antonis Jan 9, 2025
fe3dc15
Disable bouncing
antonis Jan 30, 2025
72eef2d
Add modal ui appearance
antonis Jan 30, 2025
ccc808b
Update snapshot tests
antonis Jan 30, 2025
fd47fd2
Fix bottom margin
antonis Jan 30, 2025
dcc5d3b
Merge branch 'feedback-ui' into antonis/feedback-modal-ui
antonis Jan 31, 2025
9ecd8a2
Fix sheet height
antonis Jan 31, 2025
05f94f8
Remove extra modal border
antonis Jan 31, 2025
d88a599
Do not expose modal styles
antonis Jan 31, 2025
ce1de86
Animate background color
antonis Jan 31, 2025
a7a4e56
Avoid keyboard in modal
antonis Jan 31, 2025
22fd47b
Merge branch 'feedback-ui' into antonis/4358-Feedback-Form-Autoinject…
antonis Feb 3, 2025
8779886
Merge branch 'feedback-ui' into antonis/feedback-modal-ui
antonis Feb 3, 2025
7832765
Merge branch 'antonis/feedback-modal-ui' into antonis/4358-Feedback-F…
antonis Feb 3, 2025
447e3fe
Update changelog
antonis Feb 3, 2025
47f0fc4
Fix changelog
antonis Feb 3, 2025
63bfc6d
Updates comment
antonis Feb 3, 2025
6f60162
Extract FeedbackButtonProps
antonis Feb 3, 2025
ae80f7d
Merge branch 'feedback-ui' into antonis/feedback-modal-ui
antonis Feb 7, 2025
079a436
Merge branch 'antonis/feedback-modal-ui' into antonis/4358-Feedback-F…
antonis Feb 7, 2025
3e5be69
Merge branch 'feedback-ui' into antonis/4358-Feedback-Form-Autoinject…
antonis Feb 11, 2025
0dc5f27
Merge branch 'feedback-ui' into antonis/4358-Feedback-Form-Autoinject…
antonis Feb 14, 2025
f80a48d
Merge branch 'feedback-ui' into antonis/4358-Feedback-Form-Autoinject…
antonis Feb 18, 2025
b3eec7e
Merge branch 'feedback-ui' into antonis/4358-Feedback-Form-Autoinject…
antonis Feb 20, 2025
a79951c
Merge branch 'feedback-ui' into antonis/4358-Feedback-Form-Autoinject…
antonis Feb 20, 2025
b08debb
Merge branch 'feedback-ui-2' into antonis/4358-Feedback-Form-Autoinje…
antonis Feb 25, 2025
e601785
Add public function description to satisfy lint check
antonis Feb 25, 2025
2e0e5d2
Adds tests
antonis Feb 25, 2025
2620101
Merge branch 'feedback-ui-2' into antonis/4358-Feedback-Form-Autoinje…
antonis Feb 25, 2025
9f631e2
Fix tests
antonis Feb 25, 2025
90402cb
Merge branch 'feedback-ui-2' into antonis/4358-Feedback-Form-Autoinje…
antonis Mar 7, 2025
307839d
Merge branch 'feedback-ui-2' into antonis/4358-Feedback-Form-Autoinje…
antonis Mar 21, 2025
2fbbf11
Include in the feedback integration
antonis Mar 24, 2025
bae1620
Fix circular dependency
antonis Mar 24, 2025
be791cd
Remove unneeded line
antonis Mar 26, 2025
13de5af
Merge branch 'feedback-ui-2' into antonis/4358-Feedback-Form-Autoinje…
antonis Mar 26, 2025
04f1a8d
Place widget button below the feedback widget shadow
antonis Mar 26, 2025
06adadd
Expose showFeedbackButton/hideFeedbackButton methods
antonis Mar 26, 2025
7473c58
Add dummy integration for tracking usage
antonis Mar 26, 2025
24b3df0
Adds button border
antonis Mar 26, 2025
10a70a3
Fixes tests
antonis Mar 26, 2025
b3fe27c
Merge branch 'feedback-ui-2' into antonis/4358-Feedback-Form-Autoinje…
antonis Mar 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
> make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first.
<!-- prettier-ignore-end -->

## Unreleased

### Features

- Adds the `FeedbackButton` component that shows the Feedback Widget ([#4378](https://github.com/getsentry/sentry-react-native/pull/4378))

## 6.11.0-beta.0

### Features
Expand Down
48 changes: 48 additions & 0 deletions packages/core/src/js/feedback/FeedbackButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from 'react';
import { Image, Text, TouchableOpacity } from 'react-native';

import { defaultButtonConfiguration } from './defaults';
import { defaultButtonStyles } from './FeedbackWidget.styles';
import type { FeedbackButtonProps, FeedbackButtonStyles, FeedbackButtonTextConfiguration } from './FeedbackWidget.types';
import { feedbackIcon } from './icons';
import { lazyLoadFeedbackIntegration } from './lazy';

const showFeedbackWidget = (): void => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { showFeedbackWidget } = require('./FeedbackWidgetManager');
showFeedbackWidget();
};

/**
* @beta
* Implements a feedback button that opens the FeedbackForm.
*/
export class FeedbackButton extends React.Component<FeedbackButtonProps> {
public constructor(props: FeedbackButtonProps) {
super(props);
lazyLoadFeedbackIntegration();
}

/**
* Renders the feedback button.
*/
public render(): React.ReactNode {
const text: FeedbackButtonTextConfiguration = { ...defaultButtonConfiguration, ...this.props };
const styles: FeedbackButtonStyles = {
triggerButton: { ...defaultButtonStyles.triggerButton, ...this.props.styles?.triggerButton },
triggerText: { ...defaultButtonStyles.triggerText, ...this.props.styles?.triggerText },
triggerIcon: { ...defaultButtonStyles.triggerIcon, ...this.props.styles?.triggerIcon },
};

return (
<TouchableOpacity
style={styles.triggerButton}
onPress={showFeedbackWidget}
accessibilityLabel={text.triggerAriaLabel}
>
<Image source={{ uri: feedbackIcon }} style={styles.triggerIcon}/>
<Text style={styles.triggerText}>{text.triggerLabel}</Text>
</TouchableOpacity>
);
}
}
33 changes: 32 additions & 1 deletion packages/core/src/js/feedback/FeedbackWidget.styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ViewStyle } from 'react-native';

import type { FeedbackWidgetStyles } from './FeedbackWidget.types';
import type { FeedbackButtonStyles, FeedbackWidgetStyles } from './FeedbackWidget.types';

const PURPLE = 'rgba(88, 74, 192, 1)';
const FOREGROUND_COLOR = '#2b2233';
Expand Down Expand Up @@ -99,6 +99,37 @@ const defaultStyles: FeedbackWidgetStyles = {
},
};

export const defaultButtonStyles: FeedbackButtonStyles = {
triggerButton: {
position: 'absolute',
bottom: 30,
right: 30,
backgroundColor: BACKGROUND_COLOR,
padding: 15,
borderRadius: 40,
justifyContent: 'center',
alignItems: 'center',
elevation: 5,
shadowColor: BORDER_COLOR,
shadowOffset: { width: 1, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 3,
flexDirection: 'row',
borderWidth: 1,
borderColor: BORDER_COLOR,
},
triggerText: {
color: FOREGROUND_COLOR,
fontSize: 18,
},
triggerIcon: {
width: 24,
height: 24,
padding: 2,
marginEnd: 6,
},
};

export const modalWrapper: ViewStyle = {
position: 'absolute',
top: 0,
Expand Down
31 changes: 31 additions & 0 deletions packages/core/src/js/feedback/FeedbackWidget.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,21 @@ export interface FeedbackTextConfiguration {
genericError?: string;
}

/**
* The FeedbackButton text labels that can be customized
*/
export interface FeedbackButtonTextConfiguration {
/**
* The label for the Feedback widget button that opens the dialog
*/
triggerLabel?: string;

/**
* The aria label for the Feedback widget button that opens the dialog
*/
triggerAriaLabel?: string;
}

/**
* The public callbacks available for the feedback integration
*/
Expand Down Expand Up @@ -247,6 +262,22 @@ export interface FeedbackWidgetStyles {
sentryLogo?: ImageStyle;
}

/**
* The props for the feedback button
*/
export interface FeedbackButtonProps extends FeedbackButtonTextConfiguration {
styles?: FeedbackButtonStyles;
}

/**
* The styles for the feedback button
*/
export interface FeedbackButtonStyles {
triggerButton?: ViewStyle;
triggerText?: TextStyle;
triggerIcon?: ImageStyle;
}

/**
* The state of the feedback form
*/
Expand Down
56 changes: 47 additions & 9 deletions packages/core/src/js/feedback/FeedbackWidgetManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,25 @@ import type { NativeScrollEvent, NativeSyntheticEvent} from 'react-native';
import { Animated, Dimensions, Easing, Modal, PanResponder, Platform, ScrollView, View } from 'react-native';

import { notWeb } from '../utils/environment';
import { FeedbackButton } from './FeedbackButton';
import { FeedbackWidget } from './FeedbackWidget';
import { modalSheetContainer, modalWrapper, topSpacer } from './FeedbackWidget.styles';
import type { FeedbackWidgetStyles } from './FeedbackWidget.types';
import { getFeedbackOptions } from './integration';
import { lazyLoadAutoInjectFeedbackIntegration } from './lazy';
import { getFeedbackButtonOptions, getFeedbackOptions } from './integration';
import { lazyLoadAutoInjectFeedbackButtonIntegration,lazyLoadAutoInjectFeedbackIntegration } from './lazy';
import { isModalSupported } from './utils';

const PULL_DOWN_CLOSE_THRESHOLD = 200;
const SLIDE_ANIMATION_DURATION = 200;
const BACKGROUND_ANIMATION_DURATION = 200;

class FeedbackWidgetManager {
private static _isVisible = false;
private static _setVisibility: (visible: boolean) => void;
abstract class FeedbackManager {
protected static _isVisible = false;
protected static _setVisibility: (visible: boolean) => void;

protected static get _feedbackComponentName(): string {
throw new Error('Subclasses must override feedbackComponentName');
}

public static initialize(setVisibility: (visible: boolean) => void): void {
this._setVisibility = setVisibility;
Expand All @@ -38,7 +43,7 @@ class FeedbackWidgetManager {
} else {
// This message should be always shown otherwise it's not possible to use the widget.
// eslint-disable-next-line no-console
console.warn('[Sentry] FeedbackWidget requires `Sentry.wrap(RootComponent)` to be called before `showFeedbackWidget()`.');
console.warn(`[Sentry] ${this._feedbackComponentName} requires 'Sentry.wrap(RootComponent)' to be called before 'show${this._feedbackComponentName}()'.`);
}
}

Expand All @@ -49,7 +54,7 @@ class FeedbackWidgetManager {
} else {
// This message should be always shown otherwise it's not possible to use the widget.
// eslint-disable-next-line no-console
console.warn('[Sentry] FeedbackWidget requires `Sentry.wrap(RootComponent)` before interacting with the widget.');
console.warn(`[Sentry] ${this._feedbackComponentName} requires 'Sentry.wrap(RootComponent)' before interacting with the widget.`);
}
}

Expand All @@ -58,12 +63,25 @@ class FeedbackWidgetManager {
}
}

class FeedbackWidgetManager extends FeedbackManager {
protected static get _feedbackComponentName(): string {
return 'FeedbackWidget';
}
}

class FeedbackButtonManager extends FeedbackManager {
protected static get _feedbackComponentName(): string {
return 'FeedbackButton';
}
}

interface FeedbackWidgetProviderProps {
children: React.ReactNode;
styles?: FeedbackWidgetStyles;
}

interface FeedbackWidgetProviderState {
isButtonVisible: boolean;
isVisible: boolean;
backgroundOpacity: Animated.Value;
panY: Animated.Value;
Expand All @@ -72,6 +90,7 @@ interface FeedbackWidgetProviderState {

class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps> {
public state: FeedbackWidgetProviderState = {
isButtonVisible: false,
isVisible: false,
backgroundOpacity: new Animated.Value(0),
panY: new Animated.Value(Dimensions.get('screen').height),
Expand Down Expand Up @@ -112,6 +131,7 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps

public constructor(props: FeedbackWidgetProviderProps) {
super(props);
FeedbackButtonManager.initialize(this._setButtonVisibilityFunction);
FeedbackWidgetManager.initialize(this._setVisibilityFunction);
}

Expand Down Expand Up @@ -150,7 +170,7 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
return <>{this.props.children}</>;
}

const { isVisible, backgroundOpacity } = this.state;
const { isButtonVisible, isVisible, backgroundOpacity } = this.state;

const backgroundColor = backgroundOpacity.interpolate({
inputRange: [0, 1],
Expand All @@ -162,6 +182,7 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
return (
<>
{this.props.children}
{isButtonVisible && <FeedbackButton {...getFeedbackButtonOptions()}/>}
{isVisible &&
<Animated.View style={[modalWrapper, { backgroundColor }]} >
<Modal visible={isVisible} transparent animationType="none" onRequestClose={this._handleClose} testID="feedback-form-modal">
Expand Down Expand Up @@ -219,6 +240,10 @@ class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps
}
};

private _setButtonVisibilityFunction = (visible: boolean): void => {
this.setState({ isButtonVisible: visible });
};

private _handleClose = (): void => {
FeedbackWidgetManager.hide();
};
Expand All @@ -233,4 +258,17 @@ const resetFeedbackWidgetManager = (): void => {
FeedbackWidgetManager.reset();
};

export { showFeedbackWidget, FeedbackWidgetProvider, resetFeedbackWidgetManager };
const showFeedbackButton = (): void => {
lazyLoadAutoInjectFeedbackButtonIntegration();
FeedbackButtonManager.show();
};

const hideFeedbackButton = (): void => {
FeedbackButtonManager.hide();
};

const resetFeedbackButtonManager = (): void => {
FeedbackButtonManager.reset();
};

export { showFeedbackButton, hideFeedbackButton, showFeedbackWidget, FeedbackWidgetProvider, resetFeedbackButtonManager, resetFeedbackWidgetManager };
8 changes: 7 additions & 1 deletion packages/core/src/js/feedback/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FeedbackWidgetProps } from './FeedbackWidget.types';
import type { FeedbackButtonProps, FeedbackWidgetProps } from './FeedbackWidget.types';
import { feedbackAlertDialog } from './utils';

const FORM_TITLE = 'Report a Bug';
Expand All @@ -11,6 +11,7 @@ const MESSAGE_LABEL = 'Description';
const IS_REQUIRED_LABEL = '(required)';
const SUBMIT_BUTTON_LABEL = 'Send Bug Report';
const CANCEL_BUTTON_LABEL = 'Cancel';
const TRIGGER_LABEL = 'Report a Bug';
const ERROR_TITLE = 'Error';
const FORM_ERROR = 'Please fill out all required fields.';
const EMAIL_ERROR = 'Please enter a valid email address.';
Expand Down Expand Up @@ -80,3 +81,8 @@ export const defaultConfiguration: Partial<FeedbackWidgetProps> = {
removeScreenshotButtonLabel: REMOVE_SCREENSHOT_LABEL,
genericError: GENERIC_ERROR_TEXT,
};

export const defaultButtonConfiguration: Partial<FeedbackButtonProps> = {
triggerLabel: TRIGGER_LABEL,
triggerAriaLabel: '',
};
2 changes: 2 additions & 0 deletions packages/core/src/js/feedback/icons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const feedbackIcon =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAk1BMVEUAAAAqIDEqIjMmIDArIjIrIjMoHjErITMrIjMqITIqITIqITIqIjIqITIqITIhHi4qITIqITIeAConHi8rITMqITIqITIcHCopITIpIDEpIDIlGC8qITIqITIpIDIpHjAqITIqIDIqIDEqIDAqITInHjAqIDIqIDEqITIqITIqIDIiFCgpIDEqITIoHS8qIDIrIjMN1S0HAAAAMHRSTlMAhnknzMQy1zyF6/H55PYQ0rIGGPudjAmUTEQUv7p2K6lmWDZxHV9S36J+DD7bI208pRBPAAAGrUlEQVR42uzd6XLaMBSG4Y/YhuAVbAwx+xp2eu7/6tq0nfaHIAizSNbR+5vJJM8EG45lGfrm7EZRSNL5bvcAg1oM6fZaBQxp/0HlylOY0PuRyjbco/L1unRHbVS9RYPuaoxKlzY7dF9xhgpXb9Hd1VDddiHdX4SqNnHpIU1QzcYhPaY5qpjj0aNaooL9iOlhvaFynYZEnAFmAXEGWI2IOAN8BsQZIGsTcQaY+0SMAQZT+hVfgLVPX3EFSLb0J6YARUR/YwmQ5PQvjgD9DcmWJ7hUraoANwy9owIwDuCGofc2gXEANwy9/TVgHMANQ+/pAMYBpLUOSebPAeMAbhh6tzOYByA/9A4+AeMAbhh6j1YwD0B+6B3MAOMAbhh6D09QAdCvtT33ecUkWfwDeD1Ab+yTHnknKABYHEmPwjGgAKAISY/cCVQAvGvy94c7QAVAEpEWtepQA/BBOtRppngYwDaDfAMt3gCNBVAeQKzxUciC/iAN6vZwJ4BYsC0gU5uUd3wHHgAgFu0yXE39IfCjhwcBiHWmE1yJFLfpA+UBJJpOtAbI93gwgFieaQsQFcDzAShYagqwTfAUADF3oiGAvwZeBUDxUjuA6QBPBBAbDbQC8OfAawFoU9cIoJ3h5QAUz3UBCD4BBQBESz0ARisoAqCmBgDBDFAGQB/KAaYrqASgrlKAVtcB1ALQThJgXX94px4A5QD0KQfgQP/KAYQH5gDkZ8wByOMOQE3DAfJZHtF3dd7NBngDsKh9Z9BIjQf41dyjizU5AACHFl0odFgAADOfztdmAoBsROfrMwEAxh06l8cGAEVM5+qzAcDCpzMN+QBgEtCZ6nwAcAhJbMsIAHMSixNGAPggsRkngF6DhDxOAKiHJJRxAjj3JvjBCmAgngvbrACwE88DKSuARPxIfGAFgFx8JS+AungQ4AUAYUAUMQMQ79pNeAH0hZe+8wJIY+FKKS8AuMLFcmYAubBihBnAUliwwgxgLQwGmQEIpwGXGcBCWLXEDGAiXCZmBlDn/h9w4H4MKIS5KDOAmfB9mBmA8HUwZwYgLBaoMQOIhItDvAAccZEAL4Cl8NIVLwDhEBDwmgmKeyV4vADG4v0jvACO4m0hrAAKEspYAYjrZl1WV4c/SajGCWAfkdCCE0BOQhtOa4TWJNZlBLDySczhA5A0SMzjs1I0HdKZ5mwAem06U8RmtXji0bmWXACcBp3L7zEBuPQcpyWPW2ayKZ1vk3IASMcBXWjN4La5/exIlxqZf+fopBvQxeKT2QD7fvdI3zU2++7xgK40NHz/gGsFK+YABfMtNJrMd5GZQgpgE4RR47F50/FEPYDXU7qXmFsoBmglKAGg316KZQEaGcoBaLWZanmAVqZ8O72vtokiAC/RYEPFr6K+EoB2T48tNb/66L0eoKnRrrJEjcWLAYK1VvsKE3V2LwVwHd12lhZ+pzIA8toa7i1OFC9fBODW9dxdnmi4egGAP8M3dahMemwyLQUQ1BJ8l/KnrLUHzwQIatd+vEeq84unARyXCa7VJPXl+2cAxNM+JJqQBm0Ojwbwp+se5BqRDnXTBwK0xnXIV++QDrXqT7k2WJmnjRGFb88CqMgD94i8kyIAjEmP4pkiALy3SI9GmRoAoL/dkA75czUAXyUnx3HpfHPnWjmdz/nTW0iSTRMFAFc/GL+X/mVuf/J+1DcSAGn3hoGhiQDAYSM/MDQSAPv8hqfwmggArH35JwQaCYBBW35gaCQA8BnIDwyNBMBqKD8wNBIAWMbyA0MjATBx5QeGRgIgbXbkB4YmAgCLI91flQHQ+z+H4QkA9CP6E1cAJFP6HVsAYO7TrxgD/HkMEGcAYBYzB8DJYw4AvIXMAVBvMQdA2mUOABw2zAHEgWH5xpUEAAqfHtO8ogDCwLBsk6oCCAPDckWoLoAwMCxTt8oAwsDw9uJVtQHguPeeBCsOIAwMb2uEygMAiwaVbZiYAFB+YJinMAIAWAzp9loFYAoA4OxGUUjS+W73AJgEUCILYAEsgAWwABbAAlgAC2ABLIAFsAAWwAJYAAtgASyABbAAFsACWAALYAEsgAWwABbAAlgAC2ABLIAFsAAWwAKUANg2r+WZDSCRBbAAFsAC/GyfXlIYhIIgitYgGHhoiMmDSPyAgqKz2v/qxIkL0JoU9NlB3+6OABEgAkSACBABnAP0FMvwslGsgpeBYjW8FBQbYeZNqbKFmYlSDex0FEp2BwB8V8rkPwwViSJ5gaX5QYlkuf/DZ0i8rWwM///0m7bni5flqh5dxt8BPG/wrQSMUX8AAAAASUVORK5CYII=';
23 changes: 20 additions & 3 deletions packages/core/src/js/feedback/integration.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { type Integration, getClient } from '@sentry/core';

import type { FeedbackWidgetProps } from './FeedbackWidget.types';
import type { FeedbackButtonProps, FeedbackWidgetProps } from './FeedbackWidget.types';

export const MOBILE_FEEDBACK_INTEGRATION_NAME = 'MobileFeedback';

type FeedbackIntegration = Integration & {
options: Partial<FeedbackWidgetProps>;
buttonOptions: Partial<FeedbackButtonProps>;
};

export const feedbackIntegration = (initOptions: FeedbackWidgetProps = {}): FeedbackIntegration => {
export const feedbackIntegration = (
initOptions: FeedbackWidgetProps & { buttonOptions?: FeedbackButtonProps } = {},
): FeedbackIntegration => {
const { buttonOptions, ...widgetOptions } = initOptions;

return {
name: MOBILE_FEEDBACK_INTEGRATION_NAME,
options: initOptions,
options: widgetOptions,
buttonOptions: buttonOptions || {},
};
};

Expand All @@ -25,3 +31,14 @@ export const getFeedbackOptions = (): Partial<FeedbackWidgetProps> => {

return integration.options;
};

export const getFeedbackButtonOptions = (): Partial<FeedbackButtonProps> => {
const integration = getClient()?.getIntegrationByName<ReturnType<typeof feedbackIntegration>>(
MOBILE_FEEDBACK_INTEGRATION_NAME,
);
if (!integration) {
return {};
}

return integration.buttonOptions;
};
13 changes: 13 additions & 0 deletions packages/core/src/js/feedback/lazy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,16 @@ export function lazyLoadAutoInjectFeedbackIntegration(): void {
getClient()?.addIntegration({ name: AUTO_INJECT_FEEDBACK_INTEGRATION_NAME });
}
}

export const AUTO_INJECT_FEEDBACK_BUTTON_INTEGRATION_NAME = 'AutoInjectMobileFeedbackButton';

/**
* Lazy loads the auto inject feedback button integration if it is not already loaded.
*/
export function lazyLoadAutoInjectFeedbackButtonIntegration(): void {
const integration = getClient()?.getIntegrationByName(AUTO_INJECT_FEEDBACK_BUTTON_INTEGRATION_NAME);
if (!integration) {
// Lazy load the integration to track usage
getClient()?.addIntegration({ name: AUTO_INJECT_FEEDBACK_BUTTON_INTEGRATION_NAME });
}
}
3 changes: 2 additions & 1 deletion packages/core/src/js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ export type { TimeToDisplayProps } from './tracing';

export { Mask, Unmask } from './replay/CustomMask';

export { FeedbackButton } from './feedback/FeedbackButton';
export { FeedbackWidget } from './feedback/FeedbackWidget';
export { showFeedbackWidget } from './feedback/FeedbackWidgetManager';
export { showFeedbackWidget, showFeedbackButton, hideFeedbackButton } from './feedback/FeedbackWidgetManager';

export { getDataFromUri } from './wrapper';
Loading
Loading