Skip to content
This repository has been archived by the owner on May 6, 2024. It is now read-only.

Commit

Permalink
fix: In App Purchases (#1825)
Browse files Browse the repository at this point in the history
Fixes: LEARNER-9613
  • Loading branch information
HamzaIsrar12 committed Sep 25, 2023
1 parent ca7a1c6 commit ea48dd9
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.edx.mobile.event

/**
* This event is triggered to refresh the Course Dashboard Toolbar after the course has been
* upgraded. It ensures that the toolbar's contents and appearance are updated to reflect any
* changes made during the course upgrade process.
*/
class RefreshCourseDashboardEvent : BaseEvent()
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.edx.mobile.view

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
Expand All @@ -25,6 +26,7 @@ import org.edx.mobile.event.CourseOutlineRefreshEvent
import org.edx.mobile.event.LogoutEvent
import org.edx.mobile.event.MediaStatusChangeEvent
import org.edx.mobile.event.NetworkConnectivityChangeEvent
import org.edx.mobile.event.RefreshCourseDashboardEvent
import org.edx.mobile.exception.CourseContentNotValidException
import org.edx.mobile.extenstion.parcelable
import org.edx.mobile.extenstion.serializableOrThrow
Expand Down Expand Up @@ -87,6 +89,24 @@ class CourseHomeTabFragment : OfflineSupportBaseFragment(), CourseHomeAdapter.On
}
}

