Skip to content

Commit

Permalink
Add contact support button
Browse files Browse the repository at this point in the history
  • Loading branch information
vegaro committed Jul 29, 2024
1 parent 7a9e3e9 commit 7dc9861
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ enum CustomerCenterConfigTestData {
"cancel": "Cancel",
"back": "Back"
]
)
),
support: .init(email: "support@revenuecat.com")
)

static let subscriptionInformationMonthlyRenewing: SubscriptionInformation = .init(
Expand Down
21 changes: 16 additions & 5 deletions RevenueCatUI/CustomerCenter/Data/CustomerCenterEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,22 @@ struct LocalizationKey: EnvironmentKey {

}

extension CustomerCenterConfigData.Localization {
struct AppearanceKey: EnvironmentKey {

/// Default ``CustomerCenterConfigData.Localization`` value for Environment usage
public static let `default` = CustomerCenterConfigData.Localization(locale: "en_US", localizedStrings: [:])
static let defaultValue: CustomerCenterConfigData.Appearance = .default

}

struct AppearanceKey: EnvironmentKey {
struct SupportKey: EnvironmentKey {

static let defaultValue: CustomerCenterConfigData.Appearance = .default
static let defaultValue: CustomerCenterConfigData.Support? = nil

}

extension CustomerCenterConfigData.Localization {

/// Default ``CustomerCenterConfigData.Localization`` value for Environment usage
public static let `default` = CustomerCenterConfigData.Localization(locale: "en_US", localizedStrings: [:])

}

Expand All @@ -53,4 +59,9 @@ extension EnvironmentValues {
set { self[AppearanceKey.self] = newValue }
}

var supportInformation: CustomerCenterConfigData.Support? {
get { self[SupportKey.self] }
set { self[SupportKey.self] = newValue }
}

}
23 changes: 16 additions & 7 deletions RevenueCatUI/CustomerCenter/URLUtilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,28 @@
//

import Foundation
import SwiftUI

enum URLUtilities {

static func createMailURL() -> URL? {
let subject = "Support Request"
let body = "Please describe your issue or question."
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(visionOS, unavailable)
static func createMailURLIfPossible(email: String, subject: String, body: String) -> URL? {
let encodedSubject = subject.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
let encodedBody = body.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""

// swiftlint:disable:next todo
// TODO: make configurable
let urlString = "mailto:support@revenuecat.com?subject=\(encodedSubject)&body=\(encodedBody)"
return URL(string: urlString)
let urlString = "mailto:\(email)?subject=\(encodedSubject)&body=\(encodedBody)"

#if os(iOS)
if let url = URL(string: urlString),
UIApplication.shared.canOpenURL(url) {
return url
}
#endif
return nil
}

}
2 changes: 2 additions & 0 deletions RevenueCatUI/CustomerCenter/Views/CustomerCenterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public struct CustomerCenterView: View {

private var localization: CustomerCenterConfigData.Localization
private var appearance: CustomerCenterConfigData.Appearance
private var supportInformation: CustomerCenterConfigData.Support?

/// Create a view to handle common customer support tasks
public init(customerCenterActionHandler: CustomerCenterActionHandler? = nil,
Expand Down Expand Up @@ -59,6 +60,7 @@ public struct CustomerCenterView: View {
destinationView(configuration: configuration)
.environment(\.localization, configuration.localization)
.environment(\.appearance, configuration.appearance)
.environment(\.supportInformation, configuration.support)
}
}
}
Expand Down
25 changes: 13 additions & 12 deletions RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,14 @@ import SwiftUI
@available(visionOS, unavailable)
struct ManageSubscriptionsView: View {

@Environment(\.openURL)
var openURL

@Environment(\.appearance)
private var appearance: CustomerCenterConfigData.Appearance
@Environment(\.localization)
private var localization: CustomerCenterConfigData.Localization

@StateObject
private var viewModel: ManageSubscriptionsViewModel

@Environment(\.localization)
private var localization: CustomerCenterConfigData.Localization

init(screen: CustomerCenterConfigData.Screen,
customerCenterActionHandler: CustomerCenterActionHandler?) {
let viewModel = ManageSubscriptionsViewModel(screen: screen,
Expand Down Expand Up @@ -87,7 +83,7 @@ struct ManageSubscriptionsView: View {

if let subscriptionInformation = self.viewModel.subscriptionInformation {
SubscriptionDetailsView(subscriptionInformation: subscriptionInformation,
localization: localization,
localization: self.localization,
refundRequestStatusMessage: self.viewModel.refundRequestStatusMessage)
}

Expand Down Expand Up @@ -251,15 +247,20 @@ struct ManageSubscriptionsButtonsView: View {
var viewModel: ManageSubscriptionsViewModel
@Binding
var loadingPath: CustomerCenterConfigData.HelpPath?
@Environment(\.openURL)
var openURL

@Environment(\.localization)
private var localization: CustomerCenterConfigData.Localization

var body: some View {
VStack(spacing: 16) {
let filteredPaths = self.viewModel.screen.paths.filter { path in
#if targetEnvironment(macCatalyst)
return path.type == .refundRequest
#else
return true
#endif
#if targetEnvironment(macCatalyst)
return path.type == .refundRequest
#else
return true
#endif
}
ForEach(filteredPaths, id: \.id) { path in
ManageSubscriptionButton(path: path, viewModel: self.viewModel)
Expand Down
20 changes: 19 additions & 1 deletion RevenueCatUI/CustomerCenter/Views/RestorePurchasesAlert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ struct RestorePurchasesAlert: ViewModifier {
private var alertType: AlertType = .restorePurchases
@Environment(\.dismiss)
private var dismiss
@Environment(\.localization)
private var localization
@Environment(\.supportInformation)
private var supportInformation: CustomerCenterConfigData.Support?

enum AlertType: Identifiable {
case purchasesRecovered, purchasesNotFound, restorePurchases
Expand Down Expand Up @@ -75,7 +79,21 @@ struct RestorePurchasesAlert: ViewModifier {
return Alert(title: Text(""),
message: Text("We couldn’t find any additional purchases under this account. \n\n" +
"Contact support for assistance if you think this is an error."),
dismissButton: .default(Text("Dismiss")) {
primaryButton: .default(Text(localization.commonLocalizedString(for: .contactSupport)),
action: {
if let supportInformation = self.supportInformation {
let subject = self.localization.commonLocalizedString(for: .defaultSubject)
let body = self.localization.commonLocalizedString(for: .defaultBody)
if let url = URLUtilities.createMailURLIfPossible(email: supportInformation.email,
subject: subject,
body: body) {
Task {
openURL(url)
}
}
}
}),
secondaryButton: .default(Text("Dismiss")) {
dismiss()
})
}
Expand Down
38 changes: 35 additions & 3 deletions Sources/CustomerCenter/CustomerCenterConfigData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@

import Foundation

// swiftlint:disable missing_docs
// swiftlint:disable missing_docs nesting file_length
public typealias RCColor = PaywallColor

// swiftlint:disable nesting
public struct CustomerCenterConfigData {

public let screens: [Screen.ScreenType: Screen]
public let appearance: Appearance
public let localization: Localization
public let support: Support

public init(screens: [Screen.ScreenType: Screen], appearance: Appearance, localization: Localization) {
public init(screens: [Screen.ScreenType: Screen],
appearance: Appearance,
localization: Localization,
support: Support) {
self.screens = screens
self.appearance = appearance
self.localization = localization
self.support = support
}

public struct Localization {
Expand Down Expand Up @@ -60,6 +64,9 @@ public struct CustomerCenterConfigData {
case subEarliestExpiration = "sub_earliest_expiration"
case subEarliestRenewal = "sub_earliest_renewal"
case subExpired = "sub_expired"
case contactSupport = "contact_support"
case defaultBody = "default_body"
case defaultSubject = "default_subject"

var defaultValue: String {
switch self {
Expand Down Expand Up @@ -97,6 +104,12 @@ public struct CustomerCenterConfigData {
return "This is your subscription with the earliest billing date."
case .subExpired:
return "This subscription has expired."
case .contactSupport:
return "Contact support"
case .defaultBody:
return "Please describe your issue or question."
case .defaultSubject:
return "Support Request"
}
}

Expand Down Expand Up @@ -267,6 +280,16 @@ public struct CustomerCenterConfigData {

}

public struct Support {

public let email: String

public init(email: String) {
self.email = email
}

}

}

@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
Expand All @@ -280,6 +303,7 @@ extension CustomerCenterConfigData {
let type = CustomerCenterConfigData.Screen.ScreenType(from: $0.key)
return (type, Screen(from: $0.value, localization: localization))
})
self.support = Support(from: response.customerCenter.support)
}

}
Expand Down Expand Up @@ -396,3 +420,11 @@ extension CustomerCenterConfigData.HelpPath.FeedbackSurvey.Option {
}

}

extension CustomerCenterConfigData.Support {

init(from response: CustomerCenterConfigResponse.Support) {
self.email = response.email
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ func checkCustomerCenterConfigData(_ data: CustomerCenterConfigData) {
let screens: [CustomerCenterConfigData.Screen.ScreenType: CustomerCenterConfigData.Screen] = data.screens
let appearance: CustomerCenterConfigData.Appearance = data.appearance
let localization: CustomerCenterConfigData.Localization = data.localization
let support: CustomerCenterConfigData.Support = data.support

let _: CustomerCenterConfigData = .init(screens: screens, appearance: appearance, localization: localization)
let _: CustomerCenterConfigData = .init(screens: screens,
appearance: appearance,
localization: localization,
support: support)
}

func checkHelpPath(_ path: CustomerCenterConfigData.HelpPath) {
Expand Down

0 comments on commit 7dc9861

Please sign in to comment.