Skip to content

Commit 88dfc54

Browse files
feat: added ability to handle course errors (#397)
* fix: bug when unable to see downloaded html content * feat: added ability to handle course errors --------- Co-authored-by: Omer Habib <[email protected]>
1 parent 773dac5 commit 88dfc54

File tree

45 files changed

+956
-291
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+956
-291
lines changed

app/src/main/java/org/openedx/app/AppRouter.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.openedx.app
33
import androidx.fragment.app.Fragment
44
import androidx.fragment.app.FragmentManager
55
import androidx.fragment.app.FragmentTransaction
6+
import org.openedx.app.deeplink.HomeTab
67
import org.openedx.auth.presentation.AuthRouter
78
import org.openedx.auth.presentation.logistration.LogistrationFragment
89
import org.openedx.auth.presentation.restore.RestorePasswordFragment
@@ -163,11 +164,10 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
163164
fm: FragmentManager,
164165
courseId: String,
165166
courseTitle: String,
166-
enrollmentMode: String,
167167
) {
168168
replaceFragmentWithBackStack(
169169
fm,
170-
CourseContainerFragment.newInstance(courseId, courseTitle, enrollmentMode)
170+
CourseContainerFragment.newInstance(courseId, courseTitle)
171171
)
172172
}
173173
//endregion
@@ -178,7 +178,6 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
178178
fm: FragmentManager,
179179
courseId: String,
180180
courseTitle: String,
181-
enrollmentMode: String,
182181
openTab: String,
183182
resumeBlockId: String,
184183
) {
@@ -187,7 +186,6 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
187186
CourseContainerFragment.newInstance(
188187
courseId,
189188
courseTitle,
190-
enrollmentMode,
191189
openTab,
192190
resumeBlockId
193191
)
@@ -411,6 +409,12 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
411409
replaceFragmentWithBackStack(fm, VideoQualityFragment.newInstance(videoQualityType.name))
412410
}
413411

412+
override fun navigateToDiscover(fm: FragmentManager) {
413+
fm.beginTransaction()
414+
.replace(R.id.container, MainFragment.newInstance("", "", HomeTab.DISCOVER.name))
415+
.commit()
416+
}
417+
414418
override fun navigateToWebContent(fm: FragmentManager, title: String, url: String) {
415419
replaceFragmentWithBackStack(
416420
fm,

app/src/main/java/org/openedx/app/deeplink/DeepLinkRouter.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ class DeepLinkRouter(
300300
fm = fm,
301301
courseId = courseId,
302302
courseTitle = courseTitle,
303-
enrollmentMode = ""
304303
)
305304
}
306305
}
@@ -311,7 +310,6 @@ class DeepLinkRouter(
311310
fm = fm,
312311
courseId = courseId,
313312
courseTitle = "",
314-
enrollmentMode = "",
315313
openTab = "VIDEOS"
316314
)
317315
}
@@ -323,7 +321,6 @@ class DeepLinkRouter(
323321
fm = fm,
324322
courseId = courseId,
325323
courseTitle = "",
326-
enrollmentMode = "",
327324
openTab = "DATES"
328325
)
329326
}
@@ -335,7 +332,6 @@ class DeepLinkRouter(
335332
fm = fm,
336333
courseId = courseId,
337334
courseTitle = "",
338-
enrollmentMode = "",
339335
openTab = "DISCUSSIONS"
340336
)
341337
}
@@ -347,7 +343,6 @@ class DeepLinkRouter(
347343
fm = fm,
348344
courseId = courseId,
349345
courseTitle = "",
350-
enrollmentMode = "",
351346
openTab = "MORE"
352347
)
353348
}

app/src/main/java/org/openedx/app/di/AppModule.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import org.openedx.auth.presentation.sso.OAuthHelper
3030
import org.openedx.core.CalendarRouter
3131
import org.openedx.core.R
3232
import org.openedx.core.config.Config
33+
import org.openedx.core.data.model.CourseEnrollmentDetails
3334
import org.openedx.core.data.model.CourseEnrollments
3435
import org.openedx.core.data.storage.CalendarPreferences
3536
import org.openedx.core.data.storage.CorePreferences

