Skip to content

Commit

Permalink
feat: Add Analytics events (#258)
Browse files Browse the repository at this point in the history
feat: Add Analytics events

- Add analytics for the following modules
- AppReview, Profile, WhatsNew, Course,  Logistration, MainDashboard, Discovery
- Restructure the analytics implementation to module level
- Update the event names accordingly
- Fix test cases

fix: LEARNER-9876
  • Loading branch information
omerhabib26 authored Mar 27, 2024
1 parent f294057 commit 2da3666
Show file tree
Hide file tree
Showing 93 changed files with 2,349 additions and 676 deletions.
221 changes: 20 additions & 201 deletions app/src/main/java/org/openedx/app/AnalyticsManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ import org.openedx.app.analytics.FirebaseAnalytics
import org.openedx.app.analytics.SegmentAnalytics
import org.openedx.auth.presentation.AuthAnalytics
import org.openedx.core.config.Config
import org.openedx.core.presentation.CoreAnalytics
import org.openedx.core.presentation.dialog.appreview.AppReviewAnalytics
import org.openedx.course.presentation.CourseAnalytics
import org.openedx.dashboard.presentation.dashboard.DashboardAnalytics
import org.openedx.discovery.presentation.DiscoveryAnalytics
import org.openedx.discussion.presentation.DiscussionAnalytics
import org.openedx.profile.presentation.ProfileAnalytics
import org.openedx.whatsnew.presentation.WhatsNewAnalytics

class AnalyticsManager(
context: Context,
config: Config,
) : DashboardAnalytics, AuthAnalytics, AppAnalytics, DiscoveryAnalytics, ProfileAnalytics,
CourseAnalytics, DiscussionAnalytics {
) : AppAnalytics, AppReviewAnalytics, AuthAnalytics, CoreAnalytics, CourseAnalytics,
DashboardAnalytics, DiscoveryAnalytics, DiscussionAnalytics, ProfileAnalytics,
WhatsNewAnalytics {

private val services: ArrayList<Analytics> = arrayListOf()

Expand All @@ -41,6 +45,12 @@ class AnalyticsManager(
}
}

override fun logEvent(event: String, params: Map<String, Any?>) {
services.forEach { analytics ->
analytics.logEvent(event, params)
}
}

private fun setUserId(userId: Long) {
services.forEach { analytics ->
analytics.logUserId(userId)
Expand All @@ -54,56 +64,12 @@ class AnalyticsManager(
})
}

override fun userLoginEvent(method: String) {
logEvent(Event.USER_LOGIN, buildMap {
put(Key.METHOD.keyName, method)
})
}

override fun signUpClickedEvent() {
logEvent(Event.SIGN_UP_CLICKED)
}

override fun createAccountClickedEvent(provider: String) {
logEvent(Event.CREATE_ACCOUNT_CLICKED, buildMap {
put(Key.PROVIDER.keyName, provider)
})
}

override fun registrationSuccessEvent(provider: String) {
logEvent(Event.REGISTRATION_SUCCESS, buildMap { put(Key.PROVIDER.keyName, provider) })
}

override fun forgotPasswordClickedEvent() {
logEvent(Event.FORGOT_PASSWORD_CLICKED)
}

override fun resetPasswordClickedEvent(success: Boolean) {
logEvent(Event.RESET_PASSWORD_CLICKED, buildMap { put(Key.SUCCESS.keyName, success) })
}

override fun logoutEvent(force: Boolean) {
logEvent(Event.USER_LOGOUT, buildMap {
put(Key.FORCE.keyName, force)
})
}

override fun discoveryTabClickedEvent() {
logEvent(Event.DISCOVERY_TAB_CLICKED)
}

override fun dashboardTabClickedEvent() {
logEvent(Event.DASHBOARD_TAB_CLICKED)
}

override fun programsTabClickedEvent() {
logEvent(Event.PROGRAMS_TAB_CLICKED)
}

override fun profileTabClickedEvent() {
logEvent(Event.PROFILE_TAB_CLICKED)
}

override fun setUserIdForSession(userId: Long) {
setUserId(userId)
}
Expand All @@ -126,77 +92,8 @@ class AnalyticsManager(
})
}

override fun profileEditClickedEvent() {
logEvent(Event.PROFILE_EDIT_CLICKED)
}

override fun profileEditDoneClickedEvent() {
logEvent(Event.PROFILE_EDIT_DONE_CLICKED)
}

override fun profileDeleteAccountClickedEvent() {
logEvent(Event.PROFILE_DELETE_ACCOUNT_CLICKED)
}

override fun profileVideoSettingsClickedEvent() {
logEvent(Event.PROFILE_VIDEO_SETTINGS_CLICKED)
}

override fun privacyPolicyClickedEvent() {
logEvent(Event.PRIVACY_POLICY_CLICKED)
}

override fun termsOfUseClickedEvent() {
logEvent(Event.TERMS_OF_USE_CLICKED)
}

override fun cookiePolicyClickedEvent() {
logEvent(Event.COOKIE_POLICY_CLICKED)
}

override fun dataSellClickedEvent() {
logEvent(Event.DATE_SELL_CLICKED)
}

