Skip to content

Commit

Permalink
feat: added ability to handle course errors (openedx#397)
Browse files Browse the repository at this point in the history
* fix: bug when unable to see downloaded html content

* feat: added ability to handle course errors

---------

Co-authored-by: Omer Habib <[email protected]>
  • Loading branch information
dixidroid and omerhabib26 authored Nov 8, 2024
1 parent 773dac5 commit 88dfc54
Show file tree
Hide file tree
Showing 45 changed files with 956 additions and 291 deletions.
12 changes: 8 additions & 4 deletions app/src/main/java/org/openedx/app/AppRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.openedx.app
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import org.openedx.app.deeplink.HomeTab
import org.openedx.auth.presentation.AuthRouter
import org.openedx.auth.presentation.logistration.LogistrationFragment
import org.openedx.auth.presentation.restore.RestorePasswordFragment
Expand Down Expand Up @@ -163,11 +164,10 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
fm: FragmentManager,
courseId: String,
courseTitle: String,
enrollmentMode: String,
) {
replaceFragmentWithBackStack(
fm,
CourseContainerFragment.newInstance(courseId, courseTitle, enrollmentMode)
CourseContainerFragment.newInstance(courseId, courseTitle)
)
}
//endregion
Expand All @@ -178,7 +178,6 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
fm: FragmentManager,
courseId: String,
courseTitle: String,
enrollmentMode: String,
openTab: String,
resumeBlockId: String,
) {
Expand All @@ -187,7 +186,6 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
CourseContainerFragment.newInstance(
courseId,
courseTitle,
enrollmentMode,
openTab,
resumeBlockId
)
Expand Down Expand Up @@ -411,6 +409,12 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
replaceFragmentWithBackStack(fm, VideoQualityFragment.newInstance(videoQualityType.name))
}

override fun navigateToDiscover(fm: FragmentManager) {
fm.beginTransaction()
.replace(R.id.container, MainFragment.newInstance("", "", HomeTab.DISCOVER.name))
.commit()
}

