Skip to content

Commit

Permalink
perf: optimised data loading on dashboard and course details
Browse files Browse the repository at this point in the history
  • Loading branch information
Sh-AhsanArif committed Jan 16, 2025
1 parent 46c32a2 commit cd9e651
Show file tree
Hide file tree
Showing 22 changed files with 469 additions and 88 deletions.
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/build
/google-services.json
/schemas
4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,7 @@ private def setupFirebaseConfigFields(buildType) {

buildType.manifestPlaceholders = [fcmEnabled: firebaseEnabled && cloudMessagingEnabled]
}

ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
13 changes: 9 additions & 4 deletions app/src/main/java/org/openedx/app/room/AppDatabase.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.openedx.app.room

import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import org.openedx.core.data.model.room.CourseCalendarEventEntity
import org.openedx.core.data.model.room.CourseCalendarStateEntity
import org.openedx.core.data.model.room.CourseEnrollmentDetailsEntity
import org.openedx.core.data.model.room.CourseStructureEntity
import org.openedx.core.data.model.room.OfflineXBlockProgress
import org.openedx.core.data.model.room.discovery.EnrolledCourseEntity
Expand All @@ -18,7 +20,7 @@ import org.openedx.discovery.data.converter.DiscoveryConverter
import org.openedx.discovery.data.model.room.CourseEntity
import org.openedx.discovery.data.storage.DiscoveryDao

const val DATABASE_VERSION = 1
const val DATABASE_VERSION = 2
const val DATABASE_NAME = "OpenEdX_db"