override fun faqClickedEvent() {
logEvent(Event.FAQ_CLICKED)
}

override fun emailSupportClickedEvent() {
logEvent(Event.EMAIL_SUPPORT_CLICKED)
}

override fun courseEnrollClickedEvent(courseId: String, courseName: String) {
logEvent(Event.COURSE_ENROLL_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
})
}

override fun courseEnrollSuccessEvent(courseId: String, courseName: String) {
logEvent(Event.COURSE_ENROLL_SUCCESS, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
})
}

override fun viewCourseClickedEvent(courseId: String, courseName: String) {
logEvent(Event.VIEW_COURSE_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
})
}

override fun resumeCourseTappedEvent(courseId: String, courseName: String, blockId: String) {
logEvent(Event.RESUME_COURSE_TAPPED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
put(Key.BLOCK_ID.keyName, blockId)
})
}

override fun sequentialClickedEvent(
courseId: String, courseName: String, blockId: String, blockName: String
courseId: String, courseName: String, blockId: String, blockName: String,
) {
logEvent(Event.SEQUENTIAL_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
Expand All @@ -206,19 +103,8 @@ class AnalyticsManager(
})
}

override fun verticalClickedEvent(
courseId: String, courseName: String, blockId: String, blockName: String
) {
logEvent(Event.VERTICAL_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
put(Key.BLOCK_ID.keyName, blockId)
put(Key.BLOCK_NAME.keyName, blockName)
})
}

