Skip to content
This repository has been archived by the owner on May 6, 2024. It is now read-only.

chore: learner feedback collection from the mobile app #1819

Merged
merged 2 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
2 changes: 2 additions & 0 deletions Source/OEXAnalytics+Swift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public enum AnalyticsDisplayName : String {
case PrivacyPolicyClicked = "Privacy Policy Clicked"
case CookiePolicyClicked = "Cookie Policy Clicked"
case DataSellConsentClicked = "Do Not Sell Data Clicked"
case SubmitFeedbackCLicked = "Submit feedback clicked"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: SubmitFeedbackCLicked to SubmitFeedbackClicked

}

public enum AnalyticsEventName: String {
Expand Down Expand Up @@ -194,6 +195,7 @@ public enum AnalyticsEventName: String {
case PrivacyPolicyClicked = "edx.bi.app.profile.privacy_policy.clicked"
case CookiePolicyClicked = "edx.bi.app.profile.cookie_policy.clicked"
case DataSellConsentClicked = "edx.bi.app.profile.do_not_sell_data.clicked"
case SubmitFeedbackCLicked = "edx.bi.app.profile.submit_feedback.clicked"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: SubmitFeedbackCLicked to SubmitFeedbackClicked

}

public enum AnalyticsScreenName: String {
Expand Down
57 changes: 49 additions & 8 deletions Source/ProfileOptionsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ProfileOptionsViewController: UIViewController {
case personalInformation
case restorePurchase
case privacy
case help(Bool, Bool)
case help(Bool, Bool, Bool)
case signout
case deleteAccount
}
Expand Down Expand Up @@ -139,10 +139,11 @@ class ProfileOptionsViewController: UIViewController {
}

let feedbackEnabled = environment.config.feedbackEmailAddress() != nil
let submitFeedbackEnabled = environment.serverConfig.feedbackFormURL != nil
let faqEnabled = environment.config.faqURL != nil

if feedbackEnabled || faqEnabled {
options.append(.help(feedbackEnabled, faqEnabled))
options.append(.help(feedbackEnabled, submitFeedbackEnabled, faqEnabled))
}

options.append(.signout)
Expand Down Expand Up @@ -217,8 +218,8 @@ extension ProfileOptionsViewController: UITableViewDataSource {
case .privacy:
return privacyCell(tableView, indexPath: indexPath)

case .help(let feedbackEnabled, let faqEnabled):
return helpCell(tableView, indexPath: indexPath, feedbackEnabled: feedbackEnabled, faqEnabled: faqEnabled)
case .help(let feedbackEnabled, let submitFeedbackEnabled, let faqEnabled):
return helpCell(tableView, indexPath: indexPath, feedbackEnabled: feedbackEnabled, submitFeedbackEnabled: submitFeedbackEnabled, faqEnabled: faqEnabled)

case .signout:
return signoutCell(tableView, indexPath: indexPath)
Expand Down Expand Up @@ -271,10 +272,10 @@ extension ProfileOptionsViewController: UITableViewDataSource {
return cell
}

private func helpCell(_ tableView: UITableView, indexPath: IndexPath, feedbackEnabled: Bool, faqEnabled: Bool) -> UITableViewCell {
private func helpCell(_ tableView: UITableView, indexPath: IndexPath, feedbackEnabled: Bool, submitFeedbackEnabled: Bool, faqEnabled: Bool) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: HelpCell.identifier, for: indexPath) as! HelpCell
cell.delegate = self
cell.update(feedbackEnabled: feedbackEnabled, faqEnabled: faqEnabled, platformName: environment.config.platformName())
cell.update(feedbackEnabled: feedbackEnabled, faqEnabled: faqEnabled, submitFeedbackEnabled: submitFeedbackEnabled, platformName: environment.config.platformName())

return cell
}
Expand Down Expand Up @@ -345,6 +346,14 @@ extension ProfileOptionsViewController: HelpCellDelegate {
launchEmailComposer()
}

func didTapSubmitFeedback() {
guard let url = environment.serverConfig.feedbackFormURL else { return }
environment.analytics.trackProfileOptionClcikEvent(displayName: AnalyticsDisplayName.SubmitFeedbackCLicked, name: AnalyticsEventName.SubmitFeedbackCLicked)
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:])
}
}