@Database(
Expand All @@ -29,10 +31,13 @@ const val DATABASE_NAME = "OpenEdX_db"
DownloadModelEntity::class,
OfflineXBlockProgress::class,
CourseCalendarEventEntity::class,
CourseCalendarStateEntity::class
CourseCalendarStateEntity::class,
CourseEnrollmentDetailsEntity::class
],
version = DATABASE_VERSION,
exportSchema = false
autoMigrations = [
AutoMigration(1, DATABASE_VERSION)
],
version = DATABASE_VERSION
)
@TypeConverters(DiscoveryConverter::class, CourseConverter::class)
abstract class AppDatabase : RoomDatabase() {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/org/openedx/app/room/DatabaseManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class DatabaseManager(
override fun clearTables() {
CoroutineScope(Dispatchers.IO).launch {
courseDao.clearCachedData()
courseDao.clearEnrollmentCachedData()
dashboardDao.clearCachedData()
downloadDao.clearOfflineProgress()
discoveryDao.clearCachedData()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.openedx.core.data.model.room

import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.openedx.core.data.model.room.discovery.CertificateDb
import org.openedx.core.data.model.room.discovery.CourseAccessDetailsDb
import org.openedx.core.data.model.room.discovery.CourseSharingUtmParametersDb
import org.openedx.core.data.model.room.discovery.EnrollmentDetailsDB
import org.openedx.core.domain.model.CourseEnrollmentDetails
import org.openedx.core.domain.model.CourseInfoOverview
import java.util.Date

@Entity(tableName = "course_enrollment_details_table")
data class CourseEnrollmentDetailsEntity(
@PrimaryKey
@ColumnInfo("id")
val id: String,
@ColumnInfo("courseUpdates")
val courseUpdates: String,
@ColumnInfo("courseHandouts")
val courseHandouts: String,
@ColumnInfo("discussionUrl")
val discussionUrl: String,
@Embedded
val courseAccessDetails: CourseAccessDetailsDb,
@Embedded
val certificate: CertificateDb?,
@Embedded
val enrollmentDetails: EnrollmentDetailsDB,
@Embedded
val courseInfoOverview: CourseInfoOverviewDb
) {
fun mapToDomain() = CourseEnrollmentDetails(
id = id,
courseUpdates = courseUpdates,
courseHandouts = courseHandouts,
discussionUrl = discussionUrl,
courseAccessDetails = courseAccessDetails.mapToDomain(),
certificate = certificate?.mapToDomain(),
enrollmentDetails = enrollmentDetails.mapToDomain(),
courseInfoOverview = courseInfoOverview.mapToDomain()
)
}

data class CourseInfoOverviewDb(
@ColumnInfo("name")
val name: String,
@ColumnInfo("number")
val number: String,
@ColumnInfo("org")
val org: String,
@Embedded
val start: Date?,
@ColumnInfo("startDisplay")
val startDisplay: String,
@ColumnInfo("startType")
val startType: String,
@Embedded
val end: Date?,
@ColumnInfo("isSelfPaced")
val isSelfPaced: Boolean,
@Embedded
var media: MediaDb?,
@Embedded
val courseSharingUtmParameters: CourseSharingUtmParametersDb,
@ColumnInfo("courseAbout")
val courseAbout: String,
) {
fun mapToDomain() = CourseInfoOverview(
name = name,
number = number,
org = org,
start = start,
startDisplay = startDisplay,
startType = startType,
end = end,
isSelfPaced = isSelfPaced,
media = media?.mapToDomain(),
courseSharingUtmParameters = courseSharingUtmParameters.mapToDomain(),
courseAbout = courseAbout
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.discovery.CertificateDb

@Parcelize
data class Certificate(
val certificateURL: String?
) : Parcelable {
fun isCertificateEarned() = certificateURL?.isNotEmpty() == true

fun mapToRoomEntity() = CertificateDb(certificateURL)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.openedx.core.domain.model

import android.os.Parcelable
import com.google.gson.internal.bind.util.ISO8601Utils
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.discovery.CourseAccessDetailsDb
import java.util.Date

@Parcelize
Expand All @@ -11,4 +13,14 @@ data class CourseAccessDetails(
val isStaff: Boolean,
val auditAccessExpires: Date?,
val coursewareAccess: CoursewareAccess?,
) : Parcelable
) : Parcelable {

fun mapToRoomEntity(): CourseAccessDetailsDb =
CourseAccessDetailsDb(
hasUnmetPrerequisites = hasUnmetPrerequisites,
isTooEarly = isTooEarly,
isStaff = isStaff,
auditAccessExpires = auditAccessExpires?.let { ISO8601Utils.format(it) },
coursewareAccess = coursewareAccess?.mapToEntity()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.CourseEnrollmentDetailsEntity
import org.openedx.core.extension.isNotNull
import java.util.Date

Expand All @@ -23,6 +24,17 @@ data class CourseEnrollmentDetails(
val isAuditAccessExpired: Boolean
get() = courseAccessDetails.auditAccessExpires.isNotNull() &&
Date().after(courseAccessDetails.auditAccessExpires)

fun mapToEntity() = CourseEnrollmentDetailsEntity(
id = id,
courseUpdates = courseUpdates,
courseHandouts = courseHandouts,
discussionUrl = discussionUrl,
courseAccessDetails = courseAccessDetails.mapToRoomEntity(),
certificate = certificate?.mapToRoomEntity(),
enrollmentDetails = enrollmentDetails.mapToEntity(),
courseInfoOverview = courseInfoOverview.mapToEntity()
)
}

enum class CourseAccessError {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.CourseInfoOverviewDb
import java.util.Date

@Parcelize
Expand All @@ -20,4 +21,18 @@ data class CourseInfoOverview(
) : Parcelable {
val isStarted: Boolean
get() = start?.before(Date()) ?: false

fun mapToEntity() = CourseInfoOverviewDb(
name = name,
number = number,
org = org,
start = start,
startDisplay = startDisplay,
startType = startType,
end = end,
isSelfPaced = isSelfPaced,
media = media?.mapToEntity(),
courseSharingUtmParameters = courseSharingUtmParameters.mapToEntity(),
courseAbout = courseAbout
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.discovery.CourseSharingUtmParametersDb

@Parcelize
data class CourseSharingUtmParameters(
val facebook: String,
val twitter: String
) : Parcelable
) : Parcelable {

fun mapToEntity() = CourseSharingUtmParametersDb(
facebook = facebook,
twitter = twitter
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.discovery.CoursewareAccessDb

@Parcelize
data class CoursewareAccess(
Expand All @@ -11,4 +12,14 @@ data class CoursewareAccess(
val userMessage: String,
val additionalContextUserMessage: String,
val userFragment: String
) : Parcelable
) : Parcelable {

fun mapToEntity() = CoursewareAccessDb(
hasAccess = hasAccess,
errorCode = errorCode,
developerMessage = developerMessage,
userMessage = userMessage,
additionalContextUserMessage = additionalContextUserMessage,
userFragment = userFragment
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.openedx.core.domain.model

import android.os.Parcelable
import com.google.gson.internal.bind.util.ISO8601Utils
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.discovery.EnrollmentDetailsDB
import java.util.Date

@Parcelize
Expand All @@ -10,4 +12,12 @@ data class EnrollmentDetails(
val mode: String?,
val isActive: Boolean,
val upgradeDeadline: Date?,
) : Parcelable
) : Parcelable {

fun mapToEntity() = EnrollmentDetailsDB(
created = created?.let { ISO8601Utils.format(it) },
mode = mode,
isActive = isActive,
upgradeDeadline = upgradeDeadline?.let { ISO8601Utils.format(it) }
)
}
35 changes: 30 additions & 5 deletions core/src/main/java/org/openedx/core/domain/model/Media.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,60 @@ package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.room.BannerImageDb
import org.openedx.core.data.model.room.CourseImageDb
import org.openedx.core.data.model.room.CourseVideoDb
import org.openedx.core.data.model.room.ImageDb
import org.openedx.core.data.model.room.MediaDb

@Parcelize
data class Media(
val bannerImage: BannerImage? = null,
val courseImage: CourseImage? = null,
val courseVideo: CourseVideo? = null,
val image: Image? = null
) : Parcelable
) : Parcelable {

fun mapToEntity() = MediaDb(
bannerImage = bannerImage?.mapToEntity(),
courseImage = courseImage?.mapToEntity(),
courseVideo = courseVideo?.mapToEntity(),
image = image?.mapToEntity()
)
}

@Parcelize
data class Image(
val large: String,
val raw: String,
val small: String
) : Parcelable
) : Parcelable {

fun mapToEntity() = ImageDb(large, raw, small)
}

@Parcelize
data class CourseVideo(
val uri: String
) : Parcelable
) : Parcelable {

fun mapToEntity() = CourseVideoDb(uri)
}

@Parcelize
data class CourseImage(
val uri: String,
val name: String
) : Parcelable
) : Parcelable {

fun mapToEntity() = CourseImageDb(uri, name)
}

@Parcelize
data class BannerImage(
val uri: String,
val uriAbsolute: String
) : Parcelable
) : Parcelable {

fun mapToEntity() = BannerImageDb(uri, uriAbsolute)
}
14 changes: 14 additions & 0 deletions core/src/main/java/org/openedx/core/extension/CoroutineExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.openedx.core.extension

import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.channelFlow
import kotlin.experimental.ExperimentalTypeInference

@OptIn(ExperimentalTypeInference::class)
inline fun <T> channelFlowWithAwait(
@BuilderInference crossinline block: suspend ProducerScope<T>.() -> Unit
) = channelFlow {
block(this)
awaitClose()
}
Loading

0 comments on commit cd9e651

Please sign in to comment.