Skip to content

Commit

Permalink
Finished steps analytics (#995)
Browse files Browse the repository at this point in the history
* Add analytics events

* Send events
  • Loading branch information
ivan-magda authored Jun 16, 2021
1 parent 194e804 commit c596942
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 45 deletions.
68 changes: 68 additions & 0 deletions Stepic/Legacy/Analytics/Events/AmplitudeAnalyticsEvents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,74 @@ extension AnalyticsEvent {

static let wishlistScreenOpened = AmplitudeAnalyticsEvent(name: "Wishlist screen opened")

// MARK: - Finished Steps -

static func finishedStepsScreenOpened(course: Course) -> AmplitudeAnalyticsEvent {
AmplitudeAnalyticsEvent(
name: "Finished steps screen opened",
parameters: [
"course": course.id,
"title": course.title,
"complete_rate": course.progress?.completeRate ?? 0
]
)
}

static func finishedStepsSharePressed(course: Course) -> AmplitudeAnalyticsEvent {
AmplitudeAnalyticsEvent(
name: "Finished steps share pressed",
parameters: [
"course": course.id,
"title": course.title,
"complete_rate": course.progress?.completeRate ?? 0
]
)
}

static func finishedStepsViewCertificatePressed(course: Course) -> AmplitudeAnalyticsEvent {
AmplitudeAnalyticsEvent(
name: "Finished steps view certificate pressed",
parameters: [
"course": course.id,
"title": course.title,
"complete_rate": course.progress?.completeRate ?? 0
]
)
}

static func finishedStepsBackToAssignmentsPressed(course: Course) -> AmplitudeAnalyticsEvent {
AmplitudeAnalyticsEvent(
name: "Finished steps back to assignments pressed",
parameters: [
"course": course.id,
"title": course.title,
"complete_rate": course.progress?.completeRate ?? 0
]
)
}

static func finishedStepsFindNewCoursePressed(course: Course) -> AmplitudeAnalyticsEvent {
AmplitudeAnalyticsEvent(
name: "Finished steps find new course pressed",
parameters: [
"course": course.id,
"title": course.title,
"complete_rate": course.progress?.completeRate ?? 0
]
)
}

static func finishedStepsLeaveReviewPressed(course: Course) -> AmplitudeAnalyticsEvent {
AmplitudeAnalyticsEvent(
name: "Finished steps leave review pressed",
parameters: [
"course": course.id,
"title": course.title,
"complete_rate": course.progress?.completeRate ?? 0
]
)
}

// MARK: - UserCourse -

static func userCourseActionMade(
Expand Down
10 changes: 7 additions & 3 deletions Stepic/Legacy/Model/Entities/Progress/Progress.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,14 @@ final class Progress: NSManagedObject, JSONSerializable, IDFetchable {
return true
}

var percentPassed: Float {
var completeRate: Float {
self.numberOfSteps != 0
? Float(self.numberOfStepsPassed) / Float(self.numberOfSteps) * 100
: 100.0
? Float(self.numberOfStepsPassed) / Float(self.numberOfSteps)
: 1
}

var percentPassed: Float {
self.completeRate * 100
}

enum JSONKey: String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ final class LessonFinishedStepsPanModalAssembly: Assembly {
let interactor = LessonFinishedStepsPanModalInteractor(
courseID: self.courseID,
presenter: presenter,
provider: provider
provider: provider,
analytics: StepikAnalytics.shared
)
let viewController = LessonFinishedStepsPanModalViewController(interactor: interactor)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ enum LessonFinishedStepsPanModal {
}
}

enum ShareResultPresentation {
struct Request {}
enum ModalAction {
struct Request {
let actionUniqueIdentifier: UniqueIdentifierType
}
}

enum ShareResultPresentation {
struct Response {
let course: Course
}
Expand All @@ -27,8 +31,6 @@ enum LessonFinishedStepsPanModal {
}

enum CertificatePresentation {
struct Request {}

struct Response {
let certificate: Certificate
}
Expand All @@ -38,12 +40,10 @@ enum LessonFinishedStepsPanModal {
}
}

enum LeaveReviewPresentation {
struct Request {}
}
enum BackToAssignmentsPresentation {
struct Response {}

enum FindNewCoursePresentation {
struct Request {}
struct ViewModel {}
}

// MARK: Enums
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import PromiseKit

protocol LessonFinishedStepsPanModalInteractorProtocol {
func doModalLoad(request: LessonFinishedStepsPanModal.ModalLoad.Request)
func doShareResultPresentation(request: LessonFinishedStepsPanModal.ShareResultPresentation.Request)
func doCertificatePresentation(request: LessonFinishedStepsPanModal.CertificatePresentation.Request)
func doLeaveReviewPresentation(request: LessonFinishedStepsPanModal.LeaveReviewPresentation.Request)
func doFindNewCoursePresentation(request: LessonFinishedStepsPanModal.FindNewCoursePresentation.Request)
func doModalAction(request: LessonFinishedStepsPanModal.ModalAction.Request)
}

final class LessonFinishedStepsPanModalInteractor: LessonFinishedStepsPanModalInteractorProtocol {
Expand All @@ -18,14 +15,19 @@ final class LessonFinishedStepsPanModalInteractor: LessonFinishedStepsPanModalIn
private let courseID: Course.IdType
private var currentCourse: Course?

private let analytics: Analytics
private var shouldOpenedAnalyticsEventSend = true

init(
courseID: Course.IdType,
presenter: LessonFinishedStepsPanModalPresenterProtocol,
provider: LessonFinishedStepsPanModalProviderProtocol
provider: LessonFinishedStepsPanModalProviderProtocol,
analytics: Analytics
) {
self.courseID = courseID
self.presenter = presenter
self.provider = provider
self.analytics = analytics
}

func doModalLoad(request: LessonFinishedStepsPanModal.ModalLoad.Request) {
Expand All @@ -46,30 +48,49 @@ final class LessonFinishedStepsPanModalInteractor: LessonFinishedStepsPanModalIn
CoreDataHelper.shared.save()
}

self.sendOpenedAnalyticsEventIfNeeded()
self.presenter.presentModal(response: .init(course: course, courseReview: courseReviewOrNil))
}
.catch { error in
print("LessonFinishedStepsPanModalInteractor :: failed load data with error = \(error)")
}
}

func doShareResultPresentation(request: LessonFinishedStepsPanModal.ShareResultPresentation.Request) {
if let currentCourse = self.currentCourse {
self.presenter.presentShareResult(response: .init(course: currentCourse))
func doModalAction(request: LessonFinishedStepsPanModal.ModalAction.Request) {
guard let targetAction = LessonFinishedStepsPanModal.ActionType(rawValue: request.actionUniqueIdentifier),
let currentCourse = self.currentCourse else {
return
}
}

func doCertificatePresentation(request: LessonFinishedStepsPanModal.CertificatePresentation.Request) {
if let certificate = self.currentCourse?.certificateEntity {
self.presenter.presentCertificate(response: .init(certificate: certificate))
switch targetAction {
case .backToAssignments:
self.analytics.send(.finishedStepsBackToAssignmentsPressed(course: currentCourse))
self.presenter.presentBackToAssignments(response: .init())
case .leaveReview:
self.analytics.send(.finishedStepsLeaveReviewPressed(course: currentCourse))
self.moduleOutput?.handleLessonFinishedStepsPanModalLeaveReviewAction()
case .findNewCourse:
self.analytics.send(.finishedStepsFindNewCoursePressed(course: currentCourse))
self.moduleOutput?.handleLessonFinishedStepsPanModalFindNewCourseAction()
case .shareResult:
self.analytics.send(.finishedStepsSharePressed(course: currentCourse))
self.presenter.presentShareResult(response: .init(course: currentCourse))
case .viewCertificate:
self.analytics.send(.finishedStepsViewCertificatePressed(course: currentCourse))

if let certificate = currentCourse.certificateEntity {
self.presenter.presentCertificate(response: .init(certificate: certificate))
}
}
}

func doLeaveReviewPresentation(request: LessonFinishedStepsPanModal.LeaveReviewPresentation.Request) {
self.moduleOutput?.handleLessonFinishedStepsPanModalLeaveReviewAction()
}
private func sendOpenedAnalyticsEventIfNeeded() {
guard self.shouldOpenedAnalyticsEventSend,
let currentCourse = self.currentCourse else {
return
}

func doFindNewCoursePresentation(request: LessonFinishedStepsPanModal.FindNewCoursePresentation.Request) {
self.moduleOutput?.handleLessonFinishedStepsPanModalFindNewCourseAction()
self.shouldOpenedAnalyticsEventSend = false
self.analytics.send(.finishedStepsScreenOpened(course: currentCourse))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ protocol LessonFinishedStepsPanModalPresenterProtocol {
func presentModal(response: LessonFinishedStepsPanModal.ModalLoad.Response)
func presentShareResult(response: LessonFinishedStepsPanModal.ShareResultPresentation.Response)
func presentCertificate(response: LessonFinishedStepsPanModal.CertificatePresentation.Response)
func presentBackToAssignments(response: LessonFinishedStepsPanModal.BackToAssignmentsPresentation.Response)
}

final class LessonFinishedStepsPanModalPresenter: LessonFinishedStepsPanModalPresenterProtocol {
Expand Down Expand Up @@ -47,6 +48,10 @@ final class LessonFinishedStepsPanModalPresenter: LessonFinishedStepsPanModalPre
self.viewController?.displayCertificate(viewModel: .init(certificateURL: url))
}

func presentBackToAssignments(response: LessonFinishedStepsPanModal.BackToAssignmentsPresentation.Response) {
self.viewController?.displayBackToAssignments(viewModel: .init())
}

// MARK: Private API

private func makeViewModel(course: Course, courseReview: CourseReview?) -> LessonFinishedStepsPanModalViewModel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ protocol LessonFinishedStepsPanModalViewControllerProtocol: AnyObject {
func displayModal(viewModel: LessonFinishedStepsPanModal.ModalLoad.ViewModel)
func displayShareResult(viewModel: LessonFinishedStepsPanModal.ShareResultPresentation.ViewModel)
func displayCertificate(viewModel: LessonFinishedStepsPanModal.CertificatePresentation.ViewModel)
func displayBackToAssignments(viewModel: LessonFinishedStepsPanModal.BackToAssignmentsPresentation.ViewModel)
}

final class LessonFinishedStepsPanModalViewController: PanModalPresentableViewController {
Expand Down Expand Up @@ -104,6 +105,10 @@ extension LessonFinishedStepsPanModalViewController: LessonFinishedStepsPanModal
backButtonStyle: .close
)
}

func displayBackToAssignments(viewModel: LessonFinishedStepsPanModal.BackToAssignmentsPresentation.ViewModel) {
self.dismiss(animated: true)
}
}

extension LessonFinishedStepsPanModalViewController: LessonFinishedStepsPanModalViewDelegate {
Expand All @@ -116,24 +121,11 @@ extension LessonFinishedStepsPanModalViewController: LessonFinishedStepsPanModal
didClickButtonWith uniqueIdentifier: UniqueIdentifierType?,
sourceView: UIView
) {
guard let uniqueIdentifier = uniqueIdentifier,
let actionType = LessonFinishedStepsPanModal.ActionType(rawValue: uniqueIdentifier) else {
guard let uniqueIdentifier = uniqueIdentifier else {
return
}

self.currentPopoverPresentationSourceView = sourceView

switch actionType {
case .backToAssignments:
self.dismiss(animated: true)
case .leaveReview:
self.interactor.doLeaveReviewPresentation(request: .init())
case .findNewCourse:
self.interactor.doFindNewCoursePresentation(request: .init())
case .shareResult:
self.interactor.doShareResultPresentation(request: .init())
case .viewCertificate:
self.interactor.doCertificatePresentation(request: .init())
}
self.interactor.doModalAction(request: .init(actionUniqueIdentifier: uniqueIdentifier))
}
}

0 comments on commit c596942

Please sign in to comment.