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(user feedback): display a button in a window that presents a vc #4364

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c1de18f
display a button in a window that presents a vc
armcknight Sep 24, 2024
e0f9cf9
early pr feedback
armcknight Sep 25, 2024
cae7c7b
Merge remote-tracking branch 'origin/main' into armcknight/feat(user-…
armcknight Oct 2, 2024
0430690
iterating on styling the button
armcknight Oct 2, 2024
61672ff
wip building the megaphone path from svg
armcknight Oct 3, 2024
8405700
fixup! wip building the megaphone path from svg
armcknight Oct 3, 2024
0cdd625
fixup! wip building the megaphone path from svg
armcknight Oct 3, 2024
55c592b
fixup! wip building the megaphone path from svg
armcknight Oct 3, 2024
f5b0250
lay out button elements
armcknight Oct 3, 2024
bf754c7
draw the lozenge
armcknight Oct 3, 2024
bef728e
separating into different files
armcknight Oct 3, 2024
201979c
threading through other parts of the config; icon-only widget
armcknight Oct 3, 2024
dfc9bc9
threading through more theme settings to widget
armcknight Oct 3, 2024
ba35047
add launch arg to show icon-only widget
armcknight Oct 3, 2024
dcc2e03
put back rename so the diff is smaller
armcknight Oct 4, 2024
68f32fe
more config testing
armcknight Oct 4, 2024
7b35acb
wip centering megaphone (☑️) and lozenge (wip) to label
armcknight Oct 9, 2024
846b8ae
fixed centering text/icon in lozenges for all fonts
armcknight Oct 10, 2024
657d773
fixup! fixed centering text/icon in lozenges for all fonts
armcknight Oct 10, 2024
c5b3a57
fixup! fixed centering text/icon in lozenges for all fonts
armcknight Oct 10, 2024
9bd3adb
add option to hide button icon; adjust defaults/launchargs
armcknight Oct 15, 2024
7bb36ef
fixup! fixed centering text/icon in lozenges for all fonts
armcknight Oct 15, 2024
9f04781
annotate megaphone drawing
armcknight Oct 15, 2024
602c777
wip showing button with only text or only icon
armcknight Oct 15, 2024
22490e0
extract megaphone to own UIView subclass; adaptive scaling of vertica…
armcknight Oct 15, 2024
647740a
Merge remote-tracking branch 'origin/main' into armcknight/feat(user-…
armcknight Oct 15, 2024
f828a92
remove old test script
armcknight Oct 15, 2024
abc5119
wip on right to left support: megaphone location/direction
armcknight Oct 16, 2024
7e60d57
constrain to UIKit
armcknight Oct 16, 2024
e43f64d
add accessibility label
armcknight Oct 16, 2024
283b775
Merge remote-tracking branch 'origin/main' into armcknight/feat(user-…
armcknight Oct 16, 2024
5bfdc59
fix macOS and tvOS builds
armcknight Oct 16, 2024
e928971
fix iOS-ObjectiveC build
armcknight Oct 16, 2024
be4eb19
support dynamic type accessibility sizes
armcknight Oct 16, 2024
0f7ba54
only support ios 13+ for now
armcknight Oct 18, 2024
a2f8120
fixup! only support ios 13+ for now
armcknight Oct 18, 2024
1bc5a95
fix deprecation/rename
armcknight Oct 18, 2024
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
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 @@ -699,8 +699,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 @@ -1755,9 +1760,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 @@ -3496,6 +3506,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 @@ -3954,6 +3969,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 @@ -4537,6 +4553,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 @@ -4571,6 +4588,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 @@ -4612,6 +4630,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 @@ -4706,6 +4725,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 @@
return is24Hour;
}

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

Check warning on line 21 in Sources/Sentry/NSLocale+Sentry.m

View check run for this annotation

Codecov / codecov/patch

Sources/Sentry/NSLocale+Sentry.m#L19-L21

Added lines #L19 - L21 were not covered by tests

@end
Loading
Loading