private val courseUnitDetailLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
val resultData = result.data
if (result.resultCode == Activity.RESULT_OK && resultData != null) {
// Check if the course has been upgraded
val isCourseUpgraded = resultData.getBooleanExtra(AppConstants.COURSE_UPGRADED, false)

if (isCourseUpgraded) {
fetchCourseComponents(CoursesRequestType.LIVE)
// Post a refresh event for the course dashboard toolbar
if (EventBus.getDefault().isRegistered(this).not())
EventBus.getDefault().register(this)
EventBus.getDefault().post(RefreshCourseDashboardEvent())
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.apply {
Expand Down Expand Up @@ -256,13 +276,15 @@ class CourseHomeTabFragment : OfflineSupportBaseFragment(), CourseHomeAdapter.On
}

private fun showComponentDetailScreen(component: CourseComponent) {
environment.router.getCourseUnitDetailIntent(
requireActivity(),
courseData,
courseUpgradeData,
component.id,
false
)?.let { startActivity(it) }
courseUnitDetailLauncher.launch(
environment.router.getCourseUnitDetailIntent(
requireActivity(),
courseData,
courseUpgradeData,
component.id,
false
)
)
}

override fun onSectionItemLongClick(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import org.edx.mobile.deeplink.ScreenDef
import org.edx.mobile.event.IAPFlowEvent
import org.edx.mobile.event.MainDashboardRefreshEvent
import org.edx.mobile.event.MoveToDiscoveryTabEvent
import org.edx.mobile.event.MyCoursesRefreshEvent
import org.edx.mobile.event.RefreshCourseDashboardEvent
import org.edx.mobile.exception.ErrorMessage
import org.edx.mobile.extenstion.CollapsingToolbarStatListener
import org.edx.mobile.extenstion.serializable
Expand Down Expand Up @@ -233,6 +235,9 @@ class CourseTabsDashboardFragment : BaseFragment() {
super.onViewCreated(view, savedInstanceState)
handleTabSelection(requireArguments())

if (EventBus.getDefault().isRegistered(this).not())
EventBus.getDefault().register(this)

environment.analyticsRegistry.trackScreenView(
Analytics.Screens.COURSE_DASHBOARD, courseData.course.id, null
)
Expand Down Expand Up @@ -436,13 +441,11 @@ class CourseTabsDashboardFragment : BaseFragment() {

override fun onResume() {
super.onResume()
EventBus.getDefault().register(this)
courseDateViewModel.fetchCourseDates(courseData.courseId, true)
}

override fun onPause() {
super.onPause()
EventBus.getDefault().unregister(this)
// TODO: block of code can be removed once `fetchCourseById` retrofit call replaced with MVVM approach.
fullscreenLoader?.closeTimer()
}
Expand Down Expand Up @@ -848,15 +851,31 @@ class CourseTabsDashboardFragment : BaseFragment() {
if (!this.isResumed) {
return
}
if (event.flowAction == IAPFlowData.IAPAction.PURCHASE_FLOW_COMPLETE) {
courseData.mode = EnrollmentMode.VERIFIED.toString()
arguments?.putString(Router.EXTRA_COURSE_ID, courseData.courseId)
courseDateViewModel.fetchCourseDates(courseData.courseId, true)
fetchCourseById()
EventBus.getDefault().post(MainDashboardRefreshEvent())
when (event.flowAction) {
IAPFlowData.IAPAction.PURCHASE_FLOW_COMPLETE -> {
courseData.mode = EnrollmentMode.VERIFIED.toString()
arguments?.putString(Router.EXTRA_COURSE_ID, courseData.courseId)
courseDateViewModel.fetchCourseDates(courseData.courseId, true)
fetchCourseById()
EventBus.getDefault().post(MainDashboardRefreshEvent())
}

IAPFlowData.IAPAction.SHOW_FULL_SCREEN_LOADER -> {
event.iapFlowData?.let {
showFullscreenLoader(it)
}
}
}
}

@Suppress("UNUSED_PARAMETER")
@Subscribe
fun onEvent(event: RefreshCourseDashboardEvent) {
courseData.mode = EnrollmentMode.VERIFIED.toString()
binding.toolbar.layoutUpgradeBtn.root.setVisibility(false)
EventBus.getDefault().post(MyCoursesRefreshEvent())
}

companion object {
private const val ARG_COURSE_NOT_FOUND = "ARG_COURSE_NOT_FOUND"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,6 @@ class MyCoursesListFragment : OfflineSupportBaseFragment(), RefreshListener {
data: List<EnrolledCoursesResponse>
) {
adapter.submitList(data)
adapter.notifyDataSetChanged()

if (adapter.itemCount == 0 && environment.config.discoveryConfig.isDiscoveryEnabled) {
binding.stateLayout.state.setState(EdxErrorState.State.EMPTY, Screen.MY_COURSES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import org.edx.mobile.databinding.LayoutUnitsDropDownBinding
import org.edx.mobile.deeplink.Screen
import org.edx.mobile.event.FileSelectionEvent
import org.edx.mobile.event.FileShareEvent
import org.edx.mobile.event.IAPFlowEvent
import org.edx.mobile.event.LogoutEvent
import org.edx.mobile.event.MyCoursesRefreshEvent
import org.edx.mobile.event.VideoPlaybackEvent
import org.edx.mobile.exception.ErrorMessage
import org.edx.mobile.extenstion.CollapsingToolbarStatListener
Expand All @@ -37,15 +39,19 @@ import org.edx.mobile.extenstion.setTextWithIcon
import org.edx.mobile.extenstion.setTitleStateListener
import org.edx.mobile.extenstion.setVisibility
import org.edx.mobile.http.callback.ErrorHandlingCallback
import org.edx.mobile.http.notifications.SnackbarErrorNotification
import org.edx.mobile.interfaces.OnItemClickListener
import org.edx.mobile.interfaces.RefreshListener
import org.edx.mobile.model.api.CourseUpgradeResponse
import org.edx.mobile.model.api.EnrolledCoursesResponse
import org.edx.mobile.model.course.BlockType
import org.edx.mobile.model.course.CourseComponent
import org.edx.mobile.model.course.CourseStatus
import org.edx.mobile.model.course.EnrollmentMode
import org.edx.mobile.model.course.IBlock
import org.edx.mobile.model.course.VideoBlockModel
import org.edx.mobile.model.iap.IAPFlowData
import org.edx.mobile.model.iap.IAPFlowData.IAPAction
import org.edx.mobile.services.CourseManager
import org.edx.mobile.util.AppConstants
import org.edx.mobile.util.NetworkUtil
Expand All @@ -65,6 +71,7 @@ import org.edx.mobile.view.custom.PreLoadingListener
import org.edx.mobile.view.custom.error.EdxErrorState
import org.edx.mobile.view.dialog.CelebratoryModalDialogFragment
import org.edx.mobile.view.dialog.FullscreenLoaderDialogFragment
import org.edx.mobile.view.dialog.FullscreenLoaderDialogFragment.Companion.newInstance
import org.edx.mobile.viewModel.CourseViewModel
import org.edx.mobile.viewModel.InAppPurchasesViewModel
import org.edx.mobile.wrapper.InAppPurchasesDialog
Expand Down Expand Up @@ -490,6 +497,7 @@ class CourseUnitNavigationActivity : BaseFragmentActivity(), CourseUnitFragment.

override fun refreshCourseData(courseId: String, componentId: String) {
refreshCourse = true
courseData.mode = EnrollmentMode.VERIFIED.toString()
updateCourseStructure(courseId, componentId)
}

Expand Down Expand Up @@ -529,6 +537,7 @@ class CourseUnitNavigationActivity : BaseFragmentActivity(), CourseUnitFragment.
return
}
val courseViewModel = ViewModelProvider(this)[CourseViewModel::class.java]

courseViewModel.courseComponent.observe(
this,
EventObserver { courseComponent: CourseComponent ->
Expand All @@ -538,7 +547,18 @@ class CourseUnitNavigationActivity : BaseFragmentActivity(), CourseUnitFragment.
courseComponentId = componentId ?: courseComponent.id
invalidateOptionsMenu()
onLoadData()
initAdapter()

val fullScreenLoader =
FullscreenLoaderDialogFragment.getRetainedInstance(supportFragmentManager)
if (fullScreenLoader != null && fullScreenLoader.isResumed) {
SnackbarErrorNotification(binding.pager2).showUpgradeSuccessSnackbar(
R.string.purchase_success_message
)
fullScreenLoader.closeLoader(null)
}
})

courseViewModel.handleError.observe(this) { throwable: Throwable ->
binding.stateLayout.root.setVisibility(true)
binding.pager2.setVisibility(false)
Expand All @@ -553,6 +573,7 @@ class CourseUnitNavigationActivity : BaseFragmentActivity(), CourseUnitFragment.
}
onCourseRefreshError(throwable)
}

courseId?.let {
courseViewModel.getCourseData(
courseId = courseId,
Expand Down Expand Up @@ -660,6 +681,27 @@ class CourseUnitNavigationActivity : BaseFragmentActivity(), CourseUnitFragment.
} else super.showGoogleCastButton()
}

private fun showFullscreenLoader(iapFlowData: IAPFlowData) {
// To proceed with the same instance of dialog fragment in case of orientation change
var fullScreenLoader =
FullscreenLoaderDialogFragment.getRetainedInstance(supportFragmentManager)
if (fullScreenLoader == null) {
fullScreenLoader = newInstance(iapFlowData)
}
fullScreenLoader.show(supportFragmentManager, FullscreenLoaderDialogFragment.TAG)
}

@Subscribe
fun onEventMainThread(event: IAPFlowEvent) {
if (!isInForeground) {
return
}
when (event.flowAction) {
IAPAction.SHOW_FULL_SCREEN_LOADER -> event.iapFlowData?.let { showFullscreenLoader(it) }
IAPAction.PURCHASE_FLOW_COMPLETE -> EventBus.getDefault().post(MyCoursesRefreshEvent())
}
}

@Subscribe
fun onEvent(event: FileSelectionEvent) {
fileChooserLauncher.launch(event.intent)
Expand Down

0 comments on commit ea48dd9

Please sign in to comment.