app/src/main/java/org/openedx/app/di/ScreenModule.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,11 @@ val screenModule = module {
242242
get(),
243243
)
244244
}
245-
viewModel { (courseId: String, courseTitle: String, enrollmentMode: String, resumeBlockId: String) ->
245+
viewModel { (courseId: String, courseTitle: String, resumeBlockId: String) ->
246246
CourseContainerViewModel(
247247
courseId,
248248
courseTitle,
249249
resumeBlockId,
250-
enrollmentMode,
251250
get(),
252251
get(),
253252
get(),
@@ -257,7 +256,7 @@ val screenModule = module {
257256
get(),
258257
get(),
259258
get(),
260-
get()
259+
get(),
261260
)
262261
}
263262
viewModel { (courseId: String, courseTitle: String) ->

core/src/main/java/org/openedx/core/data/api/CourseApi.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.openedx.core.data.model.BlocksCompletionBody
66
import org.openedx.core.data.model.CourseComponentStatus
77
import org.openedx.core.data.model.CourseDates
88
import org.openedx.core.data.model.CourseDatesBannerInfo
9+
import org.openedx.core.data.model.CourseEnrollmentDetails
910
import org.openedx.core.data.model.CourseEnrollments
1011
import org.openedx.core.data.model.CourseStructureModel
1112
import org.openedx.core.data.model.EnrollmentStatus
@@ -93,4 +94,9 @@ interface CourseApi {
9394
suspend fun getEnrollmentsStatus(
9495
@Path("username") username: String
9596
): List<EnrollmentStatus>
97+
98+
@GET("/api/mobile/v1/course_info/{course_id}/enrollment_details")
99+
suspend fun getEnrollmentDetails(
100+
@Path("course_id") courseId: String,
101+
): CourseEnrollmentDetails
96102
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.openedx.core.data.model
2+
3+
import com.google.gson.annotations.SerializedName
4+
import org.openedx.core.data.model.room.discovery.CourseAccessDetailsDb
5+
import org.openedx.core.utils.TimeUtils
6+
import org.openedx.core.domain.model.CourseAccessDetails as DomainCourseAccessDetails
7+
8+
data class CourseAccessDetails(
9+
@SerializedName("has_unmet_prerequisites")
10+
val hasUnmetPrerequisites: Boolean,
11+
@SerializedName("is_too_early")
12+
val isTooEarly: Boolean,
13+
@SerializedName("is_staff")
14+
val isStaff: Boolean,
15+
@SerializedName("audit_access_expires")
16+
val auditAccessExpires: String?,
17+
@SerializedName("courseware_access")
18+
var coursewareAccess: CoursewareAccess?,
19+
) {
20+
fun mapToDomain() = DomainCourseAccessDetails(
21+
hasUnmetPrerequisites = hasUnmetPrerequisites,
22+
isTooEarly = isTooEarly,
23+
isStaff = isStaff,
24+
auditAccessExpires = TimeUtils.iso8601ToDate(auditAccessExpires ?: ""),
25+
coursewareAccess = coursewareAccess?.mapToDomain(),
26+
)
27+
28+
fun mapToRoomEntity(): CourseAccessDetailsDb =
29+
CourseAccessDetailsDb(
30+
hasUnmetPrerequisites = hasUnmetPrerequisites,
31+
isTooEarly = isTooEarly,
32+
isStaff = isStaff,
33+
auditAccessExpires = auditAccessExpires,
34+
coursewareAccess = coursewareAccess?.mapToRoomEntity()
35+
)
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.openedx.core.data.model
2+
3+
import com.google.gson.annotations.SerializedName
4+
import org.openedx.core.domain.model.CourseEnrollmentDetails as DomainCourseEnrollmentDetails
5+
6+
data class CourseEnrollmentDetails(
7+
@SerializedName("id")
8+
val id: String,
9+
@SerializedName("course_updates")
10+
val courseUpdates: String?,
11+
@SerializedName("course_handouts")
12+
val courseHandouts: String?,
13+
@SerializedName("discussion_url")
14+
val discussionUrl: String?,
15+
@SerializedName("course_access_details")
16+
val courseAccessDetails: CourseAccessDetails,
17+
@SerializedName("certificate")
18+
val certificate: Certificate?,
19+
@SerializedName("enrollment_details")
20+
val enrollmentDetails: EnrollmentDetails,
21+
@SerializedName("course_info_overview")
22+
val courseInfoOverview: CourseInfoOverview,
23+
) {
24+
fun mapToDomain(): DomainCourseEnrollmentDetails {
25+
return DomainCourseEnrollmentDetails(
26+
id = id,
27+
courseUpdates = courseUpdates ?: "",
28+
courseHandouts = courseHandouts ?: "",
29+
discussionUrl = discussionUrl ?: "",
30+
courseAccessDetails = courseAccessDetails.mapToDomain(),
31+
certificate = certificate?.mapToDomain(),
32+
enrollmentDetails = enrollmentDetails.mapToDomain(),
33+
courseInfoOverview = courseInfoOverview.mapToDomain(),
34+
)
35+
}
36+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.openedx.core.data.model
2+
3+
import com.google.gson.annotations.SerializedName
4+
import org.openedx.core.utils.TimeUtils
5+
import org.openedx.core.domain.model.CourseInfoOverview as DomainCourseInfoOverview
6+
7+
data class CourseInfoOverview(
8+
@SerializedName("name")
9+
val name: String,
10+
@SerializedName("number")
11+
val number: String,
12+
@SerializedName("org")
13+
val org: String,
14+
@SerializedName("start")
15+
val start: String?,
16+
@SerializedName("start_display")
17+
val startDisplay: String,
18+
@SerializedName("start_type")
19+
val startType: String,
20+
@SerializedName("end")
21+
val end: String?,
22+
@SerializedName("is_self_paced")
23+
val isSelfPaced: Boolean,
24+
@SerializedName("media")
25+
var media: Media?,
26+
@SerializedName("course_sharing_utm_parameters")
27+
val courseSharingUtmParameters: CourseSharingUtmParameters,
28+
@SerializedName("course_about")
29+
val courseAbout: String,
30+
) {
31+
fun mapToDomain() = DomainCourseInfoOverview(
32+
name = name,
33+
number = number,
34+
org = org,
35+
start = TimeUtils.iso8601ToDate(start ?: ""),
36+
startDisplay = startDisplay,
37+
startType = startType,
38+
end = TimeUtils.iso8601ToDate(end ?: ""),
39+
isSelfPaced = isSelfPaced,
40+
media = media?.mapToDomain(),
41+
courseSharingUtmParameters = courseSharingUtmParameters.mapToDomain(),
42+
courseAbout = courseAbout,
43+
)
44+
}

core/src/main/java/org/openedx/core/data/model/CourseStructureModel.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@ data class CourseStructureModel(
3333
var coursewareAccess: CoursewareAccess?,
3434
@SerializedName("media")
3535
var media: Media?,
36+
@SerializedName("course_access_details")
37+
val courseAccessDetails: CourseAccessDetails,
3638
@SerializedName("certificate")
3739
val certificate: Certificate?,
40+
@SerializedName("enrollment_details")
41+
val enrollmentDetails: EnrollmentDetails,
3842
@SerializedName("is_self_paced")
3943
var isSelfPaced: Boolean?,
4044
@SerializedName("course_progress")
@@ -58,7 +62,7 @@ data class CourseStructureModel(
5862
media = media?.mapToDomain(),
5963
certificate = certificate?.mapToDomain(),
6064
isSelfPaced = isSelfPaced ?: false,
61-
progress = progress?.mapToDomain()
65+
progress = progress?.mapToDomain(),
6266
)
6367
}
6468

@@ -78,7 +82,7 @@ data class CourseStructureModel(
7882
media = MediaDb.createFrom(media),
7983
certificate = certificate?.mapToRoomEntity(),
8084
isSelfPaced = isSelfPaced ?: false,
81-
progress = progress?.mapToRoomEntity() ?: ProgressDb.DEFAULT_PROGRESS
85+
progress = progress?.mapToRoomEntity() ?: ProgressDb.DEFAULT_PROGRESS,
8286
)
8387
}
8488
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.openedx.core.data.model
2+
3+
import android.os.Parcelable
4+
import com.google.gson.annotations.SerializedName
5+
import kotlinx.parcelize.Parcelize
6+
import org.openedx.core.data.model.room.discovery.EnrollmentDetailsDB
7+
import org.openedx.core.utils.TimeUtils
8+
9+
import org.openedx.core.domain.model.EnrollmentDetails as DomainEnrollmentDetails
10+
11+
data class EnrollmentDetails(
12+
@SerializedName("created")
13+
var created: String?,
14+
@SerializedName("date")
15+
val date: String?,
16+
@SerializedName("mode")
17+
val mode: String?,
18+
@SerializedName("is_active")
19+
val isActive: Boolean = false,
20+
@SerializedName("upgrade_deadline")
21+
val upgradeDeadline: String?,
22+
) {
23+
fun mapToDomain() = DomainEnrollmentDetails(
24+
created = TimeUtils.iso8601ToDate(date ?: ""),
25+
mode = mode,
26+
isActive = isActive,
27+
upgradeDeadline = TimeUtils.iso8601ToDate(upgradeDeadline ?: ""),
28+
)
29+
30+
fun mapToRoomEntity() = EnrollmentDetailsDB(
31+
created = created,
32+
mode = mode,
33+
isActive = isActive,
34+
upgradeDeadline = upgradeDeadline,
35+
)
36+
}

0 commit comments

Comments
 (0)