func didTapFAQ() {
guard let faqURL = environment.config.faqURL, let url = URL(string: faqURL) else { return }
environment.analytics.trackProfileOptionClcikEvent(displayName: AnalyticsDisplayName.FAQClicked, name: AnalyticsEventName.FAQClicked)
Expand Down Expand Up @@ -1132,6 +1141,7 @@ class PrivacyCell: UITableViewCell {

protocol HelpCellDelegate: AnyObject {
func didTapEmail()
func didTapSubmitFeedback()
func didTapFAQ()
}

Expand All @@ -1142,6 +1152,7 @@ class HelpCell: UITableViewCell {

private var feedbackEnabled: Bool = false
private var faqEnabled: Bool = false
private var submitFeedbackEnabled: Bool = false

private let lineSpacing: CGFloat = 4

Expand Down Expand Up @@ -1199,6 +1210,21 @@ class HelpCell: UITableViewCell {
return button
}()

private lazy var submitFeedbackButton: UIButton = {
let button = UIButton()
button.layer.borderWidth = 1
button.layer.borderColor = OEXStyles.shared().neutralXLight().cgColor
button.oex_addAction({ [weak self] _ in
self?.delegate?.didTapSubmitFeedback()
}, for: .touchUpInside)

let faqButtonTitle = [buttonStyle.attributedString(withText: Strings.ProfileOptions.Help.Heading.feedback), faqButtonIcon]
let attributedText = NSAttributedString.joinInNaturalLayout(attributedStrings: faqButtonTitle)
button.setAttributedTitle(attributedText, for: .normal)
button.accessibilityIdentifier = "HelpCell:submit-feedback-button"
return button
}()

private lazy var supportLabel: UILabel = {
let label = UILabel()
label.attributedText = subtitleTextStyle.attributedString(withText: Strings.ProfileOptions.Help.Heading.support)
Expand Down Expand Up @@ -1253,10 +1279,11 @@ class HelpCell: UITableViewCell {
fatalError("init(coder:) has not been implemented")
}

func update(feedbackEnabled: Bool, faqEnabled: Bool, platformName: String) {
func update(feedbackEnabled: Bool, faqEnabled: Bool, submitFeedbackEnabled: Bool, platformName: String) {
self.feedbackEnabled = feedbackEnabled
self.faqEnabled = faqEnabled
self.platformName = platformName
self.submitFeedbackEnabled = submitFeedbackEnabled
setupViews()
setupConstrains()
}
Expand All @@ -1268,6 +1295,9 @@ class HelpCell: UITableViewCell {
feedbackSupportContainer.addSubview(feedbackLabel)
feedbackSupportContainer.addSubview(feedbackSubtitleLabel)
feedbackSupportContainer.addSubview(emailFeedbackButton)
if submitFeedbackEnabled {
feedbackSupportContainer.addSubview(submitFeedbackButton)
}
contentView.addSubview(feedbackSupportContainer)
}

Expand Down Expand Up @@ -1312,8 +1342,19 @@ class HelpCell: UITableViewCell {
make.height.greaterThanOrEqualTo(StandardVerticalMargin * 2)
}

if submitFeedbackEnabled {
submitFeedbackButton.snp.makeConstraints { make in
make.top.equalTo(feedbackSubtitleLabel.snp.bottom).offset(StandardVerticalMargin)
make.leading.equalTo(feedbackSupportContainer)
make.trailing.equalTo(feedbackSupportContainer)
make.height.equalTo(StandardVerticalMargin * 5)
}
}

let constraintView = submitFeedbackEnabled ? submitFeedbackButton : feedbackSubtitleLabel

emailFeedbackButton.snp.makeConstraints { make in
make.top.equalTo(feedbackSubtitleLabel.snp.bottom).offset(StandardVerticalMargin)
make.top.equalTo(constraintView.snp.bottom).offset(StandardVerticalMargin)
make.leading.equalTo(feedbackSupportContainer)
make.trailing.equalTo(feedbackSupportContainer)
make.height.equalTo(StandardVerticalMargin * 5)
Expand Down
3 changes: 3 additions & 0 deletions Source/ServerConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ public extension ServerConfigProvider {
case valuePropEnabled = "value_prop_enabled"
case config = "config"
case iapConfig = "iap_config"
case feedbackFormURL = "feedback_form_url"
}

@objc static let shared = ServerConfiguration()

private(set) var valuePropEnabled: Bool = false
private(set) var iapConfig: IAPConfig? = nil
private(set) var feedbackFormURL: URL? = nil

private override init() {
super.init()
Expand All @@ -41,6 +43,7 @@ public extension ServerConfigProvider {
let config = try? JSONSerialization.jsonObject(with: configData, options : []) as? Dictionary<String,Any> else { return }

valuePropEnabled = config[Keys.valuePropEnabled] as? Bool ?? false
feedbackFormURL = (config[Keys.feedbackFormURL] as? String).flatMap { URL(string:$0)}

if let iapDict = config[Keys.iapConfig] as? Dictionary<String, Any> {
iapConfig = IAPConfig(dictionary: iapDict)
Expand Down
Loading