From 0459bd6382abe65aaa4f3df09e2c24f43655a37b Mon Sep 17 00:00:00 2001 From: PavloNetrebchuk Date: Thu, 21 Sep 2023 13:22:22 +0300 Subject: [PATCH 1/7] API changes. TODO: find solution for courseware_access and commented logic in CourseContainerFragment --- .../org/openedx/core/data/api/CourseApi.kt | 10 +++---- .../core/data/model/CourseEnrollments.kt | 8 ++++++ .../core/data/model/CourseStructureModel.kt | 4 +-- .../core/data/model/EnrolledCourseData.kt | 4 +-- .../data/model/room/CourseStructureEntity.kt | 4 +-- .../room/discovery/EnrolledCourseEntity.kt | 4 +-- .../core/domain/model/CourseStructure.kt | 2 +- .../core/domain/model/EnrolledCourseData.kt | 2 +- .../data/repository/CourseRepository.kt | 6 ++-- .../container/CourseContainerFragment.kt | 28 +++++++++---------- .../container/CourseContainerViewModel.kt | 6 ++-- .../data/repository/DashboardRepository.kt | 4 +-- .../discussion/data/api/DiscussionApi.kt | 2 +- .../openedx/profile/data/api/ProfileApi.kt | 2 +- 14 files changed, 47 insertions(+), 39 deletions(-) create mode 100644 core/src/main/java/org/openedx/core/data/model/CourseEnrollments.kt diff --git a/core/src/main/java/org/openedx/core/data/api/CourseApi.kt b/core/src/main/java/org/openedx/core/data/api/CourseApi.kt index 89538252d..3e214f5a6 100644 --- a/core/src/main/java/org/openedx/core/data/api/CourseApi.kt +++ b/core/src/main/java/org/openedx/core/data/api/CourseApi.kt @@ -6,15 +6,15 @@ import retrofit2.http.* interface CourseApi { - @GET("/mobile_api_extensions/v1/users/{username}/course_enrollments") + @GET("/api/mobile/v3/users/{username}/course_enrollments/") suspend fun getEnrolledCourses( @Header("Cache-Control") cacheControlHeaderParam: String? = null, @Path("username") username: String, @Query("org") org: String? = null, @Query("page") page: Int - ): DashboardCourseList + ): CourseEnrollments - @GET("/mobile_api_extensions/courses/v1/courses/") + @GET("/api/courses/v1/courses/") suspend fun getCourseList( @Query("search_term") searchQuery: String? = null, @Query("page") page: Int, @@ -28,7 +28,7 @@ interface CourseApi { ) ): CourseList - @GET("/mobile_api_extensions/v1/courses/{course_id}") + @GET("/api/mobile/v3/course_info/{course_id}/info") suspend fun getCourseDetail( @Path("course_id") courseId: String?, @Query("username") username: String? = null, @@ -36,7 +36,7 @@ interface CourseApi { ): CourseDetails @GET( - "/mobile_api_extensions/{api_version}/blocks/?" + + "/api/mobile/{api_version}/course_info/blocks/?" + "depth=all&" + "requested_fields=contains_gated_content,show_gated_sections,special_exam_info,graded,format,student_view_multi_device,due,completion&" + "student_view_data=video,discussion&" + diff --git a/core/src/main/java/org/openedx/core/data/model/CourseEnrollments.kt b/core/src/main/java/org/openedx/core/data/model/CourseEnrollments.kt new file mode 100644 index 000000000..5867e6908 --- /dev/null +++ b/core/src/main/java/org/openedx/core/data/model/CourseEnrollments.kt @@ -0,0 +1,8 @@ +package org.openedx.core.data.model + +import com.google.gson.annotations.SerializedName + +data class CourseEnrollments( + @SerializedName("enrollments") + val enrollments: DashboardCourseList +) \ No newline at end of file diff --git a/core/src/main/java/org/openedx/core/data/model/CourseStructureModel.kt b/core/src/main/java/org/openedx/core/data/model/CourseStructureModel.kt index ac2552c26..16518a8c4 100644 --- a/core/src/main/java/org/openedx/core/data/model/CourseStructureModel.kt +++ b/core/src/main/java/org/openedx/core/data/model/CourseStructureModel.kt @@ -51,7 +51,7 @@ data class CourseStructureModel( startDisplay = startDisplay ?: "", startType = startType ?: "", end = TimeUtils.iso8601ToDate(end ?: ""), - coursewareAccess = coursewareAccess?.mapToDomain()!!, + coursewareAccess = coursewareAccess?.mapToDomain(), media = media?.mapToDomain(), certificate = certificate?.mapToDomain(), isSelfPaced = isSelfPaced ?: false @@ -70,7 +70,7 @@ data class CourseStructureModel( startDisplay = startDisplay ?: "", startType = startType ?: "", end = end ?: "", - coursewareAccess = coursewareAccess?.mapToRoomEntity()!!, + coursewareAccess = coursewareAccess?.mapToRoomEntity(), media = MediaDb.createFrom(media), certificate = certificate?.mapToRoomEntity(), isSelfPaced = isSelfPaced ?: false diff --git a/core/src/main/java/org/openedx/core/data/model/EnrolledCourseData.kt b/core/src/main/java/org/openedx/core/data/model/EnrolledCourseData.kt index 74aba5073..4afc9ef71 100644 --- a/core/src/main/java/org/openedx/core/data/model/EnrolledCourseData.kt +++ b/core/src/main/java/org/openedx/core/data/model/EnrolledCourseData.kt @@ -61,7 +61,7 @@ data class EnrolledCourseData( end = TimeUtils.iso8601ToDate(end ?: ""), dynamicUpgradeDeadline = dynamicUpgradeDeadline ?: "", subscriptionId = subscriptionId ?: "", - coursewareAccess = coursewareAccess?.mapToDomain()!!, + coursewareAccess = coursewareAccess?.mapToDomain(), media = media?.mapToDomain(), courseImage = courseImage ?: "", courseAbout = courseAbout ?: "", @@ -86,7 +86,7 @@ data class EnrolledCourseData( end = end ?: "", dynamicUpgradeDeadline = dynamicUpgradeDeadline ?: "", subscriptionId = subscriptionId ?: "", - coursewareAccess = coursewareAccess?.mapToRoomEntity()!!, + coursewareAccess = coursewareAccess?.mapToRoomEntity(), media = MediaDb.createFrom(media), courseImage = courseImage ?: "", courseAbout = courseAbout ?: "", diff --git a/core/src/main/java/org/openedx/core/data/model/room/CourseStructureEntity.kt b/core/src/main/java/org/openedx/core/data/model/room/CourseStructureEntity.kt index 3c0ac045b..d6ffce80f 100644 --- a/core/src/main/java/org/openedx/core/data/model/room/CourseStructureEntity.kt +++ b/core/src/main/java/org/openedx/core/data/model/room/CourseStructureEntity.kt @@ -33,7 +33,7 @@ data class CourseStructureEntity( @ColumnInfo("end") val end: String?, @Embedded - val coursewareAccess: CoursewareAccessDb, + val coursewareAccess: CoursewareAccessDb?, @Embedded val media: MediaDb?, @Embedded @@ -54,7 +54,7 @@ data class CourseStructureEntity( startDisplay, startType, TimeUtils.iso8601ToDate(end ?: ""), - coursewareAccess.mapToDomain(), + coursewareAccess?.mapToDomain(), media?.mapToDomain(), certificate?.mapToDomain(), isSelfPaced diff --git a/core/src/main/java/org/openedx/core/data/model/room/discovery/EnrolledCourseEntity.kt b/core/src/main/java/org/openedx/core/data/model/room/discovery/EnrolledCourseEntity.kt index 31eaf463f..05aab3bdd 100644 --- a/core/src/main/java/org/openedx/core/data/model/room/discovery/EnrolledCourseEntity.kt +++ b/core/src/main/java/org/openedx/core/data/model/room/discovery/EnrolledCourseEntity.kt @@ -61,7 +61,7 @@ data class EnrolledCourseDataDb( @ColumnInfo("subscriptionId") val subscriptionId: String, @Embedded - val coursewareAccess: CoursewareAccessDb, + val coursewareAccess: CoursewareAccessDb?, @Embedded val media: MediaDb?, @ColumnInfo(name = "course_image_link") @@ -93,7 +93,7 @@ data class EnrolledCourseDataDb( TimeUtils.iso8601ToDate(end), dynamicUpgradeDeadline, subscriptionId, - coursewareAccess.mapToDomain(), + coursewareAccess?.mapToDomain(), media?.mapToDomain(), courseImage, courseAbout, diff --git a/core/src/main/java/org/openedx/core/domain/model/CourseStructure.kt b/core/src/main/java/org/openedx/core/domain/model/CourseStructure.kt index 8ac5b6e41..c8bc254c1 100644 --- a/core/src/main/java/org/openedx/core/domain/model/CourseStructure.kt +++ b/core/src/main/java/org/openedx/core/domain/model/CourseStructure.kt @@ -13,7 +13,7 @@ data class CourseStructure( val startDisplay: String, val startType: String, val end: Date?, - val coursewareAccess: CoursewareAccess, + val coursewareAccess: CoursewareAccess?, val media: Media?, val certificate: Certificate?, val isSelfPaced: Boolean diff --git a/core/src/main/java/org/openedx/core/domain/model/EnrolledCourseData.kt b/core/src/main/java/org/openedx/core/domain/model/EnrolledCourseData.kt index f5bb23d41..2a66cccde 100644 --- a/core/src/main/java/org/openedx/core/domain/model/EnrolledCourseData.kt +++ b/core/src/main/java/org/openedx/core/domain/model/EnrolledCourseData.kt @@ -16,7 +16,7 @@ data class EnrolledCourseData( val end: Date?, val dynamicUpgradeDeadline: String, val subscriptionId: String, - val coursewareAccess: CoursewareAccess, + val coursewareAccess: CoursewareAccess?, val media: Media?, val courseImage: String, val courseAbout: String, diff --git a/course/src/main/java/org/openedx/course/data/repository/CourseRepository.kt b/course/src/main/java/org/openedx/course/data/repository/CourseRepository.kt index f31d31bdf..2ef50546d 100644 --- a/course/src/main/java/org/openedx/course/data/repository/CourseRepository.kt +++ b/course/src/main/java/org/openedx/course/data/repository/CourseRepository.kt @@ -1,5 +1,7 @@ package org.openedx.course.data.repository +import kotlinx.coroutines.flow.map +import okhttp3.ResponseBody import org.openedx.core.data.api.CourseApi import org.openedx.core.data.model.BlocksCompletionBody import org.openedx.core.data.model.EnrollBody @@ -9,8 +11,6 @@ import org.openedx.core.domain.model.* import org.openedx.core.exception.NoCachedDataException import org.openedx.core.module.db.DownloadDao import org.openedx.course.data.storage.CourseDao -import kotlinx.coroutines.flow.map -import okhttp3.ResponseBody class CourseRepository( private val api: CourseApi, @@ -51,7 +51,7 @@ class CourseRepository( suspend fun preloadCourseStructure(courseId: String) { val response = api.getCourseStructure( "stale-if-error=0", - "v1", + "v3", preferencesManager.user?.username, courseId ) diff --git a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt index 17363a01b..5f976d1de 100644 --- a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt +++ b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt @@ -7,6 +7,9 @@ import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.snackbar.Snackbar +import org.koin.android.ext.android.inject +import org.koin.androidx.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import org.openedx.core.presentation.global.viewBinding import org.openedx.course.R import org.openedx.course.databinding.FragmentCourseContainerBinding @@ -15,9 +18,6 @@ import org.openedx.course.presentation.handouts.HandoutsFragment import org.openedx.course.presentation.outline.CourseOutlineFragment import org.openedx.course.presentation.videos.CourseVideosFragment import org.openedx.discussion.presentation.topics.DiscussionTopicsFragment -import org.koin.android.ext.android.inject -import org.koin.androidx.viewmodel.ext.android.viewModel -import org.koin.core.parameter.parametersOf class CourseContainerFragment : Fragment(R.layout.fragment_course_container) { @@ -80,20 +80,20 @@ class CourseContainerFragment : Fragment(R.layout.fragment_course_container) { private fun observe() { viewModel.dataReady.observe(viewLifecycleOwner) { coursewareAccess -> - if (coursewareAccess != null) { - if (coursewareAccess.hasAccess) { +// if (coursewareAccess != null) { +// if (coursewareAccess.hasAccess) { binding.viewPager.isVisible = true binding.bottomNavView.isVisible = true initViewPager() - } else { - router.navigateToNoAccess( - requireActivity().supportFragmentManager, - courseTitle, - coursewareAccess, - null - ) - } - } +// } else { +// router.navigateToNoAccess( +// requireActivity().supportFragmentManager, +// courseTitle, +// coursewareAccess, +// null +// ) +// } +// } } viewModel.errorMessage.observe(viewLifecycleOwner) { snackBar = Snackbar.make(binding.root, it, Snackbar.LENGTH_INDEFINITE) diff --git a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerViewModel.kt b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerViewModel.kt index 1fb6e9aa5..974942e50 100644 --- a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerViewModel.kt +++ b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerViewModel.kt @@ -3,6 +3,7 @@ package org.openedx.course.presentation.container import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.launch import org.openedx.core.BaseViewModel import org.openedx.core.R import org.openedx.core.SingleEventLiveData @@ -15,7 +16,6 @@ import org.openedx.core.system.notifier.CourseNotifier import org.openedx.core.system.notifier.CourseStructureUpdated import org.openedx.course.domain.interactor.CourseInteractor import org.openedx.course.presentation.CourseAnalytics -import kotlinx.coroutines.launch class CourseContainerViewModel( val courseId: String, @@ -26,8 +26,8 @@ class CourseContainerViewModel( private val analytics: CourseAnalytics ) : BaseViewModel() { - private val _dataReady = MutableLiveData() - val dataReady: LiveData + private val _dataReady = MutableLiveData() + val dataReady: LiveData get() = _dataReady private val _errorMessage = SingleEventLiveData() diff --git a/dashboard/src/main/java/org/openedx/dashboard/data/repository/DashboardRepository.kt b/dashboard/src/main/java/org/openedx/dashboard/data/repository/DashboardRepository.kt index b43624364..72cb9f380 100644 --- a/dashboard/src/main/java/org/openedx/dashboard/data/repository/DashboardRepository.kt +++ b/dashboard/src/main/java/org/openedx/dashboard/data/repository/DashboardRepository.kt @@ -19,8 +19,8 @@ class DashboardRepository( page = page ) if (page == 1) dao.clearCachedData() - dao.insertEnrolledCourseEntity(*result.results.map { it.mapToRoomEntity() }.toTypedArray()) - return result.mapToDomain() + dao.insertEnrolledCourseEntity(*result.enrollments.results.map { it.mapToRoomEntity() }.toTypedArray()) + return result.enrollments.mapToDomain() } suspend fun getEnrolledCoursesFromCache(): List { diff --git a/discussion/src/main/java/org/openedx/discussion/data/api/DiscussionApi.kt b/discussion/src/main/java/org/openedx/discussion/data/api/DiscussionApi.kt index 6969522fe..ebc911425 100644 --- a/discussion/src/main/java/org/openedx/discussion/data/api/DiscussionApi.kt +++ b/discussion/src/main/java/org/openedx/discussion/data/api/DiscussionApi.kt @@ -98,7 +98,7 @@ interface DiscussionApi { @Query("requested_fields") requestedFields: List = listOf("profile_image") ): CommentsResponse - @POST("/mobile_api_extensions/discussion/v1/comments/") + @POST("/api/discussion/v1/comments/") suspend fun createComment( @Body commentBody: CommentBody ) : CommentResult diff --git a/profile/src/main/java/org/openedx/profile/data/api/ProfileApi.kt b/profile/src/main/java/org/openedx/profile/data/api/ProfileApi.kt index cfe14bdf4..1b9bb6750 100644 --- a/profile/src/main/java/org/openedx/profile/data/api/ProfileApi.kt +++ b/profile/src/main/java/org/openedx/profile/data/api/ProfileApi.kt @@ -42,7 +42,7 @@ interface ProfileApi { suspend fun deleteProfileImage(@Path("username") username: String?): Response @FormUrlEncoded - @POST("/mobile_api_extensions/user/v1/accounts/deactivate_logout/") + @POST("/api/user/v1/accounts/deactivate_logout/") suspend fun deactivateAccount( @Field("password") password: String ): Response From 994496cd8e8023e47fa4e057c7350173576266a6 Mon Sep 17 00:00:00 2001 From: PavloNetrebchuk Date: Fri, 22 Sep 2023 14:45:45 +0300 Subject: [PATCH 2/7] Chenged "dataReady" logic in CourseContainerFragment --- .../main/java/org/openedx/app/AppRouter.kt | 10 ++-- config.yaml | 52 +++++++++---------- .../course/presentation/CourseRouter.kt | 2 - .../container/CourseContainerFragment.kt | 27 +++++----- .../container/CourseContainerViewModel.kt | 10 ++-- .../NoAccessCourseContainerFragment.kt | 6 --- 6 files changed, 48 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/org/openedx/app/AppRouter.kt b/app/src/main/java/org/openedx/app/AppRouter.kt index ea24e9d7b..a5ae7c69c 100644 --- a/app/src/main/java/org/openedx/app/AppRouter.kt +++ b/app/src/main/java/org/openedx/app/AppRouter.kt @@ -8,8 +8,6 @@ import org.openedx.auth.presentation.restore.RestorePasswordFragment import org.openedx.auth.presentation.signin.SignInFragment import org.openedx.auth.presentation.signup.SignUpFragment import org.openedx.core.FragmentViewType -import org.openedx.profile.domain.model.Account -import org.openedx.core.domain.model.CoursewareAccess import org.openedx.core.presentation.course.CourseViewMode import org.openedx.course.presentation.CourseRouter import org.openedx.course.presentation.container.CourseContainerFragment @@ -17,13 +15,13 @@ import org.openedx.course.presentation.container.NoAccessCourseContainerFragment import org.openedx.course.presentation.detail.CourseDetailsFragment import org.openedx.course.presentation.handouts.HandoutsType import org.openedx.course.presentation.handouts.WebViewFragment -import org.openedx.discovery.presentation.search.CourseSearchFragment import org.openedx.course.presentation.section.CourseSectionFragment import org.openedx.course.presentation.unit.container.CourseUnitContainerFragment import org.openedx.course.presentation.unit.video.VideoFullScreenFragment import org.openedx.course.presentation.unit.video.YoutubeVideoFullScreenFragment import org.openedx.dashboard.presentation.DashboardRouter import org.openedx.discovery.presentation.DiscoveryRouter +import org.openedx.discovery.presentation.search.CourseSearchFragment import org.openedx.discussion.domain.model.DiscussionComment import org.openedx.discussion.domain.model.Thread import org.openedx.discussion.presentation.DiscussionRouter @@ -32,12 +30,13 @@ import org.openedx.discussion.presentation.responses.DiscussionResponsesFragment import org.openedx.discussion.presentation.search.DiscussionSearchThreadFragment import org.openedx.discussion.presentation.threads.DiscussionAddThreadFragment import org.openedx.discussion.presentation.threads.DiscussionThreadsFragment +import org.openedx.profile.domain.model.Account import org.openedx.profile.presentation.ProfileRouter import org.openedx.profile.presentation.delete.DeleteProfileFragment import org.openedx.profile.presentation.edit.EditProfileFragment import org.openedx.profile.presentation.settings.video.VideoQualityFragment import org.openedx.profile.presentation.settings.video.VideoSettingsFragment -import java.util.* +import java.util.Date class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, DiscussionRouter, ProfileRouter { @@ -85,10 +84,9 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di override fun navigateToNoAccess( fm: FragmentManager, title: String, - coursewareAccess: CoursewareAccess, auditAccessExpires: Date? ) { - replaceFragment(fm, NoAccessCourseContainerFragment.newInstance(title,coursewareAccess, auditAccessExpires)) + replaceFragment(fm, NoAccessCourseContainerFragment.newInstance(title, auditAccessExpires)) } //endregion diff --git a/config.yaml b/config.yaml index 09972a3b6..c6f9b4efe 100644 --- a/config.yaml +++ b/config.yaml @@ -1,38 +1,38 @@ environments: DEV: URLS: - API_HOST_URL: "https://dev-example.com/" - privacyPolicy: "https://dev-example.com/privacy" - termsOfService: "https://dev-example.com/tos" - contactUs: "https://dev-example.com/contact" - FEEDBACK_EMAIL_ADDRESS: "support@example.com" - OAUTH_CLIENT_ID: "DEV_OAUTH_CLIENT_ID" + API_HOST_URL: "https://lms-axim-dev.raccoongang.com/" + privacyPolicy: "https://lms-axim-dev.raccoongang.com/privacy" + termsOfService: "https://lms-axim-dev.raccoongang.com/tos" + contactUs: "https://lms-axim-dev.raccoongang.com/contact" + FEEDBACK_EMAIL_ADDRESS: "devops@raccoongang.com" + OAUTH_CLIENT_ID: "lpMqiQBU1xfAgtOIPBpxzxn4EpHXi8LpYWnVEacF" FIREBASE: - PROJECT_ID: "" - APPLICATION_ID: "" - API_KEY: "" - GCM_SENDER_ID: "" + PROJECT_ID: "openedxmobile-dev" + APPLICATION_ID: "1:60657986297:android:8a3a36e996a4ce1f581028" + API_KEY: "AIzaSyCNj9QxB8YQ_Dg0mVamS0-6Gs2G2FOg2k4" + GCM_SENDER_ID: "60657986297" STAGE: URLS: - API_HOST_URL: "http://stage-example.com/" - privacyPolicy: "http://stage-example.com/privacy" - termsOfService: "http://stage-example.com/tos" - contactUs: "http://stage-example.com/contact" - FEEDBACK_EMAIL_ADDRESS: "support@example.com" - OAUTH_CLIENT_ID: "STAGE_OAUTH_CLIENT_ID" + API_HOST_URL: "https://lms-rg-app-ios-stage.raccoongang.com/" + privacyPolicy: "https://lms-rg-app-ios-stage.raccoongang.com/privacy" + termsOfService: "https://lms-rg-app-ios-stage.raccoongang.com/tos" + contactUs: "https://lms-rg-app-ios-stage.raccoongang.com/contact" + FEEDBACK_EMAIL_ADDRESS: "devops@raccoongang.com" + OAUTH_CLIENT_ID: "cu4zgoqjg6dLT7juIT6pEAqQfnVwxeGQrhlXNiRG" FIREBASE: - PROJECT_ID: "" - APPLICATION_ID: "" - API_KEY: "" - GCM_SENDER_ID: "" + PROJECT_ID: "openedxmobile-stage" + APPLICATION_ID: "1:156114692773:android:52e1f8435141fae7187b4c" + API_KEY: "AIzaSyCcE0NS0Uodi0CQXeENMRWAGyRsSFMOlm4" + GCM_SENDER_ID: "156114692773" PROD: URLS: - API_HOST_URL: "https://example.com/" - privacyPolicy: "https://example.com/privacy" - termsOfService: "https://example.com/tos" - contactUs: "https://example.com/contact" - FEEDBACK_EMAIL_ADDRESS: "support@example.com" - OAUTH_CLIENT_ID: "PROD_OAUTH_CLIENT_ID" + API_HOST_URL: "https://lms-client-demo-maple.raccoongang.com/" + privacyPolicy: "https://lms-client-demo-maple.raccoongang.com/privacy" + termsOfService: "https://lms-client-demo-maple.raccoongang.com/tos" + contactUs: "https://lms-client-demo-maple.raccoongang.com/contact" + FEEDBACK_EMAIL_ADDRESS: "devops@raccoongang.com" + OAUTH_CLIENT_ID: "kAeXuoGP6i22Ag3tlIUkL08agkO4MlJE8jXp6gjk" FIREBASE: PROJECT_ID: "" APPLICATION_ID: "" diff --git a/course/src/main/java/org/openedx/course/presentation/CourseRouter.kt b/course/src/main/java/org/openedx/course/presentation/CourseRouter.kt index 11c4420c0..d98efb6c3 100644 --- a/course/src/main/java/org/openedx/course/presentation/CourseRouter.kt +++ b/course/src/main/java/org/openedx/course/presentation/CourseRouter.kt @@ -1,7 +1,6 @@ package org.openedx.course.presentation import androidx.fragment.app.FragmentManager -import org.openedx.core.domain.model.CoursewareAccess import org.openedx.core.presentation.course.CourseViewMode import org.openedx.course.presentation.handouts.HandoutsType import java.util.Date @@ -17,7 +16,6 @@ interface CourseRouter { fun navigateToNoAccess( fm: FragmentManager, title: String, - coursewareAccess: CoursewareAccess, auditAccessExpires: Date? ) diff --git a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt index 5f976d1de..1a68ee521 100644 --- a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt +++ b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt @@ -79,21 +79,18 @@ class CourseContainerFragment : Fragment(R.layout.fragment_course_container) { } private fun observe() { - viewModel.dataReady.observe(viewLifecycleOwner) { coursewareAccess -> -// if (coursewareAccess != null) { -// if (coursewareAccess.hasAccess) { - binding.viewPager.isVisible = true - binding.bottomNavView.isVisible = true - initViewPager() -// } else { -// router.navigateToNoAccess( -// requireActivity().supportFragmentManager, -// courseTitle, -// coursewareAccess, -// null -// ) -// } -// } + viewModel.dataReady.observe(viewLifecycleOwner) { isReady -> + if (isReady == true) { + binding.viewPager.isVisible = true + binding.bottomNavView.isVisible = true + initViewPager() + } else { + router.navigateToNoAccess( + requireActivity().supportFragmentManager, + courseTitle, + null + ) + } } viewModel.errorMessage.observe(viewLifecycleOwner) { snackBar = Snackbar.make(binding.root, it, Snackbar.LENGTH_INDEFINITE) diff --git a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerViewModel.kt b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerViewModel.kt index 974942e50..19ee74748 100644 --- a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerViewModel.kt +++ b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerViewModel.kt @@ -7,7 +7,6 @@ import kotlinx.coroutines.launch import org.openedx.core.BaseViewModel import org.openedx.core.R import org.openedx.core.SingleEventLiveData -import org.openedx.core.domain.model.CoursewareAccess import org.openedx.core.exception.NoCachedDataException import org.openedx.core.extension.isInternetError import org.openedx.core.system.ResourceManager @@ -16,6 +15,7 @@ import org.openedx.core.system.notifier.CourseNotifier import org.openedx.core.system.notifier.CourseStructureUpdated import org.openedx.course.domain.interactor.CourseInteractor import org.openedx.course.presentation.CourseAnalytics +import java.util.Date class CourseContainerViewModel( val courseId: String, @@ -26,8 +26,8 @@ class CourseContainerViewModel( private val analytics: CourseAnalytics ) : BaseViewModel() { - private val _dataReady = MutableLiveData() - val dataReady: LiveData + private val _dataReady = MutableLiveData() + val dataReady: LiveData get() = _dataReady private val _errorMessage = SingleEventLiveData() @@ -55,7 +55,9 @@ class CourseContainerViewModel( } val courseStructure = interactor.getCourseStructureFromCache() courseName = courseStructure.name - _dataReady.value = courseStructure.coursewareAccess + _dataReady.value = courseStructure.start?.let { start -> + start < Date() + } } catch (e: Exception) { if (e.isInternetError() || e is NoCachedDataException) { _errorMessage.value = diff --git a/course/src/main/java/org/openedx/course/presentation/container/NoAccessCourseContainerFragment.kt b/course/src/main/java/org/openedx/course/presentation/container/NoAccessCourseContainerFragment.kt index c23c3c71b..3e2c4a1e6 100644 --- a/course/src/main/java/org/openedx/course/presentation/container/NoAccessCourseContainerFragment.kt +++ b/course/src/main/java/org/openedx/course/presentation/container/NoAccessCourseContainerFragment.kt @@ -25,7 +25,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.core.os.bundleOf import androidx.fragment.app.Fragment -import org.openedx.core.domain.model.CoursewareAccess import org.openedx.core.extension.parcelable import org.openedx.core.ui.* import org.openedx.core.ui.theme.OpenEdXTheme @@ -37,14 +36,12 @@ import org.openedx.course.R as courseR class NoAccessCourseContainerFragment : Fragment() { private var courseTitle = "" - private var coursewareAccess: CoursewareAccess? = null private var auditAccessExpires: Date? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) with(requireArguments()) { courseTitle = getString(ARG_TITLE, "") - coursewareAccess = parcelable(ARG_COURSEWARE_ACCESS) auditAccessExpires = parcelable(ARG_AUDIT_ACCESS_EXPIRES) } } @@ -74,18 +71,15 @@ class NoAccessCourseContainerFragment : Fragment() { companion object { private const val ARG_TITLE = "title" - private const val ARG_COURSEWARE_ACCESS = "coursewareAccess" private const val ARG_AUDIT_ACCESS_EXPIRES = "auditAccessExpires" fun newInstance( title: String, - coursewareAccess: CoursewareAccess, auditAccessExpires: Date? ): NoAccessCourseContainerFragment { val fragment = NoAccessCourseContainerFragment() fragment.arguments = bundleOf( ARG_TITLE to title, - ARG_COURSEWARE_ACCESS to coursewareAccess, ARG_AUDIT_ACCESS_EXPIRES to auditAccessExpires ) return fragment From f6cf0bb0fc52c76ccd4437c7599adde6b355abda Mon Sep 17 00:00:00 2001 From: Volodymyr Chekyrta Date: Tue, 19 Dec 2023 17:29:50 +0200 Subject: [PATCH 3/7] Added mobile_search argument to the course search --- core/src/main/java/org/openedx/core/data/api/CourseApi.kt | 1 + .../discovery/data/repository/DiscoveryRepository.kt | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/openedx/core/data/api/CourseApi.kt b/core/src/main/java/org/openedx/core/data/api/CourseApi.kt index 42845e1e7..c556c3d83 100644 --- a/core/src/main/java/org/openedx/core/data/api/CourseApi.kt +++ b/core/src/main/java/org/openedx/core/data/api/CourseApi.kt @@ -19,6 +19,7 @@ interface CourseApi { @Query("search_term") searchQuery: String? = null, @Query("page") page: Int, @Query("mobile") mobile: Boolean, + @Query("mobile_search") mobileSearch: Boolean, @Query("username") username: String? = null, @Query("org") org: String? = null, @Query("permissions") permission: List = listOf( diff --git a/discovery/src/main/java/org/openedx/discovery/data/repository/DiscoveryRepository.kt b/discovery/src/main/java/org/openedx/discovery/data/repository/DiscoveryRepository.kt index 2762cf1aa..db2f02d65 100644 --- a/discovery/src/main/java/org/openedx/discovery/data/repository/DiscoveryRepository.kt +++ b/discovery/src/main/java/org/openedx/discovery/data/repository/DiscoveryRepository.kt @@ -20,6 +20,7 @@ class DiscoveryRepository( val pageResponse = api.getCourseList( page = pageNumber, mobile = true, + mobileSearch = false, username = username, org = organization ) @@ -42,7 +43,12 @@ class DiscoveryRepository( query: String, pageNumber: Int, ): CourseList { - val pageResponse = api.getCourseList(searchQuery = query, page = pageNumber, mobile = true) + val pageResponse = api.getCourseList( + searchQuery = query, + page = pageNumber, + mobile = true, + mobileSearch = true + ) return CourseList( pageResponse.pagination.mapToDomain(), pageResponse.results?.map { it.mapToDomain() } ?: emptyList() From c706f76a26dbf08bd710d7f238e8ad48acb1cf87 Mon Sep 17 00:00:00 2001 From: Volodymyr Chekyrta Date: Tue, 19 Dec 2023 17:52:08 +0200 Subject: [PATCH 4/7] Fix CourseContainerViewModelTest --- .../presentation/container/CourseContainerViewModelTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/course/src/test/java/org/openedx/course/presentation/container/CourseContainerViewModelTest.kt b/course/src/test/java/org/openedx/course/presentation/container/CourseContainerViewModelTest.kt index 3aff2df2b..2a7b8792f 100644 --- a/course/src/test/java/org/openedx/course/presentation/container/CourseContainerViewModelTest.kt +++ b/course/src/test/java/org/openedx/course/presentation/container/CourseContainerViewModelTest.kt @@ -21,6 +21,7 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule import java.net.UnknownHostException +import java.util.Date @OptIn(ExperimentalCoroutinesApi::class) class CourseContainerViewModelTest { @@ -46,7 +47,7 @@ class CourseContainerViewModelTest { name = "Course name", number = "", org = "Org", - start = null, + start = Date(0), startDisplay = "", startType = "", end = null, From 5e0013994e0920386909969fe1f3b6e0855960af Mon Sep 17 00:00:00 2001 From: Volodymyr Chekyrta Date: Thu, 28 Dec 2023 11:38:52 +0200 Subject: [PATCH 5/7] fix: code improvements --- .../main/java/org/openedx/core/data/model/CourseEnrollments.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/openedx/core/data/model/CourseEnrollments.kt b/core/src/main/java/org/openedx/core/data/model/CourseEnrollments.kt index 5867e6908..1c10cfa92 100644 --- a/core/src/main/java/org/openedx/core/data/model/CourseEnrollments.kt +++ b/core/src/main/java/org/openedx/core/data/model/CourseEnrollments.kt @@ -5,4 +5,4 @@ import com.google.gson.annotations.SerializedName data class CourseEnrollments( @SerializedName("enrollments") val enrollments: DashboardCourseList -) \ No newline at end of file +) From e3d98f082a4deb3c7e72ae513c30225c8938fe67 Mon Sep 17 00:00:00 2001 From: Volodymyr Chekyrta Date: Tue, 2 Jan 2024 10:24:36 +0200 Subject: [PATCH 6/7] Removed unused auditAccessExpires from the NoAccessCourseContainerFragment screen --- .../main/java/org/openedx/app/AppRouter.kt | 5 ++- .../course/presentation/CourseRouter.kt | 3 +- .../container/CourseContainerFragment.kt | 3 +- .../NoAccessCourseContainerFragment.kt | 31 +++---------------- course/src/main/res/values-uk/strings.xml | 1 - course/src/main/res/values/strings.xml | 1 - 6 files changed, 8 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/org/openedx/app/AppRouter.kt b/app/src/main/java/org/openedx/app/AppRouter.kt index 22d8f2aeb..8dc6480d1 100644 --- a/app/src/main/java/org/openedx/app/AppRouter.kt +++ b/app/src/main/java/org/openedx/app/AppRouter.kt @@ -111,10 +111,9 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di override fun navigateToNoAccess( fm: FragmentManager, - title: String, - auditAccessExpires: Date? + title: String ) { - replaceFragment(fm, NoAccessCourseContainerFragment.newInstance(title, auditAccessExpires)) + replaceFragment(fm, NoAccessCourseContainerFragment.newInstance(title)) } //endregion diff --git a/course/src/main/java/org/openedx/course/presentation/CourseRouter.kt b/course/src/main/java/org/openedx/course/presentation/CourseRouter.kt index bd8332644..438ee0f69 100644 --- a/course/src/main/java/org/openedx/course/presentation/CourseRouter.kt +++ b/course/src/main/java/org/openedx/course/presentation/CourseRouter.kt @@ -15,8 +15,7 @@ interface CourseRouter { fun navigateToNoAccess( fm: FragmentManager, - title: String, - auditAccessExpires: Date? + title: String ) fun navigateToCourseSubsections( diff --git a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt index ef106b2f4..b461116f1 100644 --- a/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt +++ b/course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt @@ -72,8 +72,7 @@ class CourseContainerFragment : Fragment(R.layout.fragment_course_container) { } else { router.navigateToNoAccess( requireActivity().supportFragmentManager, - courseTitle, - null + courseTitle ) } } diff --git a/course/src/main/java/org/openedx/course/presentation/container/NoAccessCourseContainerFragment.kt b/course/src/main/java/org/openedx/course/presentation/container/NoAccessCourseContainerFragment.kt index 3e2c4a1e6..f6f5d8e7d 100644 --- a/course/src/main/java/org/openedx/course/presentation/container/NoAccessCourseContainerFragment.kt +++ b/course/src/main/java/org/openedx/course/presentation/container/NoAccessCourseContainerFragment.kt @@ -35,17 +35,6 @@ import org.openedx.course.R as courseR class NoAccessCourseContainerFragment : Fragment() { - private var courseTitle = "" - private var auditAccessExpires: Date? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - with(requireArguments()) { - courseTitle = getString(ARG_TITLE, "") - auditAccessExpires = parcelable(ARG_AUDIT_ACCESS_EXPIRES) - } - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -55,12 +44,9 @@ class NoAccessCourseContainerFragment : Fragment() { setContent { OpenEdXTheme { val windowSize = rememberWindowSize() - val auditAccessExpired = - auditAccessExpires != null && Date().after(auditAccessExpires) NoAccessCourseContainerScreen( windowSize = windowSize, - title = courseTitle, - auditAccessExpired = auditAccessExpired, + title = requireArguments().getString(ARG_TITLE, ""), onBackClick = { requireActivity().supportFragmentManager.popBackStack() } @@ -71,16 +57,13 @@ class NoAccessCourseContainerFragment : Fragment() { companion object { private const val ARG_TITLE = "title" - private const val ARG_AUDIT_ACCESS_EXPIRES = "auditAccessExpires" fun newInstance( title: String, - auditAccessExpires: Date? ): NoAccessCourseContainerFragment { val fragment = NoAccessCourseContainerFragment() fragment.arguments = bundleOf( - ARG_TITLE to title, - ARG_AUDIT_ACCESS_EXPIRES to auditAccessExpires + ARG_TITLE to title ) return fragment } @@ -93,7 +76,6 @@ class NoAccessCourseContainerFragment : Fragment() { private fun NoAccessCourseContainerScreen( windowSize: WindowSize, title: String, - auditAccessExpired: Boolean, onBackClick: () -> Unit ) { val scaffoldState = rememberScaffoldState() @@ -159,11 +141,7 @@ private fun NoAccessCourseContainerScreen( ) Spacer(modifier = Modifier.height(10.dp)) Text( - text = if (auditAccessExpired) { - stringResource(id = courseR.string.course_access_expired) - } else { - stringResource(id = courseR.string.course_not_started) - }, + text = stringResource(id = courseR.string.course_not_started), color = MaterialTheme.appColors.textPrimary, style = MaterialTheme.appTypography.bodyLarge ) @@ -183,8 +161,7 @@ fun NoAccessCourseContainerScreenPreview() { OpenEdXTheme { NoAccessCourseContainerScreen( windowSize = WindowSize(WindowType.Compact, WindowType.Compact), - title = "Example title", - auditAccessExpired = false, + title = "Course title", onBackClick = {} ) } diff --git a/course/src/main/res/values-uk/strings.xml b/course/src/main/res/values-uk/strings.xml index 5cf345aed..eb24850db 100644 --- a/course/src/main/res/values-uk/strings.xml +++ b/course/src/main/res/values-uk/strings.xml @@ -33,7 +33,6 @@ Повернутись до модуля Ви не можете записатися на цей курс, оскільки термін запису вже минув. Цей курс ще не розпочався. - Ваш доступ до цього курсу закінчився. Ви не підключені до Інтернету. Будь ласка, перевірте ваше підключення до Інтернету. Курс Відео diff --git a/course/src/main/res/values/strings.xml b/course/src/main/res/values/strings.xml index 144b2267a..cea87765a 100644 --- a/course/src/main/res/values/strings.xml +++ b/course/src/main/res/values/strings.xml @@ -33,7 +33,6 @@ Next section You cannot enroll in this course because the enrollment date is over. This course hasn’t started yet. - Your access to this course has expired. You are not connected to the Internet. Please check your Internet connection. Course Video From 0c6b2150f424ea27531be1686899abbf7fc0d2d8 Mon Sep 17 00:00:00 2001 From: Volodymyr Chekyrta Date: Wed, 3 Jan 2024 10:07:15 +0200 Subject: [PATCH 7/7] Change CourseApi.getCourseDetail endpoint --- core/src/main/java/org/openedx/core/data/api/CourseApi.kt | 5 ++--- .../org/openedx/course/data/repository/CourseRepository.kt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/openedx/core/data/api/CourseApi.kt b/core/src/main/java/org/openedx/core/data/api/CourseApi.kt index c556c3d83..e7f97b2e6 100644 --- a/core/src/main/java/org/openedx/core/data/api/CourseApi.kt +++ b/core/src/main/java/org/openedx/core/data/api/CourseApi.kt @@ -29,11 +29,10 @@ interface CourseApi { ) ): CourseList - @GET("/api/mobile/v3/course_info/{course_id}/info") + @GET("/api/courses/v1/courses/{course_id}") suspend fun getCourseDetail( @Path("course_id") courseId: String?, - @Query("username") username: String? = null, - @Query("is_enrolled") isEnrolled: Boolean = true, + @Query("username") username: String? = null ): CourseDetails @GET( diff --git a/course/src/main/java/org/openedx/course/data/repository/CourseRepository.kt b/course/src/main/java/org/openedx/course/data/repository/CourseRepository.kt index 701c5df8c..ab0fe1e49 100644 --- a/course/src/main/java/org/openedx/course/data/repository/CourseRepository.kt +++ b/course/src/main/java/org/openedx/course/data/repository/CourseRepository.kt @@ -21,7 +21,7 @@ class CourseRepository( private var courseStructure: CourseStructure? = null suspend fun getCourseDetail(id: String): Course { - val course = api.getCourseDetail(id) + val course = api.getCourseDetail(id, preferencesManager.user?.username) courseDao.updateCourseEntity(CourseEntity.createFrom(course)) return course.mapToDomain() }