-
Notifications
You must be signed in to change notification settings - Fork 45
Locked Content Support #430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package org.openedx.core.data.model | ||
|
|
||
| import com.google.gson.annotations.SerializedName | ||
| import org.openedx.core.domain.model.GatedContent | ||
|
|
||
| data class GatedContentModel( | ||
| @SerializedName("prereq_id") | ||
| val prereqId: String?, | ||
| @SerializedName("prereq_url") | ||
| val prereqUrl: String?, | ||
| @SerializedName("prereq_section_name") | ||
| val prereqSectionName: String?, | ||
| @SerializedName("gated") | ||
| val gated: Boolean, | ||
| @SerializedName("gated_section_name") | ||
| val gatedSectionName: String?, | ||
| ) { | ||
| fun mapToDomain(): GatedContent { | ||
| return GatedContent( | ||
| prereqId = prereqId, | ||
| prereqUrl = prereqUrl, | ||
| prereqSubsectionName = prereqSectionName, | ||
| gated = gated, | ||
| gatedSubsectionName = gatedSectionName | ||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package org.openedx.core.data.model | ||
|
|
||
| import com.google.gson.annotations.SerializedName | ||
|
||
| import org.openedx.core.domain.model.Subsection | ||
|
|
||
| data class SequenceModel( | ||
| @SerializedName("element_id") | ||
| val elementId: String, | ||
| @SerializedName("item_id") | ||
| val itemId: String, | ||
| @SerializedName("banner_text") | ||
| val bannerText: String?, | ||
| @SerializedName("gated_content") | ||
| val gatedContentModel: GatedContentModel, | ||
| @SerializedName("sequence_name") | ||
| val sequenceName: String, | ||
| @SerializedName("display_name") | ||
| val displayName: String, | ||
| ) { | ||
| fun mapToDomain(): Subsection { | ||
| return Subsection( | ||
| elementId = elementId, | ||
| itemId = itemId, | ||
| bannerText = bannerText, | ||
| subsectionName = sequenceName, | ||
| displayName = displayName, | ||
| gatedContent = gatedContentModel.mapToDomain(), | ||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package org.openedx.core.domain.model | ||
|
|
||
| import android.os.Parcelable | ||
| import kotlinx.parcelize.Parcelize | ||
|
|
||
| @Parcelize | ||
| data class GatedContent( | ||
| val prereqId: String?, | ||
| val prereqUrl: String?, | ||
| val prereqSubsectionName: String?, | ||
| val gated: Boolean, | ||
| val gatedSubsectionName: String? | ||
| ) : Parcelable |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package org.openedx.core.domain.model | ||
|
|
||
| import android.os.Parcelable | ||
| import kotlinx.parcelize.Parcelize | ||
|
|
||
| @Parcelize | ||
| data class Subsection( | ||
| val elementId: String, | ||
| val itemId: String, | ||
| val bannerText: String?, | ||
| val gatedContent: GatedContent, | ||
| val subsectionName: String, | ||
| val displayName: String | ||
| ) : Parcelable |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -9,6 +9,7 @@ import org.openedx.core.BlockType | |||
| import org.openedx.core.R | ||||
| import org.openedx.core.domain.model.Block | ||||
| import org.openedx.core.presentation.course.CourseViewMode | ||||
| import org.openedx.core.system.connection.NetworkConnection | ||||
| import org.openedx.core.system.notifier.CourseNotifier | ||||
| import org.openedx.core.system.notifier.CourseSectionChanged | ||||
| import org.openedx.course.domain.interactor.CourseInteractor | ||||
|
|
@@ -25,6 +26,7 @@ class CourseSectionViewModel( | |||
| val courseId: String, | ||||
| private val interactor: CourseInteractor, | ||||
| private val resourceManager: ResourceManager, | ||||
| private val networkConnection: NetworkConnection, | ||||
| private val notifier: CourseNotifier, | ||||
| private val analytics: CourseAnalytics, | ||||
| ) : BaseViewModel() { | ||||
|
|
@@ -54,6 +56,17 @@ class CourseSectionViewModel( | |||
| _uiState.value = CourseSectionUIState.Loading | ||||
| viewModelScope.launch { | ||||
| try { | ||||
| if (networkConnection.isOnline()) { | ||||
| val sectionData = interactor.getSubsection(blockId) | ||||
| if (sectionData.gatedContent.gated) { | ||||
| _uiState.value = CourseSectionUIState.Gated( | ||||
| prereqId = sectionData.gatedContent.prereqId, | ||||
| prereqSubsectionName = sectionData.gatedContent.prereqSubsectionName, | ||||
| gatedSubsectionName = sectionData.gatedContent.gatedSubsectionName, | ||||
| ) | ||||
| return@launch | ||||
| } | ||||
| } | ||||
|
Comment on lines
+59
to
+69
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @0x29a, thanks for the contribution; it's a great improvement. A few architectural concerns:
To address both issues, we must rely on the @e0d @marcotuts wdyt?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the review, @volodymyr-chekyrta! We've tried to add the locked content information to that endpoint, but it proved to be really hard, so we had to resort to this "online-only" half-measure, which solves the problem for us. Once locked content data is available in the |
||||
| val courseStructure = when (mode) { | ||||
| CourseViewMode.FULL -> interactor.getCourseStructure(courseId) | ||||
| CourseViewMode.VIDEOS -> interactor.getCourseStructureForVideos(courseId) | ||||
|
|
@@ -118,4 +131,19 @@ class CourseSectionViewModel( | |||
| ) | ||||
| } | ||||
| } | ||||
|
|
||||
| fun goToPrerequisiteSectionClickedEvent(subSectionId: String) { | ||||
| val currentState = uiState.value | ||||
| if (currentState is CourseSectionUIState.Gated) { | ||||
| analytics.logEvent( | ||||
| event = CourseAnalyticsEvent.PREREQUISITE.eventName, | ||||
| params = buildMap { | ||||
| put(CourseAnalyticsKey.NAME.key, CourseAnalyticsEvent.PREREQUISITE.biValue) | ||||
| put(CourseAnalyticsKey.COURSE_ID.key, courseId) | ||||
| put(CourseAnalyticsKey.BLOCK_ID.key, subSectionId) | ||||
| put(CourseAnalyticsKey.CATEGORY.key, CourseAnalyticsKey.NAVIGATION.key) | ||||
| } | ||||
| ) | ||||
| } | ||||
| } | ||||
| } | ||||
Uh oh!
There was an error while loading. Please reload this page.