Skip to content

Commit

Permalink
feat: WebView discovery capabilities for Pre-Login Experience
Browse files Browse the repository at this point in the history
- Integrate search to align with configured discovery settings.
- “Explore All Courses" redirects based on the feature discovery flag.
- Auth Panel (SignIn, Register) remains visible during pre-login webview discovery.
- Ensure Sign In & Enroll mirror Native Discovery & Market App functionality.
- Clear edit text after submit Logistration.
- Fix test cases for View Models.

LEARNER-9798
  • Loading branch information
farhan-arshad-dev committed Feb 14, 2024
1 parent e6876be commit 43a5b9c
Show file tree
Hide file tree
Showing 28 changed files with 420 additions and 99 deletions.
23 changes: 14 additions & 9 deletions app/src/main/java/org/openedx/app/AppRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import org.openedx.dashboard.presentation.DashboardRouter
import org.openedx.dashboard.presentation.program.ProgramFragment
import org.openedx.discovery.presentation.DiscoveryRouter
import org.openedx.discovery.presentation.NativeDiscoveryFragment
import org.openedx.discovery.presentation.WebViewDiscoveryFragment
import org.openedx.discovery.presentation.search.CourseSearchFragment
import org.openedx.discussion.domain.model.DiscussionComment
import org.openedx.discussion.domain.model.Thread
Expand All @@ -52,19 +53,19 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
ProfileRouter, AppUpgradeRouter, WhatsNewRouter {

//region AuthRouter
override fun navigateToMain(fm: FragmentManager, courseId: String?) {
override fun navigateToMain(fm: FragmentManager, courseId: String?, infoType: String?) {
fm.popBackStack()
fm.beginTransaction()
.replace(R.id.container, MainFragment.newInstance(courseId))
.replace(R.id.container, MainFragment.newInstance(courseId, infoType))
.commit()
}

override fun navigateToSignIn(fm: FragmentManager, courseId: String?) {
replaceFragmentWithBackStack(fm, SignInFragment.newInstance(courseId))
override fun navigateToSignIn(fm: FragmentManager, courseId: String?, infoType: String?) {
replaceFragmentWithBackStack(fm, SignInFragment.newInstance(courseId, infoType))
}

override fun navigateToSignUp(fm: FragmentManager, courseId: String?) {
replaceFragmentWithBackStack(fm, SignUpFragment.newInstance(courseId))
override fun navigateToSignUp(fm: FragmentManager, courseId: String?, infoType: String?) {
replaceFragmentWithBackStack(fm, SignUpFragment.newInstance(courseId, infoType))
}

override fun navigateToLogistration(fm: FragmentManager, courseId: String?) {
Expand All @@ -75,14 +76,18 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
replaceFragmentWithBackStack(fm, RestorePasswordFragment())
}

override fun navigateToDiscoverCourses(fm: FragmentManager, querySearch: String) {
override fun navigateToNativeDiscoverCourses(fm: FragmentManager, querySearch: String) {
replaceFragmentWithBackStack(fm, NativeDiscoveryFragment.newInstance(querySearch))
}

override fun navigateToWhatsNew(fm: FragmentManager, courseId: String?) {
override fun navigateToWebDiscoverCourses(fm: FragmentManager, querySearch: String) {
replaceFragmentWithBackStack(fm, WebViewDiscoveryFragment.newInstance(querySearch))
}

override fun navigateToWhatsNew(fm: FragmentManager, courseId: String?, infoType: String?) {
fm.popBackStack()
fm.beginTransaction()
.replace(R.id.container, WhatsNewFragment.newInstance(courseId))
.replace(R.id.container, WhatsNewFragment.newInstance(courseId, infoType))
.commit()
}

Expand Down
23 changes: 17 additions & 6 deletions app/src/main/java/org/openedx/app/MainFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.openedx.app.adapter.MainNavigationFragmentAdapter
import org.openedx.app.databinding.FragmentMainBinding
import org.openedx.core.config.Config
import org.openedx.core.presentation.global.app_upgrade.UpgradeRequiredFragment
import org.openedx.core.presentation.global.viewBinding
import org.openedx.dashboard.presentation.dashboard.DashboardFragment
Expand All @@ -27,6 +28,7 @@ class MainFragment : Fragment(R.layout.fragment_main) {
private val analytics by inject<AppAnalytics>()
private val viewModel by viewModel<MainViewModel>()
private val router by inject<DiscoveryRouter>()
private val config by inject<Config>()

private lateinit var adapter: MainNavigationFragmentAdapter

Expand Down Expand Up @@ -82,12 +84,19 @@ class MainFragment : Fragment(R.layout.fragment_main) {
}

requireArguments().apply {
this.getString(ARG_COURSE_ID, null)?.let {
if (it.isNotBlank()) {
router.navigateToCourseDetail(parentFragmentManager, it)
getString(ARG_COURSE_ID).takeIf { it.isNullOrBlank().not() }?.let { courseId ->
val infoType = getString(ARG_INFO_TYPE)

if (config.getDiscoveryConfig().isViewTypeWebView() && infoType != null) {
router.navigateToCourseInfo(parentFragmentManager, courseId, infoType)
} else {
router.navigateToCourseDetail(parentFragmentManager, courseId)
}

// Clear arguments after navigation
putString(ARG_COURSE_ID, "")
putString(ARG_INFO_TYPE, "")
}
this.putString(ARG_COURSE_ID, null)
}
}

Expand Down Expand Up @@ -121,10 +130,12 @@ class MainFragment : Fragment(R.layout.fragment_main) {

companion object {
private const val ARG_COURSE_ID = "courseId"
fun newInstance(courseId: String? = null): MainFragment {
private const val ARG_INFO_TYPE = "info_type"
fun newInstance(courseId: String? = null, infoType: String? = null): MainFragment {
val fragment = MainFragment()
fragment.arguments = bundleOf(
ARG_COURSE_ID to courseId
ARG_COURSE_ID to courseId,
ARG_INFO_TYPE to infoType
)
return fragment
}
Expand Down
40 changes: 34 additions & 6 deletions app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ val screenModule = module {
factory { AuthRepository(get(), get(), get()) }
factory { AuthInteractor(get()) }
factory { Validator() }
viewModel { (courseId: String?) ->
viewModel { (courseId: String?, infoType: String?) ->
SignInViewModel(
get(),
get(),
Expand All @@ -75,10 +75,12 @@ val screenModule = module {
get(),
get(),
courseId,
infoType,
)
}
viewModel { (courseId: String?) ->
SignUpViewModel(get(), get(), get(), get(), get(), get(), get(), courseId)

viewModel { (courseId: String?, infoType: String?) ->
SignUpViewModel(get(), get(), get(), get(), get(), get(), get(), courseId, infoType)
}
viewModel { RestorePasswordViewModel(get(), get(), get(), get()) }

Expand All @@ -89,7 +91,15 @@ val screenModule = module {
factory { DiscoveryRepository(get(), get()) }
factory { DiscoveryInteractor(get()) }
viewModel { NativeDiscoveryViewModel(get(), get(), get(), get(), get(), get(), get()) }
viewModel { WebViewDiscoveryViewModel(get(), get(), get()) }
viewModel { (querySearch: String) ->
WebViewDiscoveryViewModel(
get(),
get(),
get(),
get(),
querySearch
)
}

factory { ProfileRepository(get(), get(), get(), get(), get()) }
factory { ProfileInteractor(get()) }
Expand All @@ -116,7 +126,19 @@ val screenModule = module {

single { CourseRepository(get(), get(), get(), get()) }
factory { CourseInteractor(get()) }
viewModel { CourseInfoViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { (pathId: String, infoType: String) ->
CourseInfoViewModel(
get(),
get(),
get(),
get(),
get(),
get(),
get(),
pathId,
infoType
)
}
viewModel { (courseId: String) ->
CourseDetailsViewModel(
courseId,
Expand Down Expand Up @@ -264,7 +286,13 @@ val screenModule = module {
)
}

viewModel { (courseId: String?) -> WhatsNewViewModel(courseId, get()) }
viewModel { (courseId: String?, infoType: String?) ->
WhatsNewViewModel(
courseId,
infoType,
get()
)
}
viewModel { HtmlUnitViewModel(get(), get(), get(), get()) }

viewModel { ProgramViewModel(get(), get(), get(), get(), get(), get(), get()) }
Expand Down
12 changes: 7 additions & 5 deletions auth/src/main/java/org/openedx/auth/presentation/AuthRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ import androidx.fragment.app.FragmentManager

interface AuthRouter {

fun navigateToMain(fm: FragmentManager, courseId: String?)
fun navigateToMain(fm: FragmentManager, courseId: String?, infoType: String?)

fun navigateToSignIn(fm: FragmentManager, courseId: String?)
fun navigateToSignIn(fm: FragmentManager, courseId: String?, infoType: String?)

fun navigateToLogistration(fm: FragmentManager, courseId: String?)

fun navigateToSignUp(fm: FragmentManager, courseId: String?)
fun navigateToSignUp(fm: FragmentManager, courseId: String?, infoType: String?)

fun navigateToRestorePassword(fm: FragmentManager)

fun navigateToWhatsNew(fm: FragmentManager, courseId: String? = null)
fun navigateToWhatsNew(fm: FragmentManager, courseId: String? = null, infoType: String? = null)

fun navigateToDiscoverCourses(fm: FragmentManager, querySearch: String)
fun navigateToWebDiscoverCourses(fm: FragmentManager, querySearch: String)

fun navigateToNativeDiscoverCourses(fm: FragmentManager, querySearch: String)

fun clearBackStack(fm: FragmentManager)
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import androidx.fragment.app.Fragment
import org.koin.android.ext.android.inject
import org.openedx.auth.R
import org.openedx.auth.presentation.AuthRouter
import org.openedx.core.config.Config
import org.openedx.core.ui.AuthButtonsPanel
import org.openedx.core.ui.SearchBar
import org.openedx.core.ui.displayCutoutForLandscape
Expand All @@ -53,6 +54,7 @@ import org.openedx.core.ui.theme.compose.LogistrationLogoView
class LogistrationFragment : Fragment() {

private val router: AuthRouter by inject()
private val config by inject<Config>()

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -63,15 +65,26 @@ class LogistrationFragment : Fragment() {
setContent {
OpenEdXTheme {
val courseId = arguments?.getString(ARG_COURSE_ID, "")
val isDiscoveryTypeWebView = config.getDiscoveryConfig().isViewTypeWebView()
LogistrationScreen(
onSignInClick = {
router.navigateToSignIn(parentFragmentManager, courseId)
router.navigateToSignIn(parentFragmentManager, courseId, null)
},
onRegisterClick = {
router.navigateToSignUp(parentFragmentManager, courseId)
router.navigateToSignUp(parentFragmentManager, courseId, null)
},
onSearchClick = { querySearch ->
router.navigateToDiscoverCourses(parentFragmentManager, querySearch)
if (isDiscoveryTypeWebView) {
router.navigateToWebDiscoverCourses(
parentFragmentManager,
querySearch
)
} else {
router.navigateToNativeDiscoverCourses(
parentFragmentManager,
querySearch
)
}
}
)
}
Expand Down Expand Up @@ -153,6 +166,7 @@ private fun LogistrationScreen(
label = stringResource(id = R.string.pre_auth_search_hint),
requestFocus = false,
searchValue = textFieldValue,
clearOnSubmit = true,
keyboardActions = {
focusManager.clearFocus()
onSearchClick(textFieldValue.text)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import org.openedx.core.ui.theme.OpenEdXTheme
class SignInFragment : Fragment() {

private val viewModel: SignInViewModel by viewModel {
parametersOf(requireArguments().getString(ARG_COURSE_ID, null))
parametersOf(
requireArguments().getString(ARG_COURSE_ID, ""),
requireArguments().getString(ARG_INFO_TYPE, "")
)
}
private val router: AuthRouter by inject()
private val whatsNewGlobalManager by inject<WhatsNewGlobalManager>()
Expand Down Expand Up @@ -64,7 +67,7 @@ class SignInFragment : Fragment() {

AuthEvent.RegisterClick -> {
viewModel.signUpClickedEvent()
router.navigateToSignUp(parentFragmentManager, null)
router.navigateToSignUp(parentFragmentManager, null, null)
}

AuthEvent.BackClick -> {
Expand All @@ -79,9 +82,17 @@ class SignInFragment : Fragment() {
if (state.loginSuccess) {
router.clearBackStack(parentFragmentManager)
if (isNeedToShowWhatsNew) {
router.navigateToWhatsNew(parentFragmentManager, viewModel.courseId)
router.navigateToWhatsNew(
parentFragmentManager,
viewModel.courseId,
viewModel.infoType
)
} else {
router.navigateToMain(parentFragmentManager, viewModel.courseId)
router.navigateToMain(
parentFragmentManager,
viewModel.courseId,
viewModel.infoType
)
}
}

Expand All @@ -99,10 +110,12 @@ class SignInFragment : Fragment() {

companion object {
private const val ARG_COURSE_ID = "courseId"
fun newInstance(courseId: String?): SignInFragment {
private const val ARG_INFO_TYPE = "info_type"
fun newInstance(courseId: String?, infoType: String?): SignInFragment {
val fragment = SignInFragment()
fragment.arguments = bundleOf(
ARG_COURSE_ID to courseId
ARG_COURSE_ID to courseId,
ARG_INFO_TYPE to infoType
)
return fragment
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class SignInViewModel(
private val oAuthHelper: OAuthHelper,
config: Config,
val courseId: String?,
val infoType: String?,
) : BaseViewModel() {

private val logger = Logger("SignInViewModel")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import org.openedx.core.ui.theme.OpenEdXTheme
class SignUpFragment : Fragment() {

private val viewModel by viewModel<SignUpViewModel> {
parametersOf(requireArguments().getString(ARG_COURSE_ID, ""))
parametersOf(
requireArguments().getString(ARG_COURSE_ID, ""),
requireArguments().getString(ARG_INFO_TYPE, "")
)
}
private val router by inject<AuthRouter>()

Expand Down Expand Up @@ -73,7 +76,11 @@ class SignUpFragment : Fragment() {
LaunchedEffect(uiState.successLogin) {
if (uiState.successLogin) {
router.clearBackStack(requireActivity().supportFragmentManager)
router.navigateToMain(parentFragmentManager, viewModel.courseId)
router.navigateToMain(
parentFragmentManager,
viewModel.courseId,
viewModel.infoType
)
}
}
} else {
Expand All @@ -89,10 +96,12 @@ class SignUpFragment : Fragment() {

companion object {
private const val ARG_COURSE_ID = "courseId"
fun newInstance(courseId: String?): SignUpFragment {
private const val ARG_INFO_TYPE = "info_type"
fun newInstance(courseId: String?, infoType: String?): SignUpFragment {
val fragment = SignUpFragment()
fragment.arguments = bundleOf(
ARG_COURSE_ID to courseId
ARG_COURSE_ID to courseId,
ARG_INFO_TYPE to infoType
)
return fragment
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class SignUpViewModel(
private val oAuthHelper: OAuthHelper,
private val config: Config,
val courseId: String?,
val infoType: String?,
) : BaseViewModel() {

private val logger = Logger("SignUpViewModel")
Expand Down
Loading

0 comments on commit 43a5b9c

Please sign in to comment.