override fun navigateToWebContent(fm: FragmentManager, title: String, url: String) {
replaceFragmentWithBackStack(
fm,
Expand Down
5 changes: 0 additions & 5 deletions app/src/main/java/org/openedx/app/deeplink/DeepLinkRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,6 @@ class DeepLinkRouter(
fm = fm,
courseId = courseId,
courseTitle = courseTitle,
enrollmentMode = ""
)
}
}
Expand All @@ -311,7 +310,6 @@ class DeepLinkRouter(
fm = fm,
courseId = courseId,
courseTitle = "",
enrollmentMode = "",
openTab = "VIDEOS"
)
}
Expand All @@ -323,7 +321,6 @@ class DeepLinkRouter(
fm = fm,
courseId = courseId,
courseTitle = "",
enrollmentMode = "",
openTab = "DATES"
)
}
Expand All @@ -335,7 +332,6 @@ class DeepLinkRouter(
fm = fm,
courseId = courseId,
courseTitle = "",
enrollmentMode = "",
openTab = "DISCUSSIONS"
)
}
Expand All @@ -347,7 +343,6 @@ class DeepLinkRouter(
fm = fm,
courseId = courseId,
courseTitle = "",
enrollmentMode = "",
openTab = "MORE"
)
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/org/openedx/app/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import org.openedx.auth.presentation.sso.OAuthHelper
import org.openedx.core.CalendarRouter
import org.openedx.core.R
import org.openedx.core.config.Config
import org.openedx.core.data.model.CourseEnrollmentDetails
import org.openedx.core.data.model.CourseEnrollments
import org.openedx.core.data.storage.CalendarPreferences
import org.openedx.core.data.storage.CorePreferences
Expand Down
5 changes: 2 additions & 3 deletions app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,11 @@ val screenModule = module {
get(),
)
}
viewModel { (courseId: String, courseTitle: String, enrollmentMode: String, resumeBlockId: String) ->
viewModel { (courseId: String, courseTitle: String, resumeBlockId: String) ->
CourseContainerViewModel(
courseId,
courseTitle,
resumeBlockId,
enrollmentMode,
get(),
get(),
get(),
Expand All @@ -257,7 +256,7 @@ val screenModule = module {
get(),
get(),
get(),
get()
get(),
)
}
viewModel { (courseId: String, courseTitle: String) ->
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/org/openedx/core/data/api/CourseApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.openedx.core.data.model.BlocksCompletionBody
import org.openedx.core.data.model.CourseComponentStatus
import org.openedx.core.data.model.CourseDates
import org.openedx.core.data.model.CourseDatesBannerInfo
import org.openedx.core.data.model.CourseEnrollmentDetails
import org.openedx.core.data.model.CourseEnrollments
import org.openedx.core.data.model.CourseStructureModel
import org.openedx.core.data.model.EnrollmentStatus
Expand Down Expand Up @@ -93,4 +94,9 @@ interface CourseApi {
suspend fun getEnrollmentsStatus(
@Path("username") username: String
): List<EnrollmentStatus>

@GET("/api/mobile/v1/course_info/{course_id}/enrollment_details")
suspend fun getEnrollmentDetails(
@Path("course_id") courseId: String,
): CourseEnrollmentDetails
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.data.model.room.discovery.CourseAccessDetailsDb
import org.openedx.core.utils.TimeUtils
import org.openedx.core.domain.model.CourseAccessDetails as DomainCourseAccessDetails

data class CourseAccessDetails(
@SerializedName("has_unmet_prerequisites")
val hasUnmetPrerequisites: Boolean,
@SerializedName("is_too_early")
val isTooEarly: Boolean,
@SerializedName("is_staff")
val isStaff: Boolean,
@SerializedName("audit_access_expires")
val auditAccessExpires: String?,
@SerializedName("courseware_access")
var coursewareAccess: CoursewareAccess?,
) {
fun mapToDomain() = DomainCourseAccessDetails(
hasUnmetPrerequisites = hasUnmetPrerequisites,
isTooEarly = isTooEarly,
isStaff = isStaff,
auditAccessExpires = TimeUtils.iso8601ToDate(auditAccessExpires ?: ""),
coursewareAccess = coursewareAccess?.mapToDomain(),
)

fun mapToRoomEntity(): CourseAccessDetailsDb =
CourseAccessDetailsDb(
hasUnmetPrerequisites = hasUnmetPrerequisites,
isTooEarly = isTooEarly,
isStaff = isStaff,
auditAccessExpires = auditAccessExpires,
coursewareAccess = coursewareAccess?.mapToRoomEntity()
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.domain.model.CourseEnrollmentDetails as DomainCourseEnrollmentDetails

data class CourseEnrollmentDetails(
@SerializedName("id")
val id: String,
@SerializedName("course_updates")
val courseUpdates: String?,
@SerializedName("course_handouts")
val courseHandouts: String?,
@SerializedName("discussion_url")
val discussionUrl: String?,
@SerializedName("course_access_details")
val courseAccessDetails: CourseAccessDetails,
@SerializedName("certificate")
val certificate: Certificate?,
@SerializedName("enrollment_details")
val enrollmentDetails: EnrollmentDetails,
@SerializedName("course_info_overview")
val courseInfoOverview: CourseInfoOverview,
) {
fun mapToDomain(): DomainCourseEnrollmentDetails {
return DomainCourseEnrollmentDetails(
id = id,
courseUpdates = courseUpdates ?: "",
courseHandouts = courseHandouts ?: "",
discussionUrl = discussionUrl ?: "",
courseAccessDetails = courseAccessDetails.mapToDomain(),
certificate = certificate?.mapToDomain(),
enrollmentDetails = enrollmentDetails.mapToDomain(),
courseInfoOverview = courseInfoOverview.mapToDomain(),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.utils.TimeUtils
import org.openedx.core.domain.model.CourseInfoOverview as DomainCourseInfoOverview

data class CourseInfoOverview(
@SerializedName("name")
val name: String,
@SerializedName("number")
val number: String,
@SerializedName("org")
val org: String,
@SerializedName("start")
val start: String?,
@SerializedName("start_display")
val startDisplay: String,
@SerializedName("start_type")
val startType: String,
@SerializedName("end")
val end: String?,
@SerializedName("is_self_paced")
val isSelfPaced: Boolean,
@SerializedName("media")
var media: Media?,
@SerializedName("course_sharing_utm_parameters")
val courseSharingUtmParameters: CourseSharingUtmParameters,
@SerializedName("course_about")
val courseAbout: String,
) {
fun mapToDomain() = DomainCourseInfoOverview(
name = name,
number = number,
org = org,
start = TimeUtils.iso8601ToDate(start ?: ""),
startDisplay = startDisplay,
startType = startType,
end = TimeUtils.iso8601ToDate(end ?: ""),
isSelfPaced = isSelfPaced,
media = media?.mapToDomain(),
courseSharingUtmParameters = courseSharingUtmParameters.mapToDomain(),
courseAbout = courseAbout,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ data class CourseStructureModel(
var coursewareAccess: CoursewareAccess?,
@SerializedName("media")
var media: Media?,
@SerializedName("course_access_details")
val courseAccessDetails: CourseAccessDetails,
@SerializedName("certificate")
val certificate: Certificate?,
@SerializedName("enrollment_details")
val enrollmentDetails: EnrollmentDetails,
@SerializedName("is_self_paced")
var isSelfPaced: Boolean?,
@SerializedName("course_progress")
Expand All @@ -58,7 +62,7 @@ data class CourseStructureModel(
media = media?.mapToDomain(),
certificate = certificate?.mapToDomain(),
isSelfPaced = isSelfPaced ?: false,
progress = progress?.mapToDomain()
progress = progress?.mapToDomain(),
)
}

Expand All @@ -78,7 +82,7 @@ data class CourseStructureModel(
media = MediaDb.createFrom(media),
certificate = certificate?.mapToRoomEntity(),
isSelfPaced = isSelfPaced ?: false,
progress = progress?.mapToRoomEntity() ?: ProgressDb.DEFAULT_PROGRESS
progress = progress?.mapToRoomEntity() ?: ProgressDb.DEFAULT_PROGRESS,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.openedx.core.data.model

import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.discovery.EnrollmentDetailsDB
import org.openedx.core.utils.TimeUtils

import org.openedx.core.domain.model.EnrollmentDetails as DomainEnrollmentDetails

data class EnrollmentDetails(
@SerializedName("created")
var created: String?,
@SerializedName("date")
val date: String?,
@SerializedName("mode")
val mode: String?,
@SerializedName("is_active")
val isActive: Boolean = false,
@SerializedName("upgrade_deadline")
val upgradeDeadline: String?,
) {
fun mapToDomain() = DomainEnrollmentDetails(
created = TimeUtils.iso8601ToDate(date ?: ""),
mode = mode,
isActive = isActive,
upgradeDeadline = TimeUtils.iso8601ToDate(upgradeDeadline ?: ""),
)

fun mapToRoomEntity() = EnrollmentDetailsDB(
created = created,
mode = mode,
isActive = isActive,
upgradeDeadline = upgradeDeadline,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import androidx.room.PrimaryKey
import org.openedx.core.data.model.DateType
import org.openedx.core.data.model.room.MediaDb
import org.openedx.core.domain.model.Certificate
import org.openedx.core.domain.model.CourseAccessDetails
import org.openedx.core.domain.model.CourseAssignments
import org.openedx.core.domain.model.CourseDateBlock
import org.openedx.core.domain.model.CourseSharingUtmParameters
import org.openedx.core.domain.model.CourseStatus
import org.openedx.core.domain.model.CoursewareAccess
import org.openedx.core.domain.model.EnrolledCourse
import org.openedx.core.domain.model.EnrolledCourseData
import org.openedx.core.domain.model.EnrollmentDetails
import org.openedx.core.domain.model.Progress
import org.openedx.core.utils.TimeUtils
import java.util.Date
Expand Down Expand Up @@ -244,3 +246,44 @@ data class CourseDateBlockDb(
assignmentType = assignmentType
)
}

data class EnrollmentDetailsDB(
@ColumnInfo("created")
var created: String?,
@ColumnInfo("mode")
var mode: String?,
@ColumnInfo("isActive")
var isActive: Boolean,
@ColumnInfo("upgradeDeadline")
var upgradeDeadline: String?,
) {
fun mapToDomain() = EnrollmentDetails(
TimeUtils.iso8601ToDate(created ?: ""),
mode,
isActive,
TimeUtils.iso8601ToDate(upgradeDeadline ?: "")
)
}

data class CourseAccessDetailsDb(
@ColumnInfo("hasUnmetPrerequisites")
val hasUnmetPrerequisites: Boolean,
@ColumnInfo("isTooEarly")
val isTooEarly: Boolean,
@ColumnInfo("isStaff")
val isStaff: Boolean,
@ColumnInfo("auditAccessExpires")
var auditAccessExpires: String?,
@Embedded
val coursewareAccess: CoursewareAccessDb?,
) {
fun mapToDomain(): CourseAccessDetails {
return CourseAccessDetails(
hasUnmetPrerequisites = hasUnmetPrerequisites,
isTooEarly = isTooEarly,
isStaff = isStaff,
auditAccessExpires = TimeUtils.iso8601ToDate(auditAccessExpires ?: ""),
coursewareAccess = coursewareAccess?.mapToDomain()
)
}
}
Loading

0 comments on commit 88dfc54

Please sign in to comment.