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 all commits
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"
}

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"
}

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