diff --git a/Flinky.xcodeproj/project.pbxproj b/Flinky.xcodeproj/project.pbxproj index daa23ab..4a78979 100644 --- a/Flinky.xcodeproj/project.pbxproj +++ b/Flinky.xcodeproj/project.pbxproj @@ -1884,7 +1884,7 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/getsentry/sentry-cocoa"; requirement = { - branch = main; + branch = "philprime/feedback-show-form-button"; kind = branch; }; }; diff --git a/Flinky.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Flinky.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1b1d4a7..7431653 100644 --- a/Flinky.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Flinky.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,8 +15,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/getsentry/sentry-cocoa", "state" : { - "branch" : "main", - "revision" : "5d81ddcd2a3df4f6825797d8d5c39a589da195ba" + "branch" : "philprime/feedback-show-form-button", + "revision" : "5c6740d29d13c13e7990906a0e72bae22573479b" } }, { diff --git a/Targets/App/Sources/Generated/L10n.swift b/Targets/App/Sources/Generated/L10n.swift index 4259079..fa05fbf 100644 --- a/Targets/App/Sources/Generated/L10n.swift +++ b/Targets/App/Sources/Generated/L10n.swift @@ -281,6 +281,16 @@ internal enum L10n { internal static let label = L10n.tr("shared.button.edit.accessibility.label", fallback: "Edit") } } + internal enum Feedback { + /// Send Feedback + internal static let label = L10n.tr("shared.button.feedback.label", fallback: "Send Feedback") + internal enum Accessibility { + /// Send feedback to help improve the app + internal static let hint = L10n.tr("shared.button.feedback.accessibility.hint", fallback: "Send feedback to help improve the app") + /// Send Feedback + internal static let label = L10n.tr("shared.button.feedback.accessibility.label", fallback: "Send Feedback") + } + } internal enum NewLink { internal enum Accessibility { /// Create a new link in this list diff --git a/Targets/App/Sources/Resources/Localizable.xcstrings b/Targets/App/Sources/Resources/Localizable.xcstrings index 8f086bc..0666494 100644 --- a/Targets/App/Sources/Resources/Localizable.xcstrings +++ b/Targets/App/Sources/Resources/Localizable.xcstrings @@ -1026,6 +1026,42 @@ } } }, + "shared.button.feedback.accessibility.hint": { + "comment": "Feedback button accessibility hint", + "extractionState": "manual", + "localizations": { + "en": { + "stringUnit": { + "state": "translated", + "value": "Send feedback to help improve the app" + } + } + } + }, + "shared.button.feedback.accessibility.label": { + "comment": "Feedback button accessibility label", + "extractionState": "manual", + "localizations": { + "en": { + "stringUnit": { + "state": "translated", + "value": "Send Feedback" + } + } + } + }, + "shared.button.feedback.label": { + "comment": "Feedback button text", + "extractionState": "manual", + "localizations": { + "en": { + "stringUnit": { + "state": "translated", + "value": "Send Feedback" + } + } + } + }, "shared.color-picker.accessibility.label": { "comment": "Color picker accessibility label", "extractionState": "manual", diff --git a/Targets/App/Sources/UI/CreateLinkEditor/CreateLinkEditorRenderView.swift b/Targets/App/Sources/UI/CreateLinkEditor/CreateLinkEditorRenderView.swift index bd8ccba..aae8313 100644 --- a/Targets/App/Sources/UI/CreateLinkEditor/CreateLinkEditorRenderView.swift +++ b/Targets/App/Sources/UI/CreateLinkEditor/CreateLinkEditorRenderView.swift @@ -1,4 +1,6 @@ import SwiftUI +import SFSafeSymbols +import Sentry struct CreateLinkEditorRenderView: View { private enum CreateField { @@ -55,6 +57,16 @@ struct CreateLinkEditorRenderView: View { .accessibilityHint(L10n.Shared.Button.Cancel.Accessibility.hint) .accessibilityIdentifier("create-link.cancel.button") } + ToolbarItem(placement: .topBarTrailing) { + Button(action: { + SentrySDK.feedback.showForm() + }, label: { + Label(L10n.Shared.Button.Feedback.label, systemSymbol: .megaphone) + }) + .accessibilityLabel(L10n.Shared.Button.Feedback.Accessibility.label) + .accessibilityHint(L10n.Shared.Button.Feedback.Accessibility.hint) + .accessibilityIdentifier("create-link.feedback.button") + } ToolbarItem(placement: .confirmationAction) { if #available(iOS 26, *) { Button(role: .confirm) { diff --git a/Targets/App/Sources/UI/CreateListEditor/CreateLinkListEditorRenderView.swift b/Targets/App/Sources/UI/CreateListEditor/CreateLinkListEditorRenderView.swift index 20b0eff..7e7bb40 100644 --- a/Targets/App/Sources/UI/CreateListEditor/CreateLinkListEditorRenderView.swift +++ b/Targets/App/Sources/UI/CreateListEditor/CreateLinkListEditorRenderView.swift @@ -1,3 +1,5 @@ +import SFSafeSymbols +import Sentry import SwiftUI struct CreateLinkListEditorRenderView: View { @@ -27,6 +29,16 @@ struct CreateLinkListEditorRenderView: View { .navigationTitle(L10n.CreateList.title) .accessibilityIdentifier("create-link-list.container") .toolbar { + ToolbarItem(placement: .topBarTrailing) { + Button(action: { + SentrySDK.feedback.showForm() + }, label: { + Label(L10n.Shared.Button.Feedback.label, systemSymbol: .megaphone) + }) + .accessibilityLabel(L10n.Shared.Button.Feedback.Accessibility.label) + .accessibilityHint(L10n.Shared.Button.Feedback.Accessibility.hint) + .accessibilityIdentifier("create-link-list.feedback.button") + } ToolbarItem(placement: .cancellationAction) { Button(role: .cancel) { dismiss() diff --git a/Targets/App/Sources/UI/LinkDetail/LinkDetailRenderView.swift b/Targets/App/Sources/UI/LinkDetail/LinkDetailRenderView.swift index 0bcb80f..14c7e7f 100644 --- a/Targets/App/Sources/UI/LinkDetail/LinkDetailRenderView.swift +++ b/Targets/App/Sources/UI/LinkDetail/LinkDetailRenderView.swift @@ -32,6 +32,16 @@ struct LinkDetailRenderView: View { } .background(Color(UIColor.systemGroupedBackground)) .toolbar { + ToolbarItemGroup(placement: .topBarLeading) { + Button(action: { + SentrySDK.feedback.showForm() + }, label: { + Label(L10n.Shared.Button.Feedback.label, systemSymbol: .megaphone) + }) + .accessibilityLabel(L10n.Shared.Button.Feedback.Accessibility.label) + .accessibilityHint(L10n.Shared.Button.Feedback.Accessibility.hint) + .accessibilityIdentifier("link-detail.feedback.button") + } ToolbarItemGroup(placement: .topBarLeading) { Menu { Button { diff --git a/Targets/App/Sources/UI/LinkInfo/LinkInfoRenderView.swift b/Targets/App/Sources/UI/LinkInfo/LinkInfoRenderView.swift index 75faa90..6dc1a90 100644 --- a/Targets/App/Sources/UI/LinkInfo/LinkInfoRenderView.swift +++ b/Targets/App/Sources/UI/LinkInfo/LinkInfoRenderView.swift @@ -1,5 +1,6 @@ import FlinkyCore import SFSafeSymbols +import Sentry import SwiftUI struct LinkInfoRenderView: View { @@ -34,6 +35,16 @@ struct LinkInfoRenderView: View { .accessibilityHint(L10n.Shared.Button.Cancel.Accessibility.hint) .accessibilityIdentifier("link-info.cancel.button") } + ToolbarItem(placement: .topBarTrailing) { + Button(action: { + SentrySDK.feedback.showForm() + }, label: { + Label(L10n.Shared.Button.Feedback.label, systemSymbol: .megaphone) + }) + .accessibilityLabel(L10n.Shared.Button.Feedback.Accessibility.label) + .accessibilityHint(L10n.Shared.Button.Feedback.Accessibility.hint) + .accessibilityIdentifier("link-info.feedback.button") + } if #available(iOS 26, *) { ToolbarItem(placement: .confirmationAction) { Button(role: .confirm) { @@ -171,8 +182,8 @@ extension LinkInfoRenderView { .font(.system(size: 22, weight: .medium)) .foregroundStyle( symbol.isEmoji - ? Color.blue - : (colorScheme == .light ? Color.gray.mix(with: Color.black, by: 0.3) : Color.gray) + ? Color.blue + : (colorScheme == .light ? Color.gray.mix(with: Color.black, by: 0.3) : Color.gray) ) .frame(maxWidth: .infinity, maxHeight: .infinity) .padding(6) @@ -180,7 +191,7 @@ extension LinkInfoRenderView { .frame(maxWidth: .infinity, maxHeight: .infinity) .background( symbol.isEmoji - ? Color.blue.opacity(0.15) : Color.gray.opacity(colorScheme == .light ? 0.1 : 0.2) + ? Color.blue.opacity(0.15) : Color.gray.opacity(colorScheme == .light ? 0.1 : 0.2) ) .clipShape(Circle()) .contentShape(Circle()) diff --git a/Targets/App/Sources/UI/LinkListDetail/LinkListDetailRenderView.swift b/Targets/App/Sources/UI/LinkListDetail/LinkListDetailRenderView.swift index 165a66f..041a975 100644 --- a/Targets/App/Sources/UI/LinkListDetail/LinkListDetailRenderView.swift +++ b/Targets/App/Sources/UI/LinkListDetail/LinkListDetailRenderView.swift @@ -1,4 +1,5 @@ import SFSafeSymbols +import Sentry import SwiftUI struct LinkListDetailRenderView: View { @@ -29,6 +30,16 @@ struct LinkListDetailRenderView: View { ToolbarItem(placement: .navigationBarTrailing) { moreMenu } + ToolbarItem(placement: .topBarTrailing) { + Button(action: { + SentrySDK.feedback.presentUI() + }, label: { + Label(L10n.Shared.Button.Feedback.label, systemSymbol: .megaphone) + }) + .accessibilityLabel(L10n.Shared.Button.Feedback.Accessibility.label) + .accessibilityHint(L10n.Shared.Button.Feedback.Accessibility.hint) + .accessibilityIdentifier("link-list-detail.feedback.button") + } if #available(iOS 26, *) { ToolbarItem(placement: .bottomBar) { Spacer() diff --git a/Targets/App/Sources/UI/LinkLists/LinkListsContainerView.swift b/Targets/App/Sources/UI/LinkLists/LinkListsContainerView.swift index 75e7adc..94b9a8e 100644 --- a/Targets/App/Sources/UI/LinkLists/LinkListsContainerView.swift +++ b/Targets/App/Sources/UI/LinkLists/LinkListsContainerView.swift @@ -188,11 +188,6 @@ struct LinkListsContainerView: View { } } .sentryTrace("LINK_LISTS_VIEW") - .onAppear { - // Auto-injecting Sentry feedback widget is currently not supported in SwiftUI. - // Therefore we manually trigger it when the view appears. - SentrySDK.feedback.showWidget() - } } var pinnedListDisplayItems: [LinkListsDisplayItem] { diff --git a/Targets/App/Sources/UI/LinkLists/LinkListsRenderView.swift b/Targets/App/Sources/UI/LinkLists/LinkListsRenderView.swift index fed4c47..3f274f8 100644 --- a/Targets/App/Sources/UI/LinkLists/LinkListsRenderView.swift +++ b/Targets/App/Sources/UI/LinkLists/LinkListsRenderView.swift @@ -1,4 +1,5 @@ import SFSafeSymbols +import Sentry import SwiftUI struct LinkListsRenderView: View { @@ -95,6 +96,16 @@ struct LinkListsRenderView: View { .accessibilityIdentifier("link-lists.create-link.button") } } + ToolbarItem(placement: .topBarTrailing) { + Button(action: { + SentrySDK.feedback.presentUI() + }, label: { + Label(L10n.Shared.Button.Feedback.label, systemSymbol: .megaphone) + }) + .accessibilityLabel(L10n.Shared.Button.Feedback.Accessibility.label) + .accessibilityHint(L10n.Shared.Button.Feedback.Accessibility.hint) + .accessibilityIdentifier("link-lists.feedback.button") + } ToolbarItem(placement: .topBarTrailing) { Button( action: {