override fun nextBlockClickedEvent(
courseId: String, courseName: String, blockId: String, blockName: String
courseId: String, courseName: String, blockId: String, blockName: String,
) {
logEvent(Event.NEXT_BLOCK_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
Expand All @@ -229,7 +115,7 @@ class AnalyticsManager(
}

override fun prevBlockClickedEvent(
courseId: String, courseName: String, blockId: String, blockName: String
courseId: String, courseName: String, blockId: String, blockName: String,
) {
logEvent(Event.PREV_BLOCK_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
Expand All @@ -240,7 +126,7 @@ class AnalyticsManager(
}

override fun finishVerticalClickedEvent(
courseId: String, courseName: String, blockId: String, blockName: String
courseId: String, courseName: String, blockId: String, blockName: String,
) {
logEvent(Event.FINISH_VERTICAL_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
Expand All @@ -251,7 +137,7 @@ class AnalyticsManager(
}

override fun finishVerticalNextClickedEvent(
courseId: String, courseName: String, blockId: String, blockName: String
courseId: String, courseName: String, blockId: String, blockName: String,
) {
logEvent(Event.FINISH_VERTICAL_NEXT_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
Expand All @@ -268,41 +154,6 @@ class AnalyticsManager(
})
}

override fun courseTabClickedEvent(courseId: String, courseName: String) {
logEvent(Event.COURSE_TAB_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
})
}

override fun videoTabClickedEvent(courseId: String, courseName: String) {
logEvent(Event.VIDEO_TAB_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
})
}

override fun discussionTabClickedEvent(courseId: String, courseName: String) {
logEvent(Event.DISCUSSION_TAB_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
})
}

override fun datesTabClickedEvent(courseId: String, courseName: String) {
logEvent(Event.DATES_TAB_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
})
}

override fun handoutsTabClickedEvent(courseId: String, courseName: String) {
logEvent(Event.HANDOUTS_TAB_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
put(Key.COURSE_NAME.keyName, courseName)
})
}

override fun discussionAllPostsClickedEvent(courseId: String, courseName: String) {
logEvent(Event.DISCUSSION_ALL_POSTS_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
Expand All @@ -318,7 +169,7 @@ class AnalyticsManager(
}

override fun discussionTopicClickedEvent(
courseId: String, courseName: String, topicId: String, topicName: String
courseId: String, courseName: String, topicId: String, topicName: String,
) {
logEvent(Event.DISCUSSION_TOPIC_CLICKED, buildMap {
put(Key.COURSE_ID.keyName, courseId)
Expand All @@ -329,48 +180,19 @@ class AnalyticsManager(
}
}

private enum class Event(val eventName: String) {
USER_LOGIN("User_Login"),
SIGN_UP_CLICKED("Sign_up_Clicked"),
CREATE_ACCOUNT_CLICKED("Create_Account_Clicked"),
REGISTRATION_SUCCESS("Registration_Success"),
enum class Event(val eventName: String) {
USER_LOGOUT("User_Logout"),
FORGOT_PASSWORD_CLICKED("Forgot_password_Clicked"),
RESET_PASSWORD_CLICKED("Reset_password_Clicked"),
DISCOVERY_TAB_CLICKED("Main_Discovery_tab_Clicked"),
DASHBOARD_TAB_CLICKED("Main_Dashboard_tab_Clicked"),
PROGRAMS_TAB_CLICKED("Main_Programs_tab_Clicked"),
PROFILE_TAB_CLICKED("Main_Profile_tab_Clicked"),
DISCOVERY_SEARCH_BAR_CLICKED("Discovery_Search_Bar_Clicked"),
DISCOVERY_COURSE_SEARCH("Discovery_Courses_Search"),
DISCOVERY_COURSE_CLICKED("Discovery_Course_Clicked"),
DASHBOARD_COURSE_CLICKED("Dashboard_Course_Clicked"),
PROFILE_EDIT_CLICKED("Profile_Edit_Clicked"),
PROFILE_EDIT_DONE_CLICKED("Profile_Edit_Done_Clicked"),
PROFILE_DELETE_ACCOUNT_CLICKED("Profile_Delete_Account_Clicked"),
PROFILE_VIDEO_SETTINGS_CLICKED("Profile_Video_settings_Clicked"),
PRIVACY_POLICY_CLICKED("Privacy_Policy_Clicked"),
TERMS_OF_USE_CLICKED("Terms_Of_Use_Clicked"),
COOKIE_POLICY_CLICKED("Cookie_Policy_Clicked"),
DATE_SELL_CLICKED("Data_Sell_Clicked"),
FAQ_CLICKED("FAQ_Clicked"),
EMAIL_SUPPORT_CLICKED("Email_Support_Clicked"),
COURSE_ENROLL_CLICKED("Course_Enroll_Clicked"),
COURSE_ENROLL_SUCCESS("Course_Enroll_Success"),
VIEW_COURSE_CLICKED("View_Course_Clicked"),
RESUME_COURSE_TAPPED("Resume_Course_Tapped"),

SEQUENTIAL_CLICKED("Sequential_Clicked"),
VERTICAL_CLICKED("Vertical_Clicked"),
NEXT_BLOCK_CLICKED("Next_Block_Clicked"),
PREV_BLOCK_CLICKED("Prev_Block_Clicked"),
FINISH_VERTICAL_CLICKED("Finish_Vertical_Clicked"),
FINISH_VERTICAL_NEXT_CLICKED("Finish_Vertical_Next_section_Clicked"),
FINISH_VERTICAL_BACK_CLICKED("Finish_Vertical_Back_to_outline_Clicked"),
COURSE_TAB_CLICKED("Course_Outline_Course_tab_Clicked"),
VIDEO_TAB_CLICKED("Course_Outline_Videos_tab_Clicked"),
DISCUSSION_TAB_CLICKED("Course_Outline_Discussion_tab_Clicked"),
DATES_TAB_CLICKED("Course_Outline_Dates_tab_Clicked"),
HANDOUTS_TAB_CLICKED("Course_Outline_Handouts_tab_Clicked"),
DISCUSSION_ALL_POSTS_CLICKED("Discussion_All_Posts_Clicked"),
DISCUSSION_FOLLOWING_CLICKED("Discussion_Following_Clicked"),
DISCUSSION_TOPIC_CLICKED("Discussion_Topic_Clicked"),
Expand All @@ -383,9 +205,6 @@ private enum class Key(val keyName: String) {
BLOCK_NAME("block_name"),
TOPIC_ID("topic_id"),
TOPIC_NAME("topic_name"),
METHOD("method"),
SUCCESS("success"),
PROVIDER("provider"),
FORCE("force"),
LABEL("label"),
COURSE_COUNT("courses_count"),
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/org/openedx/app/AppActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder {
installSplashScreen()
binding = ActivityAppBinding.inflate(layoutInflater)
lifecycle.addObserver(viewModel)
viewModel.logAppLaunchEvent()
setContentView(binding.root)
val container = binding.rootLayout

Expand Down
34 changes: 29 additions & 5 deletions app/src/main/java/org/openedx/app/AppAnalytics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,33 @@ package org.openedx.app

interface AppAnalytics {
fun logoutEvent(force: Boolean)
fun discoveryTabClickedEvent()
fun dashboardTabClickedEvent()
fun programsTabClickedEvent()
fun profileTabClickedEvent()
fun setUserIdForSession(userId: Long)
}
fun logEvent(event: String, params: Map<String, Any?>)
}

enum class AppAnalyticsEvent(val eventName: String, val biValue: String) {
LAUNCH(
"Launch",
"edx.bi.app.launch"
),
DISCOVER(
"MainDashboard:Discover",
"edx.bi.app.main_dashboard.discover"
),
MY_COURSES(
"MainDashboard:My Courses",
"edx.bi.app.main_dashboard.my_course"
),
MY_PROGRAMS(
"MainDashboard:My Programs",
"edx.bi.app.main_dashboard.my_program"
),
PROFILE(
"MainDashboard:Profile",
"edx.bi.app.main_dashboard.profile"
),
}

enum class AppAnalyticsKey(val key: String) {
NAME("name"),
}
5 changes: 3 additions & 2 deletions app/src/main/java/org/openedx/app/AppRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,12 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
override fun navigateToCourseOutline(
fm: FragmentManager,
courseId: String,
courseTitle: String
courseTitle: String,
enrollmentMode: String,
) {
replaceFragmentWithBackStack(
fm,
CourseContainerFragment.newInstance(courseId, courseTitle)
CourseContainerFragment.newInstance(courseId, courseTitle, enrollmentMode)
)
}

Expand Down
Loading

0 comments on commit 2da3666

Please sign in to comment.