Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions app/src/main/java/org/openedx/app/MainFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ class MainFragment : Fragment(R.layout.fragment_main) {
binding.viewPager.setCurrentItem(0, false)
}

R.id.fragmentDiscover -> {
viewModel.logDiscoveryTabClickedEvent()
binding.viewPager.setCurrentItem(1, false)
}

R.id.fragmentProfile -> {
viewModel.logProfileTabClickedEvent()
binding.viewPager.setCurrentItem(2, false)
Expand All @@ -68,9 +63,9 @@ class MainFragment : Fragment(R.layout.fragment_main) {
}

viewLifecycleOwner.lifecycleScope.launch {
viewModel.navigateToDiscovery.collect { shouldNavigateToDiscovery ->
if (shouldNavigateToDiscovery) {
binding.bottomNavView.selectedItemId = R.id.fragmentDiscover
viewModel.navigateToHome.collect { shouldNavigateToHome ->
if (shouldNavigateToHome) {
binding.bottomNavView.selectedItemId = R.id.fragmentLearn
}
}
}
Expand All @@ -92,13 +87,6 @@ class MainFragment : Fragment(R.layout.fragment_main) {

when (requireArguments().getString(ARG_OPEN_TAB, "")) {
HomeTab.LEARN.name,
HomeTab.PROGRAMS.name -> {
binding.bottomNavView.selectedItemId = R.id.fragmentLearn
}

HomeTab.DISCOVER.name -> {
binding.bottomNavView.selectedItemId = R.id.fragmentDiscover
}

HomeTab.PROFILE.name -> {
binding.bottomNavView.selectedItemId = R.id.fragmentProfile
Expand All @@ -114,14 +102,9 @@ class MainFragment : Fragment(R.layout.fragment_main) {
binding.viewPager.offscreenPageLimit = 4

val openTab = requireArguments().getString(ARG_OPEN_TAB, HomeTab.LEARN.name)
val learnTab = if (openTab == HomeTab.PROGRAMS.name) {
LearnTab.PROGRAMS
} else {
LearnTab.COURSES
}
val learnTab = LearnTab.COURSES
adapter = NavigationFragmentAdapter(this).apply {
addFragment(LearnFragment.newInstance(openTab = learnTab.name))
addFragment(viewModel.getDiscoveryFragment)
addFragment(ProfileFragment())
}
binding.viewPager.adapter = adapter
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/java/org/openedx/app/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ class MainViewModel(
val isBottomBarEnabled: LiveData<Boolean>
get() = _isBottomBarEnabled

private val _navigateToDiscovery = MutableSharedFlow<Boolean>()
val navigateToDiscovery: SharedFlow<Boolean>
get() = _navigateToDiscovery.asSharedFlow()
private val _navigateToHome = MutableSharedFlow<Boolean>()
val navigateToHome: SharedFlow<Boolean>
get() = _navigateToHome.asSharedFlow()

val isDiscoveryTypeWebView get() = config.getDiscoveryConfig().isViewTypeWebView()
val getDiscoveryFragment get() = DiscoveryNavigator(isDiscoveryTypeWebView).getDiscoveryFragment()
Expand All @@ -38,7 +38,7 @@ class MainViewModel(
notifier.notifier
.onEach {
if (it is NavigationToDiscovery) {
_navigateToDiscovery.emit(true)
_navigateToHome.emit(true)
}
}
.distinctUntilChanged()
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ val screenModule = module {
get(),
get(),
get(),
get(),
)
}
viewModel { (courseId: String, unitId: String) ->
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/res/menu/bottom_view_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@
android:icon="@drawable/app_ic_rows"
android:title="@string/app_navigation_learn" />

<item
android:id="@+id/fragmentDiscover"
android:enabled="true"
android:icon="@drawable/app_ic_home"
android:title="@string/app_navigation_discovery" />

<item
android:id="@+id/fragmentProfile"
android:enabled="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ internal data class AgreementUrlsConfig(
private val dataSellConsentUrl: String = "",
@SerializedName("TOS_URL")
private val tosUrl: String = "",
@SerializedName("CONTACT_SUPPORT_URL")
private val contactSupportUrl: String = "",
@SerializedName("EULA_URL")
private val eulaUrl: String = "",
@SerializedName("SUPPORTED_LANGUAGES")
Expand All @@ -25,6 +27,7 @@ internal data class AgreementUrlsConfig(
cookiePolicyUrl = cookiePolicyUrl,
dataSellConsentUrl = dataSellConsentUrl,
tosUrl = tosUrl,
contactSupportUrl = contactSupportUrl,
eulaUrl = eulaUrl,
supportedLanguages = supportedLanguages,
)
Expand All @@ -35,6 +38,7 @@ internal data class AgreementUrlsConfig(
cookiePolicyUrl = cookiePolicyUrl.appendLocale(it),
dataSellConsentUrl = dataSellConsentUrl.appendLocale(it),
tosUrl = tosUrl.appendLocale(it),
contactSupportUrl = contactSupportUrl.appendLocale(it),
eulaUrl = eulaUrl.appendLocale(it),
supportedLanguages = supportedLanguages,
)
Expand Down
4 changes: 4 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 @@ -12,6 +12,7 @@ import org.openedx.core.data.model.CourseStructureModel
import org.openedx.core.data.model.EnrollmentStatus
import org.openedx.core.data.model.HandoutsModel
import org.openedx.core.data.model.ResetCourseDates
import org.openedx.core.data.model.SequenceModel
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
Expand Down Expand Up @@ -100,4 +101,7 @@ interface CourseApi {
suspend fun getEnrollmentDetails(
@Path("course_id") courseId: String,
): CourseEnrollmentDetails

@GET("api/courseware/sequence/{sequence_id}/")
suspend fun getSequence(@Path("sequence_id") sequenceId: String): SequenceModel
}
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
)
}
}
30 changes: 30 additions & 0 deletions core/src/main/java/org/openedx/core/data/model/SequenceModel.kt
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
Expand Up @@ -17,6 +17,7 @@ internal data class Agreement(

data class AgreementUrls(
val privacyPolicyUrl: String = "",
val contactSupportUrl: String = "",
val cookiePolicyUrl: String = "",
val dataSellConsentUrl: String = "",
val tosUrl: String = "",
Expand Down
13 changes: 13 additions & 0 deletions core/src/main/java/org/openedx/core/domain/model/GatedContent.kt
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
7 changes: 2 additions & 5 deletions core/src/main/java/org/openedx/core/domain/model/Progress.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.openedx.core.domain.model
import android.os.Parcelable
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.openedx.core.extension.safeDivBy

@Parcelize
data class Progress(
Expand All @@ -11,11 +12,7 @@ data class Progress(
) : Parcelable {

@IgnoredOnParcel
val value: Float = try {
assignmentsCompleted.toFloat() / totalAssignmentsCount.toFloat()
} catch (_: ArithmeticException) {
0f
}
val value: Float = assignmentsCompleted.toFloat().safeDivBy(totalAssignmentsCount.toFloat())

companion object {
val DEFAULT_PROGRESS = Progress(0, 0)
Expand Down
14 changes: 14 additions & 0 deletions core/src/main/java/org/openedx/core/domain/model/Subsection.kt
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
19 changes: 19 additions & 0 deletions core/src/main/java/org/openedx/core/extension/FloatExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.openedx.core.extension

/**
* Safely divides this Float by [divisor], returning 0f if:
* - [divisor] is zero,
* - the result is NaN.
*
* Workaround for accessibility issue:
* https://github.com/openedx/openedx-app-android/issues/442
*/
fun Float.safeDivBy(divisor: Float): Float = try {
var result = this / divisor
if (result.isNaN()) {
result = 0f
}
result
} catch (_: ArithmeticException) {
0f
}
1 change: 1 addition & 0 deletions core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="core_data_sell" translatable="false">Do not sell my personal information</string>
<string name="core_faq" translatable="false">View FAQ</string>
<string name="core_terms_of_use">Terms of Use</string>
<string name="core_contact_support">Contact Support</string>
<string name="core_profile">Profile</string>
<string name="core_cancel">Cancel</string>
<string name="core_search">Search</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,6 @@ class CourseRepository(
downloadDao.removeOfflineXBlockProgress(listOf(blockId))
}
}

suspend fun getSequence(sequenceId: String) = api.getSequence(sequenceId).mapToDomain()
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class CourseInteractor(

suspend fun removeDownloadModel(id: String) = repository.removeDownloadModel(id)

suspend fun getSubsection(subsectionId: String) = repository.getSequence(subsectionId)

fun getDownloadModels() = repository.getDownloadModels()

suspend fun getAllDownloadModels() = repository.getAllDownloadModels()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ enum class CourseAnalyticsEvent(val eventName: String, val biValue: String) {
"Course:Unit Detail",
"edx.bi.app.course.unit_detail"
),
PREREQUISITE(
"Course:Prerequisite",
"edx.bi.app.course.prerequisite"
),
VIEW_CERTIFICATE(
"Course:View Certificate Clicked",
"edx.bi.app.course.view_certificate.clicked"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import kotlinx.coroutines.launch
import org.openedx.core.BlockType
import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.domain.model.Block
import org.openedx.core.extension.safeDivBy
import org.openedx.core.module.DownloadWorkerController
import org.openedx.core.module.db.DownloadDao
import org.openedx.core.module.db.DownloadModel
Expand Down Expand Up @@ -187,19 +188,24 @@ class CourseOfflineViewModel(
completedDownloads: List<DownloadModel>,
downloadedBlocks: List<Block>
) {
val downloadedSize = getFilesSize(downloadedBlocks)
val downloadedSize = getFilesSize(downloadedBlocks).toFloat()
val realDownloadedSize = completedDownloads.sumOf { it.size }
val largestDownloads = completedDownloads
.sortedByDescending { it.size }
.take(n = 5)

val progressBarValue = downloadedSize.safeDivBy(totalDownloadableSize.toFloat())
val readyToDownloadSize = if (progressBarValue >= 1) {
0
} else {
totalDownloadableSize - realDownloadedSize
}
_uiState.update {
it.copy(
isHaveDownloadableBlocks = true,
largestDownloads = largestDownloads,
readyToDownloadSize = (totalDownloadableSize - downloadedSize).toFileSize(1, false),
readyToDownloadSize = readyToDownloadSize.toFileSize(1, false),
downloadedSize = realDownloadedSize.toFileSize(1, false),
progressBarValue = downloadedSize.toFloat() / totalDownloadableSize.toFloat()
progressBarValue = progressBarValue
)
}
}
Expand Down
Loading
Loading