Skip to content

Commit

Permalink
Merge pull request #4916 from wikimedia/T371428
Browse files Browse the repository at this point in the history
[ALT TEXT] Sprint 1 logging
  • Loading branch information
mazevedofs authored Aug 7, 2024
2 parents b963e50 + a6192b7 commit 26094dc
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ final class WMFAltTextExperimentModalSheetView: WMFComponentView {

weak var viewModel: WMFAltTextExperimentModalSheetViewModel?
weak var delegate: WMFAltTextExperimentModalSheetDelegate?
weak var loggingDelegate: WMFAltTextExperimentModalSheetLoggingDelegate?

private lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
Expand Down Expand Up @@ -99,9 +100,10 @@ final class WMFAltTextExperimentModalSheetView: WMFComponentView {

// MARK: Lifecycle

public init(frame: CGRect, viewModel: WMFAltTextExperimentModalSheetViewModel, delegate: WMFAltTextExperimentModalSheetDelegate?) {
public init(frame: CGRect, viewModel: WMFAltTextExperimentModalSheetViewModel, delegate: WMFAltTextExperimentModalSheetDelegate?, loggingDelegate: WMFAltTextExperimentModalSheetLoggingDelegate?) {
self.viewModel = viewModel
self.delegate = delegate
self.loggingDelegate = loggingDelegate
super.init(frame: frame)
textView.delegate = self
setup()
Expand Down Expand Up @@ -224,6 +226,7 @@ extension WMFAltTextExperimentModalSheetView: UITextViewDelegate {

func textViewDidBeginEditing(_ textView: UITextView) {
placeholder.isHidden = true
loggingDelegate?.didFocusTextView()
}

func textViewDidEndEditing(_ textView: UITextView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ public protocol WMFAltTextExperimentModalSheetDelegate: AnyObject {
func didTapNext(altText: String)
}

public protocol WMFAltTextExperimentModalSheetLoggingDelegate: AnyObject {
func didAppear()
func didFocusTextView()
}

final public class WMFAltTextExperimentModalSheetViewController: WMFCanvasViewController {

weak var viewModel: WMFAltTextExperimentModalSheetViewModel?
weak var delegate: WMFAltTextExperimentModalSheetDelegate?
weak var loggingDelegate: WMFAltTextExperimentModalSheetLoggingDelegate?

public init(viewModel: WMFAltTextExperimentModalSheetViewModel?, delegate: WMFAltTextExperimentModalSheetDelegate?) {
public init(viewModel: WMFAltTextExperimentModalSheetViewModel?, delegate: WMFAltTextExperimentModalSheetDelegate?, loggingDelegate: WMFAltTextExperimentModalSheetLoggingDelegate?) {
self.viewModel = viewModel
self.delegate = delegate
self.loggingDelegate = loggingDelegate
super.init()
}

Expand All @@ -22,9 +29,13 @@ final public class WMFAltTextExperimentModalSheetViewController: WMFCanvasViewCo
override public func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let viewModel else { return }
let view = WMFAltTextExperimentModalSheetView(frame: UIScreen.main.bounds, viewModel: viewModel, delegate: delegate)
let view = WMFAltTextExperimentModalSheetView(frame: UIScreen.main.bounds, viewModel: viewModel, delegate: delegate, loggingDelegate: loggingDelegate)
addComponent(view, pinToEdges: true)
}

public override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
loggingDelegate?.didAppear()
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public protocol WMFImageRecommendationsLoggingDelegate: AnyObject {
func logEmptyStateDidAppear()
func logEmptyStateDidTapBack()
func logDialogWarningMessageDidDisplay(fileName: String, recommendationSource: String)
func logAltTextExperimentDidAssignGroup()
}

fileprivate final class WMFImageRecommendationsHostingViewController: WMFComponentHostingController<WMFImageRecommendationsView> {
Expand Down Expand Up @@ -202,6 +203,7 @@ public final class WMFImageRecommendationsViewController: WMFCanvasViewControlle

do {
try dataController.assignImageRecsExperiment(isLoggedIn: isLoggedIn, project: viewModel.project)
loggingDelegate?.logAltTextExperimentDidAssignGroup()
} catch let error {
debugPrint(error)
return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ public final class WMFImageRecommendationsViewModel: ObservableObject {
public var imageWikitext: String?
public var fullArticleWikitextWithImage: String?
public var suggestionAcceptDate: Date?
public var altTextExperimentAcceptDate: Date?
public var lastRevisionID: UInt64?
public var localizedFileTitle: String?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public final class WMFAltTextDataController {
case invalidDeviceOrOS
case invalidDate
case unexpectedBucketValue
case alreadyAssignedThisExperiment
case alreadyAssignedOtherExperiment
}

Expand Down Expand Up @@ -64,6 +65,10 @@ public final class WMFAltTextDataController {
throw WMFAltTextDataControllerError.invalidDate
}

if experimentsDataController.bucketForExperiment(.altTextImageRecommendations) != nil {
throw WMFAltTextDataControllerError.alreadyAssignedThisExperiment
}

if let articleEditorExperimentBucket = experimentsDataController.bucketForExperiment(.altTextArticleEditor) {

switch articleEditorExperimentBucket {
Expand Down Expand Up @@ -102,6 +107,10 @@ public final class WMFAltTextDataController {
throw WMFAltTextDataControllerError.invalidDate
}

if experimentsDataController.bucketForExperiment(.altTextArticleEditor) != nil {
throw WMFAltTextDataControllerError.alreadyAssignedThisExperiment
}

if let imageRecommendationsExperimentBucket = experimentsDataController.bucketForExperiment(.altTextImageRecommendations) {

switch imageRecommendationsExperimentBucket {
Expand Down
1 change: 1 addition & 0 deletions Wikipedia/Code/ArticleViewController+Editing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ extension ArticleViewController: EditorViewControllerDelegate {

do {
try dataController.assignArticleEditorExperiment(isLoggedIn: isLoggedIn, project: project)
EditInteractionFunnel.shared.logAltTextDidAssignArticleEditorGroup(project: WikimediaProject(wmfProject: project))
} catch let error {
DDLogWarn("Error assigning alt text article editor experiment: \(error)")
}
Expand Down
33 changes: 32 additions & 1 deletion Wikipedia/Code/ArticleViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ class ArticleViewController: ViewController, HintPresenting {
messagingController.hideEditPencils()
messagingController.scrollToNewImage(filename: altTextExperimentViewModel.filename)

let bottomSheetViewController = WMFAltTextExperimentModalSheetViewController(viewModel: altTextBottomSheetViewModel, delegate: self)
let bottomSheetViewController = WMFAltTextExperimentModalSheetViewController(viewModel: altTextBottomSheetViewModel, delegate: self, loggingDelegate: self)

if #available(iOS 16.0, *) {
if let sheet = bottomSheetViewController.sheetPresentationController {
Expand Down Expand Up @@ -1389,8 +1389,39 @@ extension ArticleViewController: UISheetPresentationControllerDelegate {
case .medium, .large:
webView.scrollView.contentInset = UIEdgeInsets(top: oldContentInset.top, left: oldContentInset.left, bottom: view.bounds.height * 0.65, right: oldContentInset.right)
default:
logMinimized()
webView.scrollView.contentInset = UIEdgeInsets(top: oldContentInset.top, left: oldContentInset.left, bottom: 75, right: oldContentInset.right)
}
}
}

private func logMinimized() {
guard let siteURL = articleURL.wmf_site,
let project = WikimediaProject(siteURL: siteURL) else {
return
}

EditInteractionFunnel.shared.logAltTextInputDidMinimize(project: project)
}
}

extension ArticleViewController: WMFAltTextExperimentModalSheetLoggingDelegate {
func didAppear() {

guard let siteURL = articleURL.wmf_site,
let project = WikimediaProject(siteURL: siteURL) else {
return
}

EditInteractionFunnel.shared.logAltTextInputDidAppear(project: project)
}

func didFocusTextView() {
guard let siteURL = articleURL.wmf_site,
let project = WikimediaProject(siteURL: siteURL) else {
return
}

EditInteractionFunnel.shared.logAltTextInputDidFocus(project: project)
}
}
102 changes: 102 additions & 0 deletions Wikipedia/Code/EditInteractionFunnel.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import WMFData

final class EditInteractionFunnel {

Expand Down Expand Up @@ -28,6 +29,10 @@ final class EditInteractionFunnel {
case articleEditPreview = "article_edit_preview"
case articleEditSummary = "article_edit_summary"
case talkEditSummary = "talk_edit_summary"

// Alt-Text-Experiment Items
case altTextEditingOnboarding = "alt_text_editing_onboarding"
case altTextEditingInterface = "alt_text_editing_interface"
}

private enum Action: String {
Expand All @@ -42,6 +47,17 @@ final class EditInteractionFunnel {
case saveAttempt = "save_attempt"
case saveSuccess = "save_success"
case saveFailure = "save_failure"

// Alt-Text-Experiment Items
case groupAssignment = "group_assignment"
case launchImpression = "launch_impression"
case launchCloseClick = "launch_close_click"
case addClick = "add_click"
case doNotAddClick = "do_not_add_click"
case addAltTextImpression = "add_alt_text_impression"
case addAltTextInput = "add_alt_text_input"
case altTextEditSuccess = "alt_text_edit_success"
case minimizedImpression = "minimized_impression"
}

private struct Event: EventInterface {
Expand Down Expand Up @@ -236,4 +252,90 @@ final class EditInteractionFunnel {
let actionData = ["abort_source": ProblemSource.blockedMessageLink.rawValue]
logEvent(activeInterface: .talkEditSummary, action: .editCancel, actionData: actionData, project: project)
}

// MARK: Alt-Text-Experiment

func logAltTextDidAssignImageRecsGroup(project: WikimediaProject) {

guard let group = WMFAltTextDataController.shared?.assignedAltTextImageRecommendationsGroupForLogging() else {
return
}

var actionData: [String: String] = [:]
switch group {
case "A":
actionData["exp_b_group"] = "a"
case "B":
actionData["exp_b_group"] = "b"
default:
assertionFailure("Unexpected experiment group")
}

logEvent(activeInterface: .altTextEditingOnboarding, action: .groupAssignment, actionData: actionData, project: project)
}

func logAltTextDidAssignArticleEditorGroup(project: WikimediaProject) {

guard let group = WMFAltTextDataController.shared?.assignedAltTextArticleEditorGroupForLogging() else {
return
}

var actionData: [String: String] = [:]
switch group {
case "C":
actionData["exp_c_group"] = "c"
case "D":
actionData["exp_c_group"] = "d"
default:
assertionFailure("Unexpected experiment group")
}

logEvent(activeInterface: .altTextEditingOnboarding, action: .groupAssignment, actionData: actionData, project: project)
}

func logAltTextPromptDidAppear(project: WikimediaProject) {
logEvent(activeInterface: .altTextEditingOnboarding, action: .launchImpression, project: project)
}

func logAltTextPromptDidTapClose(project: WikimediaProject) {
logEvent(activeInterface: .altTextEditingOnboarding, action: .launchCloseClick, project: project)
}

func logAltTextPromptDidTapAdd(project: WikimediaProject) {
logEvent(activeInterface: .altTextEditingOnboarding, action: .addClick, project: project)
}

func logAltTextPromptDidTapDoNotAdd(project: WikimediaProject) {
logEvent(activeInterface: .altTextEditingOnboarding, action: .doNotAddClick, project: project)
}

func logAltTextInputDidAppear(project: WikimediaProject) {
logEvent(activeInterface: .altTextEditingInterface, action: .addAltTextImpression, project: project)
}

func logAltTextInputDidFocus(project: WikimediaProject) {
logEvent(activeInterface: .altTextEditingInterface, action: .addAltTextInput, project: project)
}

func logAltTextInputDidMinimize(project: WikimediaProject) {
logEvent(activeInterface: .altTextEditingInterface, action: .minimizedImpression, project: project)
}

func logAltTextDidSuccessfullyPostEdit(timeSpent: Int, revisionID: UInt64, altText: String, articleTitle: String, image: String, username: String, userEditCount: UInt64, registrationDate: String?, project: WikimediaProject) {

var actionData = ["time_spent": String(timeSpent),
"revision_id": String(revisionID),
"alt_text": altText,
"article_title": articleTitle,
"image": image,
"username": username,
"event_user_revision_count": String(userEditCount)]

if let registrationDate {
actionData["user_create_date"] = registrationDate
}

logEvent(activeInterface: .altTextEditingInterface, action: .altTextEditSuccess, actionData: actionData, project: project)
}
}

Loading

0 comments on commit 26094dc

Please sign in to comment.