Skip to content
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

fix: Update resume course navigation #151

Merged
merged 4 commits into from
Dec 12, 2023
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
35 changes: 27 additions & 8 deletions app/src/main/java/org/openedx/app/AppRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -127,37 +127,56 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
override fun navigateToCourseSubsections(
fm: FragmentManager,
courseId: String,
blockId: String,
mode: CourseViewMode,
descendantId: String?
subSectionId: String,
unitId: String,
componentId: String,
mode: CourseViewMode
) {
replaceFragmentWithBackStack(
fm,
CourseSectionFragment.newInstance(courseId, blockId, mode, descendantId)
CourseSectionFragment.newInstance(
courseId = courseId,
subSectionId = subSectionId,
unitId = unitId,
componentId = componentId,
mode = mode
)
)
}

override fun navigateToCourseContainer(
fm: FragmentManager,
blockId: String,
courseId: String,
unitId: String,
componentId: String,
mode: CourseViewMode
) {
replaceFragmentWithBackStack(
fm,
CourseUnitContainerFragment.newInstance(blockId, courseId, mode)
CourseUnitContainerFragment.newInstance(
courseId = courseId,
unitId = unitId,
componentId = componentId,
mode = mode
)
)
}

override fun replaceCourseContainer(
fm: FragmentManager,
blockId: String,
courseId: String,
unitId: String,
componentId: String,
mode: CourseViewMode
) {
replaceFragment(
fm,
CourseUnitContainerFragment.newInstance(blockId, courseId, mode),
CourseUnitContainerFragment.newInstance(
courseId = courseId,
unitId = unitId,
componentId = componentId,
mode = mode
),
FragmentTransaction.TRANSIT_FRAGMENT_FADE
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.openedx.core.domain.model

import org.openedx.core.BlockType
import java.util.Date

data class CourseStructure(
Expand All @@ -18,12 +17,4 @@ data class CourseStructure(
val media: Media?,
val certificate: Certificate?,
val isSelfPaced: Boolean
) {
fun getVerticalBlocks(): List<Block> {
return blockData.filter { it.type == BlockType.VERTICAL }
}

fun getSequentialBlocks(): List<Block> {
return blockData.filter { it.type == BlockType.SEQUENTIAL }
}
}
)
11 changes: 11 additions & 0 deletions core/src/main/java/org/openedx/core/extension/ListExt.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.openedx.core.extension

import org.openedx.core.BlockType
import org.openedx.core.domain.model.Block

inline fun <T> List<T>.indexOfFirstFromIndex(startIndex: Int, predicate: (T) -> Boolean): Int {
var index = 0
for ((i, item) in this.withIndex()) {
Expand All @@ -23,3 +26,11 @@ fun <T> MutableList<T>.clearAndAddAll(collection: Collection<T>): MutableList<T>
this.addAll(collection)
return this
}

fun List<Block>.getVerticalBlocks(): List<Block> {
return this.filter { it.type == BlockType.VERTICAL }
}

fun List<Block>.getSequentialBlocks(): List<Block> {
return this.filter { it.type == BlockType.SEQUENTIAL }
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,25 @@ interface CourseRouter {
fun navigateToCourseSubsections(
fm: FragmentManager,
courseId: String,
blockId: String,
mode: CourseViewMode,
descendantId: String? = ""
subSectionId: String,
unitId: String = "",
componentId: String = "",
mode: CourseViewMode
)

fun navigateToCourseContainer(
fm: FragmentManager,
blockId: String,
courseId: String,
unitId: String,
componentId: String = "",
mode: CourseViewMode
)

fun replaceCourseContainer(
fm: FragmentManager,
blockId: String,
courseId: String,
unitId: String,
componentId: String = "",
mode: CourseViewMode
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ class CourseDatesFragment : Fragment() {
viewModel.getSequentialBlock(verticalBlock.id)
?.let { sequentialBlock ->
router.navigateToCourseSubsections(
requireActivity().supportFragmentManager,
blockId = sequentialBlock.id,
fm = requireActivity().supportFragmentManager,
subSectionId = sequentialBlock.id,
courseId = viewModel.courseId,
mode = CourseViewMode.FULL,
descendantId = verticalBlock.id
unitId = verticalBlock.id,
mode = CourseViewMode.FULL
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import org.openedx.core.R
import org.openedx.core.SingleEventLiveData
import org.openedx.core.UIMessage
import org.openedx.core.domain.model.Block
import org.openedx.core.extension.getSequentialBlocks
import org.openedx.core.extension.getVerticalBlocks
import org.openedx.core.extension.isInternetError
import org.openedx.core.system.ResourceManager
import org.openedx.core.system.connection.NetworkConnection
Expand Down Expand Up @@ -73,7 +75,7 @@ class CourseDatesViewModel(
fun getVerticalBlock(blockId: String): Block? {
return try {
val courseStructure = interactor.getCourseStructureFromCache()
courseStructure.getVerticalBlocks().find { it.descendants.contains(blockId) }
courseStructure.blockData.getVerticalBlocks().find { it.descendants.contains(blockId) }
} catch (e: Exception) {
null
}
Expand All @@ -82,7 +84,8 @@ class CourseDatesViewModel(
fun getSequentialBlock(blockId: String): Block? {
return try {
val courseStructure = interactor.getCourseStructureFromCache()
courseStructure.getSequentialBlocks().find { it.descendants.contains(blockId) }
courseStructure.blockData.getSequentialBlocks()
.find { it.descendants.contains(blockId) }
} catch (e: Exception) {
null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,25 @@ class CourseOutlineFragment : Fragment() {
onItemClick = { block ->
viewModel.sequentialClickedEvent(block.blockId, block.displayName)
router.navigateToCourseSubsections(
requireActivity().supportFragmentManager,
fm = requireActivity().supportFragmentManager,
courseId = viewModel.courseId,
blockId = block.id,
subSectionId = block.id,
mode = CourseViewMode.FULL
)
},
onResumeClick = { blockId ->
viewModel.resumeSectionBlock?.let { sequential ->
viewModel.resumeCourseTappedEvent(sequential.blockId)
router.navigateToCourseSubsections(
requireActivity().supportFragmentManager,
viewModel.courseId,
sequential.id,
CourseViewMode.FULL
)
onResumeClick = { componentId ->
viewModel.resumeSectionBlock?.let { subSection ->
viewModel.resumeCourseTappedEvent(subSection.id)
viewModel.resumeVerticalBlock?.let { unit ->
router.navigateToCourseSubsections(
requireActivity().supportFragmentManager,
courseId = viewModel.courseId,
subSectionId = subSection.id,
mode = CourseViewMode.FULL,
unitId = unit.id,
componentId = componentId
)
}
}
},
onBackClick = {
Expand Down Expand Up @@ -290,18 +294,18 @@ internal fun CourseOutlineScreen(
courseName = uiState.courseStructure.name
)
}
if (uiState.resumeBlock != null) {
if (uiState.resumeComponent != null) {
item {
Spacer(Modifier.height(28.dp))
Box(listPadding) {
if (windowSize.isTablet) {
ResumeCourseTablet(
block = uiState.resumeBlock,
block = uiState.resumeComponent,
onResumeClick = onResumeClick
)
} else {
ResumeCourse(
block = uiState.resumeBlock,
block = uiState.resumeComponent,
onResumeClick = onResumeClick
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sealed class CourseOutlineUIState {
data class CourseData(
val courseStructure: CourseStructure,
val downloadedState: Map<String, DownloadedState>,
val resumeBlock: Block?
val resumeComponent: Block?
) : CourseOutlineUIState()

object Loading : CourseOutlineUIState()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import org.openedx.core.config.Config
import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.domain.model.Block
import org.openedx.core.domain.model.CourseComponentStatus
import org.openedx.core.extension.getSequentialBlocks
import org.openedx.core.extension.getVerticalBlocks
import org.openedx.core.extension.isInternetError
import org.openedx.core.module.DownloadWorkerController
import org.openedx.core.module.db.DownloadDao
Expand Down Expand Up @@ -81,7 +83,7 @@ class CourseOutlineViewModel(
_uiState.value = CourseOutlineUIState.CourseData(
courseStructure = state.courseStructure,
downloadedState = it.toMap(),
resumeBlock = state.resumeBlock
resumeComponent = state.resumeComponent
)
}
}
Expand Down Expand Up @@ -137,7 +139,7 @@ class CourseOutlineViewModel(
_uiState.value = CourseOutlineUIState.CourseData(
courseStructure = courseStructure,
downloadedState = getDownloadModelsStatus(),
resumeBlock = getResumeBlock(blocks, courseStatus.lastVisitedBlockId)
resumeComponent = getResumeBlock(blocks, courseStatus.lastVisitedBlockId)
)
} catch (e: Exception) {
if (e.isInternetError()) {
Expand Down Expand Up @@ -176,13 +178,11 @@ class CourseOutlineViewModel(
continueBlockId: String
): Block? {
val resumeBlock = blocks.firstOrNull { it.id == continueBlockId }
resumeVerticalBlock = blocks.find {
it.descendants.contains(resumeBlock?.id) && it.type == BlockType.VERTICAL
}
resumeSectionBlock = blocks.find {
it.descendants.contains(resumeVerticalBlock?.id) && it.type == BlockType.SEQUENTIAL
}
return resumeVerticalBlock
resumeVerticalBlock =
blocks.getVerticalBlocks().find { it.descendants.contains(resumeBlock?.id) }
resumeSectionBlock =
blocks.getSequentialBlocks().find { it.descendants.contains(resumeVerticalBlock?.id) }
return resumeBlock
}

fun resumeCourseTappedEvent(blockId: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ class CourseSectionFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(viewModel)
val blockId = requireArguments().getString(ARG_BLOCK_ID, "")
val subSectionId = requireArguments().getString(ARG_SUBSECTION_ID, "")
viewModel.mode = requireArguments().serializable(ARG_MODE)!!
viewModel.getBlocks(blockId, viewModel.mode)
viewModel.getBlocks(subSectionId, viewModel.mode)
}

override fun onCreateView(
Expand All @@ -121,9 +121,9 @@ class CourseSectionFragment : Fragment() {
if (block.descendants.isNotEmpty()) {
viewModel.verticalClickedEvent(block.blockId, block.displayName)
router.navigateToCourseContainer(
requireActivity().supportFragmentManager,
block.id,
fm = requireActivity().supportFragmentManager,
courseId = viewModel.courseId,
unitId = block.id,
mode = viewModel.mode
)
}
Expand All @@ -146,15 +146,16 @@ class CourseSectionFragment : Fragment() {
)

LaunchedEffect(rememberSaveable { true }) {
val descendantId = requireArguments().getString(ARG_DESCENDANT_ID, "")
if (descendantId.isNotEmpty()) {
val unitId = requireArguments().getString(ARG_UNIT_ID, "")
if (unitId.isNotEmpty()) {
router.navigateToCourseContainer(
requireActivity().supportFragmentManager,
descendantId,
fm = requireActivity().supportFragmentManager,
courseId = viewModel.courseId,
unitId = unitId,
componentId = requireArguments().getString(ARG_COMPONENT_ID, ""),
mode = viewModel.mode
)
requireArguments().putString(ARG_DESCENDANT_ID, "")
requireArguments().putString(ARG_UNIT_ID, "")
}
}
}
Expand All @@ -163,20 +164,23 @@ class CourseSectionFragment : Fragment() {

companion object {
private const val ARG_COURSE_ID = "courseId"
private const val ARG_BLOCK_ID = "blockId"
private const val ARG_DESCENDANT_ID = "descendantId"
private const val ARG_SUBSECTION_ID = "subSectionId"
private const val ARG_UNIT_ID = "unitId"
private const val ARG_COMPONENT_ID = "componentId"
private const val ARG_MODE = "mode"
fun newInstance(
courseId: String,
blockId: String,
subSectionId: String,
unitId: String?,
componentId: String?,
mode: CourseViewMode,
descendantId: String?,
): CourseSectionFragment {
val fragment = CourseSectionFragment()
fragment.arguments = bundleOf(
ARG_COURSE_ID to courseId,
ARG_BLOCK_ID to blockId,
ARG_DESCENDANT_ID to descendantId,
ARG_SUBSECTION_ID to subSectionId,
ARG_UNIT_ID to unitId,
ARG_COMPONENT_ID to componentId,
ARG_MODE to mode
)
return fragment
Expand Down
Loading