Skip to content

Commit

Permalink
feat(user feedback): button widget (#4364)
Browse files Browse the repository at this point in the history
  • Loading branch information
armcknight authored Oct 29, 2024
1 parent b8ac050 commit 1a790ba
Show file tree
Hide file tree
Showing 20 changed files with 669 additions and 139 deletions.
21 changes: 18 additions & 3 deletions Samples/iOS-ObjectiveC/iOS-ObjectiveC/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,41 @@ - (BOOL)application:(UIApplication *)application
};

options.configureUserFeedback = ^(SentryUserFeedbackConfiguration *_Nonnull config) {
UIOffset layoutOffset = UIOffsetMake(25, 75);
if ([args containsObject:@"--io.sentry.iOS-Swift.user-feedback.all-defaults"]) {
config.configureWidget = ^(SentryUserFeedbackWidgetConfiguration *widget) {
widget.layoutUIOffset = layoutOffset;
};
return;
}
config.useShakeGesture = YES;
config.showFormForScreenshots = YES;
config.configureWidget = ^(SentryUserFeedbackWidgetConfiguration *_Nonnull widget) {
if ([args
containsObject:@"--io.sentry.iOS-Swift.auto-inject-user-feedback-widget"]) {
widget.labelText = @"Report Jank";
widget.widgetAccessibilityLabel = @"io.sentry.iOS-Swift.button.report-jank";
widget.layoutUIOffset = layoutOffset;
} else {
widget.autoInject = NO;
}

if ([args containsObject:@"--io.sentry.iOS-Swift.user-feedback.no-widget-text"]) {
widget.labelText = nil;
}
if ([args containsObject:@"--io.sentry.iOS-Swift.user-feedback.no-widget-icon"]) {
widget.showIcon = NO;
}
};
config.configureForm = ^(SentryUserFeedbackFormConfiguration *_Nonnull uiForm) {
uiForm.formTitle = @"Jank Report";
uiForm.submitButtonLabel = @"Report that jank";
uiForm.addScreenshotButtonLabel = @"Show us the jank";
uiForm.messagePlaceholder
= @"Describe the nature of the jank. Its essence, if you will.";
uiForm.themeOverrides = ^(SentryUserFeedbackThemeConfiguration *_Nonnull theme) {
theme.font = [UIFont fontWithName:@"Comic Sans" size:25];
};
};
config.configureTheme = ^(SentryUserFeedbackThemeConfiguration *_Nonnull theme) {
theme.font = [UIFont fontWithName:@"ChalkboardSE-Regular" size:25];
};
config.onSubmitSuccess = ^(NSDictionary<NSString *, id> *_Nonnull info) {
NSString *name = info[@"name"] ?: @"$shakespearean_insult_name";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@
argument = "--disable-file-io-tracing"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--io.sentry.iOS-Swift.user-feedback.no-widget-icon"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--io.sentry.iOS-Swift.user-feedback.no-widget-text"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--io.sentry.iOS-Swift.user-feedback.all-defaults"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--skip-sentry-init"
isEnabled = "NO">
Expand Down Expand Up @@ -163,7 +175,7 @@
</CommandLineArgument>
<CommandLineArgument
argument = "--io.sentry.iOS-Swift.auto-inject-user-feedback-widget"
isEnabled = "NO">
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<EnvironmentVariables>
Expand Down
47 changes: 44 additions & 3 deletions Samples/iOS-Swift/iOS-Swift/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,24 +163,65 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

options.configureUserFeedback = { config in
let layoutOffset = UIOffset(horizontal: 25, vertical: 75)
guard !args.contains("--io.sentry.iOS-Swift.user-feedback.all-defaults") else {
config.configureWidget = { widget in
widget.layoutUIOffset = layoutOffset
}
return
}
config.useShakeGesture = true
config.showFormForScreenshots = true
config.configureWidget = { widget in
if args.contains("--io.sentry.iOS-Swift.auto-inject-user-feedback-widget") {
widget.labelText = "Report Jank"
if Locale.current.languageCode == "ar" { // arabic
widget.labelText = ""
} else if Locale.current.languageCode == "ur" { // urdu
widget.labelText = "نستعلیق"
} else if Locale.current.languageCode == "he" { // hebrew
widget.labelText = "עִבְרִית‎"
} else if Locale.current.languageCode == "hi" { // Hindi
widget.labelText = "नागरि"
} else {
widget.labelText = "Report Jank"
}
widget.widgetAccessibilityLabel = "io.sentry.iOS-Swift.button.report-jank"
widget.layoutUIOffset = layoutOffset
} else {
widget.autoInject = false
}
if args.contains("--io.sentry.iOS-Swift.user-feedback.no-widget-text") {
widget.labelText = nil
}
if args.contains("--io.sentry.iOS-Swift.user-feedback.no-widget-icon") {
widget.showIcon = false
}
}
config.configureForm = { uiForm in
uiForm.formTitle = "Jank Report"
uiForm.submitButtonLabel = "Report that jank"
uiForm.addScreenshotButtonLabel = "Show us the jank"
uiForm.messagePlaceholder = "Describe the nature of the jank. Its essence, if you will."
uiForm.themeOverrides = { theme in
theme.font = UIFont(name: "Comic Sans", size: 25)
}
config.configureTheme = { theme in
let fontSize: CGFloat = 25

let fontFamily: String
if Locale.current.languageCode == "ar" { // arabic; ar_EG
fontFamily = "Damascus"
} else if Locale.current.languageCode == "ur" { // urdu; ur_PK
fontFamily = "NotoNastaliq"
} else if Locale.current.languageCode == "he" { // hebrew; he_IL
fontFamily = "Arial Hebrew"
} else if Locale.current.languageCode == "hi" { // Hindi; hi_IN
fontFamily = "DevanagariSangamMN"
} else {
fontFamily = "ChalkboardSE-Regular"
}
theme.font = UIFont(name: fontFamily, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
theme.outlineColor = .purple
theme.foreground = .purple
theme.background = .purple.withAlphaComponent(0.1)
}
config.onSubmitSuccess = { info in
let name = info["name"] ?? "$shakespearean_insult_name"
Expand Down
20 changes: 20 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,13 @@
84B7FA4429B2924000AD93B1 /* TestRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E25C97425F8511A00DC215B /* TestRandom.swift */; };
84B7FA4529B2926900AD93B1 /* TestDisplayLinkWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B30B68126527C55006B2752 /* TestDisplayLinkWrapper.swift */; };
84B7FA4629B2935F00AD93B1 /* ClearTestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD47B4C268F0B080076A663 /* ClearTestState.swift */; };
84BA62272CAE2EEF0049F636 /* SentryUserFeedbackWidgetButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BA62262CAE2EEF0049F636 /* SentryUserFeedbackWidgetButtonView.swift */; };
84CFA4CA2C9DF884008DA5F4 /* SentryUserFeedbackWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CFA4C92C9DF884008DA5F4 /* SentryUserFeedbackWidget.swift */; };
84CFA4CD2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84CFA4CC2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.m */; };
84CFA4CE2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.h in Headers */ = {isa = PBXBuildFile; fileRef = 84CFA4CB2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.h */; };
84DEE86B2B686BD400A7BC17 /* SentrySamplerDecision.h in Headers */ = {isa = PBXBuildFile; fileRef = 84DEE86A2B686BD400A7BC17 /* SentrySamplerDecision.h */; };
84DEE8762B69AD6400A7BC17 /* SentryLaunchProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 84DEE8752B69AD6400A7BC17 /* SentryLaunchProfiling.h */; };
84E13B842CBF1D91003B52EC /* SentryUserFeedbackWidgetButtonMegaphoneIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E13B832CBF1D91003B52EC /* SentryUserFeedbackWidgetButtonMegaphoneIconView.swift */; };
84EB21942BF01C6C00EDDA28 /* TestNSNotificationCenterWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B18DE4328D9F8F6004845C6 /* TestNSNotificationCenterWrapper.swift */; };
84EB21962BF01CEA00EDDA28 /* SentryCrashInstallationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84EB21952BF01CEA00EDDA28 /* SentryCrashInstallationTests.swift */; };
84F994E62A6894B500EC0190 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F994E52A6894B500EC0190 /* CoreData.framework */; };
Expand Down Expand Up @@ -1761,9 +1766,14 @@
84AF45A429A7FFA500FBB177 /* SentryProfiledTracerConcurrency.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryProfiledTracerConcurrency.h; path = ../include/SentryProfiledTracerConcurrency.h; sourceTree = "<group>"; };
84AF45A529A7FFA500FBB177 /* SentryProfiledTracerConcurrency.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryProfiledTracerConcurrency.mm; sourceTree = "<group>"; };
84B7FA3B29B2866200AD93B1 /* SentryTestUtils-ObjC-BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryTestUtils-ObjC-BridgingHeader.h"; sourceTree = "<group>"; };
84BA62262CAE2EEF0049F636 /* SentryUserFeedbackWidgetButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUserFeedbackWidgetButtonView.swift; sourceTree = "<group>"; };
84C47B2B2A09239100DAEB8A /* .codecov.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .codecov.yml; sourceTree = "<group>"; };
84CFA4C92C9DF884008DA5F4 /* SentryUserFeedbackWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUserFeedbackWidget.swift; sourceTree = "<group>"; };
84CFA4CB2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryUserFeedbackIntegrationShell.h; sourceTree = "<group>"; };
84CFA4CC2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryUserFeedbackIntegrationShell.m; sourceTree = "<group>"; };
84DEE86A2B686BD400A7BC17 /* SentrySamplerDecision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentrySamplerDecision.h; path = include/SentrySamplerDecision.h; sourceTree = "<group>"; };
84DEE8752B69AD6400A7BC17 /* SentryLaunchProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryLaunchProfiling.h; path = Sources/Sentry/include/SentryLaunchProfiling.h; sourceTree = SOURCE_ROOT; };
84E13B832CBF1D91003B52EC /* SentryUserFeedbackWidgetButtonMegaphoneIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUserFeedbackWidgetButtonMegaphoneIconView.swift; sourceTree = "<group>"; };
84EACEBC2C33CA7A009B8753 /* SentryWithoutUIKit.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; name = SentryWithoutUIKit.modulemap; path = Sources/Resources/SentryWithoutUIKit.modulemap; sourceTree = SOURCE_ROOT; };
84EACEDF2C3DCAE2009B8753 /* DeploymentTargets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DeploymentTargets.xcconfig; sourceTree = "<group>"; };
84EB21952BF01CEA00EDDA28 /* SentryCrashInstallationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCrashInstallationTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3505,6 +3515,11 @@
children = (
849B8F9E2C70091A00148E1F /* Configuration */,
849B8F962C6E906900148E1F /* SentryUserFeedbackIntegration.swift */,
84CFA4CB2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.h */,
84CFA4CC2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.m */,
84CFA4C92C9DF884008DA5F4 /* SentryUserFeedbackWidget.swift */,
84BA62262CAE2EEF0049F636 /* SentryUserFeedbackWidgetButtonView.swift */,
84E13B832CBF1D91003B52EC /* SentryUserFeedbackWidgetButtonMegaphoneIconView.swift */,
);
name = UserFeedback;
path = ../Swift/Integrations/UserFeedback;
Expand Down Expand Up @@ -3963,6 +3978,7 @@
8E133FA625E72EB400ABD0BF /* SentrySamplingContext.h in Headers */,
0A9BF4E428A114B50068D266 /* SentryViewHierarchyIntegration.h in Headers */,
D8BBD32728FD9FC00011F850 /* SentrySwift.h in Headers */,
84CFA4CE2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.h in Headers */,
8E4E7C7425DAAB49006AB9E2 /* SentrySpanProtocol.h in Headers */,
8EC4CF4A25C38DAA0093DEE9 /* SentrySpanStatus.h in Headers */,
8ECC673D25C23996000E2BF6 /* SentrySpanId.h in Headers */,
Expand Down Expand Up @@ -4547,6 +4563,7 @@
63FE712F20DA4C1100CDBAE8 /* SentryCrashSysCtl.c in Sources */,
7B3B473825D6CC7E00D01640 /* SentryNSError.m in Sources */,
621AE74D2C626C510012E730 /* SentryANRTrackerV2.m in Sources */,
84CFA4CA2C9DF884008DA5F4 /* SentryUserFeedbackWidget.swift in Sources */,
D8ACE3C82762187200F5A213 /* SentryNSDataTracker.m in Sources */,
7BE3C77D2446112C00A38442 /* SentryRateLimitParser.m in Sources */,
51B15F7E2BE88A7C0026A2F2 /* URLSessionTaskHelper.swift in Sources */,
Expand Down Expand Up @@ -4582,6 +4599,7 @@
7B63459F280EBA7200CFA05A /* SentryUIEventTracker.m in Sources */,
7BF9EF782722B35D00B5BBEF /* SentrySubClassFinder.m in Sources */,
D80CD8D32B751447002F710B /* SentryMXCallStackTree.swift in Sources */,
84CFA4CD2C9E0CA3008DA5F4 /* SentryUserFeedbackIntegrationShell.m in Sources */,
7BCFA71627D0BB50008C662C /* SentryANRTrackerV1.m in Sources */,
8459FCC02BD73EB20038E9C9 /* SentryProfilerSerialization.mm in Sources */,
621C884A2CAD23E9000EABCB /* SentryCaptureTransactionWithProfile.mm in Sources */,
Expand Down Expand Up @@ -4623,6 +4641,7 @@
84354E1229BF944900CDBB8B /* SentryProfileTimeseries.mm in Sources */,
D85852B627ECEEDA00C6D8AE /* SentryScreenshot.m in Sources */,
7D5C441C237C2E1F00DAB0A3 /* SentryHub.m in Sources */,
84E13B842CBF1D91003B52EC /* SentryUserFeedbackWidgetButtonMegaphoneIconView.swift in Sources */,
63FE715920DA4C1100CDBAE8 /* SentryCrashCPU_x86_32.c in Sources */,
D8C66A372A77B1F70015696A /* SentryPropagationContext.m in Sources */,
7BE912AD272162D900E49E62 /* SentryNoOpSpan.m in Sources */,
Expand Down Expand Up @@ -4717,6 +4736,7 @@
635B3F391EBC6E2500A6176D /* SentryAsynchronousOperation.m in Sources */,
63FE717520DA4C1100CDBAE8 /* SentryCrash.m in Sources */,
6344DDB11EC308E400D9160D /* SentryCrashInstallationReporter.m in Sources */,
84BA62272CAE2EEF0049F636 /* SentryUserFeedbackWidgetButtonView.swift in Sources */,
D85596F3280580F10041FF8B /* SentryScreenshotIntegration.m in Sources */,
7BAF3DCE243DCBFE008A5414 /* SentryTransportFactory.m in Sources */,
844EDC70294143B900C86F34 /* SentryNSProcessInfoWrapper.mm in Sources */,
Expand Down
6 changes: 6 additions & 0 deletions Sources/Sentry/NSLocale+Sentry.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@ + (BOOL)timeIs24HourFormat
return is24Hour;
}

+ (BOOL)isRightToLeftLanguage
{
return [NSLocale characterDirectionForLanguage:NSLocale.currentLocale.languageCode]
== NSLocaleLanguageDirectionRightToLeft;
}

@end
Loading

0 comments on commit 1a790ba

Please sign in to comment.