forked from woocommerce/woocommerce-ios
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInAppFeedbackCardViewController.swift
164 lines (128 loc) · 5.3 KB
/
InAppFeedbackCardViewController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import UIKit
import StoreKit
/// Defines methods for presenting the in-app app store review form.
///
protocol SKStoreReviewControllerProtocol {
/// Displays the in app app store review alert.
///
static func requestReview()
}
extension SKStoreReviewController: SKStoreReviewControllerProtocol { }
/// Displays a small view asking the user to provide a feedback for the app.
///
final class InAppFeedbackCardViewController: UIViewController {
@IBOutlet private var titleLabel: UILabel!
@IBOutlet private var didNotLikeButton: UIButton!
@IBOutlet private var likeButton: UIButton!
/// Closure invoked after the user has chosen what kind feedback to give.
var onFeedbackGiven: (() -> Void)?
/// The stackview containing the `titleLabel` and the horizontal view for the buttons.
@IBOutlet private var verticalStackView: UIStackView!
/// SKStoreReviewController type wrapper. Needed for testing
private let storeReviewControllerType: SKStoreReviewControllerProtocol.Type
private let analytics: Analytics
init(storeReviewControllerType: SKStoreReviewControllerProtocol.Type = SKStoreReviewController.self,
analytics: Analytics = ServiceLocator.analytics) {
self.storeReviewControllerType = storeReviewControllerType
self.analytics = analytics
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
configureVerticalStackView()
configureTitleLabel()
configureDidNotLikeButton()
configureLikeButton()
view.backgroundColor = .listForeground
}
}
// MARK: - Provisioning
private extension InAppFeedbackCardViewController {
func configureVerticalStackView() {
verticalStackView.isLayoutMarginsRelativeArrangement = true
verticalStackView.layoutMargins = .init(top: 0, left: 16, bottom: 0, right: 16)
}
func configureTitleLabel() {
titleLabel.applyBodyStyle()
titleLabel.numberOfLines = 0
titleLabel.text = Localization.enjoyingTheWooCommerceApp
}
func configureDidNotLikeButton() {
didNotLikeButton.applySecondaryButtonStyle()
didNotLikeButton.setTitle(Localization.couldBeBetter, for: .normal)
didNotLikeButton.on(.touchUpInside) { [weak self] _ in
guard let self = self else {
return
}
let surveyNavigation = SurveyCoordinatingController(survey: .inAppFeedback)
self.present(surveyNavigation, animated: true, completion: nil)
self.onFeedbackGiven?()
self.analytics.track(event: .appFeedbackPrompt(action: .didntLike))
}
}
func configureLikeButton() {
likeButton.applyPrimaryButtonStyle()
likeButton.setTitle(Localization.iLikeIt, for: .normal)
likeButton.on(.touchUpInside) { [weak self] _ in
guard let self = self else {
return
}
self.storeReviewControllerType.requestReview()
self.onFeedbackGiven?()
self.analytics.track(event: .appFeedbackPrompt(action: .liked))
}
}
}
// MARK: - Constants
private extension InAppFeedbackCardViewController {
enum Localization {
static let enjoyingTheWooCommerceApp = NSLocalizedString("Enjoying the WooCommerce app?",
comment: "The title used when asking the user for feedback for the app.")
static let couldBeBetter = NSLocalizedString("Could Be Better",
comment: "The title of the button for giving a negative feedback for the app.")
static let iLikeIt = NSLocalizedString("I Like It",
comment: "The title of the button for giving a positive feedback for the app.")
}
}
// MARK: - Previews
#if canImport(SwiftUI) && DEBUG
import SwiftUI
private struct InAppFeedbackCardViewControllerRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let viewController = InAppFeedbackCardViewController()
return viewController.view
}
func updateUIView(_ view: UIView, context: Context) {
// noop
}
}
struct InAppFeedbackCardViewController_Previews: PreviewProvider {
private static func makeStack() -> some View {
VStack {
InAppFeedbackCardViewControllerRepresentable()
}
}
static var previews: some View {
Group {
makeStack()
.previewLayout(.fixed(width: 320, height: 148))
.previewDisplayName("Light")
makeStack()
.previewLayout(.fixed(width: 375, height: 128))
.environment(\.colorScheme, .dark)
.previewDisplayName("Dark")
makeStack()
.previewLayout(.fixed(width: 414, height: 528))
.environment(\.sizeCategory, .accessibilityExtraExtraExtraLarge)
.previewDisplayName("Large Font")
makeStack()
.previewLayout(.fixed(width: 896, height: 128))
.environment(\.colorScheme, .dark)
.previewDisplayName("Large Width - Dark")
}
}
}
#endif