Skip to content

Commit

Permalink
Merge branch 'main' into T376073-donate-slide
Browse files Browse the repository at this point in the history
# Conflicts:
#	WMFComponents/Sources/WMFComponents/Components/Year in Review/WMFYearInReviewView.swift
#	WMFComponents/Sources/WMFComponents/Components/Year in Review/WMFYearInReviewViewModel.swift
  • Loading branch information
golson-wmf committed Oct 29, 2024
2 parents 583cf62 + d4cab24 commit ac5af98
Show file tree
Hide file tree
Showing 16 changed files with 214 additions and 36 deletions.
2 changes: 1 addition & 1 deletion WMF Framework/LocationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ extension LocationManager: CLLocationManagerDelegate {

self.heading = heading
delegate?.locationManager?(self, didUpdate: heading)
DDLogDebug("LocationManager - did update heading: \(heading).")
DDLogDebug("LocationManager - did update heading.")
}

public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ enum ProfileState {
isLoadingDonateConfigs: false,
action: {
coordinatorDelegate?.handleProfileAction(.showYearInReview)
coordinatorDelegate?.handleProfileAction(.logYearInReviewTap)
}
)

Expand Down Expand Up @@ -261,6 +262,7 @@ enum ProfileState {
isLoadingDonateConfigs: false,
action: {
coordinatorDelegate?.handleProfileAction(.showYearInReview)
coordinatorDelegate?.handleProfileAction(.logYearInReviewTap)
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ struct WMFFeatureAnnouncementView: View {
HStack {
Spacer()
Button(
action: { viewModel.closeButtonAction?() },
action: {
viewModel.closeButtonAction?()
},
label: {
closeImage
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import SwiftUI

public struct WMFSlideShow: View {
@ObservedObject var appEnvironment = WMFAppEnvironment.current
@Binding private var currentSlide: Int
@Binding public var currentSlide: Int

var theme: WMFTheme {
return appEnvironment.theme
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct WMFYearInReviewDonateButton: View {

var body: some View {
Button(action: {
viewModel.coordinatorDelegate?.handleYearInReviewAction(.donate(sourceRect: buttonRect))
viewModel.coordinatorDelegate?.handleYearInReviewAction(.donate(sourceRect: buttonRect, slideLoggingID: viewModel.slideLoggingID))
}) {

ZStack {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct WMFYearInReview: View {
public struct WMFYearInReviewView: View {
@ObservedObject var appEnvironment = WMFAppEnvironment.current
@ObservedObject var viewModel: WMFYearInReviewViewModel

Expand All @@ -26,6 +26,7 @@ public struct WMFYearInReview: View {
}
Spacer()
Button(action: {
viewModel.logYearInReviewDidTapDone()
donePressed?()
}) {
Text(viewModel.localizedStrings.doneButtonTitle)
Expand All @@ -37,6 +38,9 @@ public struct WMFYearInReview: View {
if viewModel.isEdgeSlide && viewModel.currentSlide == 0 {
WMFYearInReviewScrollView(scrollViewContents: scrollViewContent, contents: { AnyView(buttonsFirstSlide) })
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onAppear {
viewModel.logYearInReviewSlideDidAppear()
}
} else if viewModel.isEdgeSlide {
if viewModel.hasDonated {
WMFYearInReviewScrollView(scrollViewContents: scrollViewContent)
Expand Down Expand Up @@ -64,9 +68,16 @@ public struct WMFYearInReview: View {
}
.ignoresSafeArea(edges: .bottom)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onAppear {
viewModel.logYearInReviewSlideDidAppear()
}
}
}
.background(Color(uiColor: theme.midBackground))
.onChange(of: viewModel.currentSlide) { newSlide in
// Logs slide impressions and next taps
viewModel.logYearInReviewSlideDidAppear()
}
.toolbar {
if viewModel.shouldShowToolbar() {
ToolbarItem(placement: .bottomBar) {
Expand Down Expand Up @@ -97,7 +108,8 @@ public struct WMFYearInReview: View {
Spacer()
Button(action: {
withAnimation {
viewModel.currentSlide = (viewModel.currentSlide + 1) % viewModel.slides.count
viewModel.logYearInReviewSlideDidTapNext()
viewModel.nextSlide()
}
}) {
Text(viewModel.shouldShowFinish() ? viewModel.localizedStrings.finishButtonTitle : viewModel.localizedStrings.nextButtonTitle)
Expand Down Expand Up @@ -165,10 +177,12 @@ public struct WMFYearInReview: View {
VStack {
WMFLargeButton(configuration: .primary, title: viewModel.localizedStrings.firstSlideCTA) {
withAnimation(.easeInOut(duration: 0.75)) {
viewModel.loggingDelegate?.logYearInReviewIntroDidTapContinue()
viewModel.getStarted()
}
}
WMFSmallButton(configuration: configuration, title: viewModel.localizedStrings.firstSlideHide) {
viewModel.loggingDelegate?.logYearInReviewIntroDidTapDisable()
// TODO: Implement hide this feature
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,51 @@
import Foundation
import SwiftUI

public protocol WMFYearInReviewLoggingDelegate: AnyObject {
func logYearInReviewIntroDidTapContinue()
func logYearInReviewIntroDidTapDisable()
func logYearInReviewSlideDidAppear(slideLoggingID: String)
func logYearInReviewDidTapDone(slideLoggingID: String)
func logYearInReviewDidTapNext(slideLoggingID: String)
}

public class WMFYearInReviewViewModel: ObservableObject {
@Published var isFirstSlide = true
@Published var currentSlide = 0
// Edge slide refers to one at either the beginning or the end
@Published var isEdgeSlide = true
@Published var hasDonated = false
@Published var currentSlide = 0

public let localizedStrings: LocalizedStrings
var slides: [YearInReviewSlideContent]
let username: String?
public let shareLink: String
public let hashtag: String
weak var coordinatorDelegate: YearInReviewCoordinatorDelegate?
private(set) weak var loggingDelegate: WMFYearInReviewLoggingDelegate?

@Published public var isLoading: Bool = false
private var isFirstSlide = true

public init(isEdgeSlide: Bool = true, localizedStrings: LocalizedStrings, slides: [YearInReviewSlideContent], username: String?, shareLink: String, hashtag: String, coordinatorDelegate: YearInReviewCoordinatorDelegate?, hasDonated: Bool = false) {
self.isEdgeSlide = isEdgeSlide
public init(isFirstSlide: Bool = true, localizedStrings: LocalizedStrings, slides: [YearInReviewSlideContent], username: String?, shareLink: String, hashtag: String, coordinatorDelegate: YearInReviewCoordinatorDelegate?, loggingDelegate: WMFYearInReviewLoggingDelegate, hasDonated: Bool = false) {
self.isFirstSlide = isFirstSlide
self.localizedStrings = localizedStrings
self.slides = slides
self.username = username
self.shareLink = shareLink
self.hashtag = hashtag
self.coordinatorDelegate = coordinatorDelegate
self.hasDonated = false
self.hasDonated = hasDonated
self.loggingDelegate = loggingDelegate
}

public func getStarted() {
isEdgeSlide = false
isFirstSlide = false
}

public func nextSlide() {
currentSlide = (currentSlide + 1) % slides.count
}

public struct LocalizedStrings {
let donateButtonTitle: String
Expand Down Expand Up @@ -100,18 +115,36 @@ public class WMFYearInReviewViewModel: ObservableObject {
let shareView = view.snapshot()
coordinatorDelegate?.handleYearInReviewAction(.share(image: shareView))
}

func logYearInReviewSlideDidAppear() {
loggingDelegate?.logYearInReviewSlideDidAppear(slideLoggingID: slideLoggingID)
}

public func logYearInReviewDidTapDone() {
loggingDelegate?.logYearInReviewDidTapDone(slideLoggingID: slideLoggingID)
}

func logYearInReviewSlideDidTapNext() {
loggingDelegate?.logYearInReviewDidTapNext(slideLoggingID: slideLoggingID)
}

var slideLoggingID: String {
return isFirstSlide ? "start" : slides[currentSlide].loggingID
}
}

public struct YearInReviewSlideContent: SlideShowProtocol {
public let imageName: String
public let title: String
let informationBubbleText: String?
public let subtitle: String

public init(imageName: String, title: String, informationBubbleText: String?, subtitle: String) {
public let loggingID: String

public init(imageName: String, title: String, informationBubbleText: String?, subtitle: String, loggingID: String) {
self.imageName = imageName
self.title = title
self.informationBubbleText = informationBubbleText
self.subtitle = subtitle
self.loggingID = loggingID
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ public enum ProfileAction {
case logout
case logDonateTap
case showYearInReview
case logYearInReviewTap
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ public protocol YearInReviewCoordinatorDelegate: AnyObject {
}

public enum YearInReviewCoordinatorAction {
case donate(sourceRect: CGRect)
case donate(sourceRect: CGRect, slideLoggingID: String)
case share(image: UIImage)
}
4 changes: 4 additions & 0 deletions Wikipedia/Code/ArticleViewController+Announcements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,17 @@ extension ArticleViewController {
else { return }
yirCoordinator = YearInReviewCoordinator(navigationController: navController, theme: theme, dataStore: dataStore, dataController: yirDataController)
yirCoordinator?.start()
DonateFunnel.shared.logYearInReviewFeatureAnnouncementDidTapContinue()
}, closeButtonAction: {
DonateFunnel.shared.logYearInReviewFeatureAnnouncementDidTapClose()
})

if navigationBar.superview != nil {
let xOrigin = navigationBar.frame.width - 100
let yOrigin = view.safeAreaInsets.top + navigationBar.barTopSpacing + 15
let sourceRect = CGRect(x: xOrigin, y: yOrigin, width: 30, height: 30)
announceFeature(viewModel: viewModel, sourceView: self.view, sourceRect: sourceRect)
DonateFunnel.shared.logYearInReviewFeatureAnnouncementDidAppear()
}

yirDataController.hasPresentedYiRFeatureAnnouncementModel = true
Expand Down
22 changes: 13 additions & 9 deletions Wikipedia/Code/DonateCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,19 @@ class DonateCoordinator: Coordinator {
switch donateSource {
case .articleCampaignModal(_, let metricsID, _):
return metricsID
case .articleProfile, .exploreProfile, .settingsProfile, .yearInReview:
case .articleProfile, .exploreProfile, .settingsProfile:
guard let languageCode,
let countryCode = Locale.current.region?.identifier else {
return nil
}

return "\(languageCode)\(countryCode)_appmenu_iOS"
case .yearInReview:
guard let languageCode,
let countryCode = Locale.current.region?.identifier else {
return nil
}
return "\(languageCode)\(countryCode)_appmenu_yir_iOS"
}
}

Expand Down Expand Up @@ -179,7 +185,7 @@ class DonateCoordinator: Coordinator {

DonateFunnel.shared.logArticleDidTapCancel(project: project, metricsID: metricsID)
case .yearInReview:
print("Year in review")
DonateFunnel.shared.logYearInReviewDidTapDonateCancel(metricsID: metricsID)
}
}))

Expand All @@ -203,7 +209,7 @@ class DonateCoordinator: Coordinator {
}
DonateFunnel.shared.logArticleDidTapDonateWithApplePay(project: project, metricsID: metricsID)
case .yearInReview:
print("Year in review")
DonateFunnel.shared.logYearInReviewDidTapDonateApplePay(metricsID: metricsID)
}
self.navigationController.dismiss(animated: true, completion: {
self.pushToNativeDonateForm(donateViewModel: donateViewModel)
Expand Down Expand Up @@ -231,7 +237,7 @@ class DonateCoordinator: Coordinator {
}
DonateFunnel.shared.logArticleDidTapOtherPaymentMethod(project: project, metricsID: metricsID)
case .yearInReview:
print("Year in review")
DonateFunnel.shared.logYearInReviewDidTapDonateOtherPaymentMethod(metricsID: metricsID)
}
self.navigationController.dismiss(animated: true, completion: {
self.pushToOtherPaymentMethod()
Expand Down Expand Up @@ -589,7 +595,7 @@ extension DonateCoordinator: WMFDonateLoggingDelegate {
DonateFunnel.shared.logArticleCampaignDidSeeApplePayDonateSuccessToast(project: wikimediaProject, metricsID: metricsID)
}
case .yearInReview:
print("year in review")
DonateFunnel.shared.logYearInReviewDidSeeApplePayDonateSuccessToast(metricsID: metricsID)
}
}

Expand Down Expand Up @@ -661,10 +667,8 @@ extension DonateCoordinator: WMFDonateLoggingDelegate {
}

DonateFunnel.shared.logDonateFormInAppWebViewDidTapArticleReturnButton(project: wikimediaProject, metricsID: metricsID)
case .exploreProfile, .settingsProfile:
case .exploreProfile, .settingsProfile, .yearInReview:
DonateFunnel.shared.logDonateFormInAppWebViewDidTapReturnButton(metricsID: metricsID)
case .yearInReview:
print("Year in review")
}
}

Expand Down Expand Up @@ -698,7 +702,7 @@ extension DonateCoordinator: WMFDonateLoggingDelegate {
case .settingsProfile:
DonateFunnel.shared.logExploreOptOutProfileDidSeeApplePayDonateSuccessToast(metricsID: metricsID)
case .yearInReview:
print("year in review")
DonateFunnel.shared.logYearInReviewDidSeeApplePayDonateSuccessToast(metricsID: metricsID)
}
}
}
Expand Down
Loading

0 comments on commit ac5af98

Please sign in to comment.