From 091cbccac468da6f4021f997c65219625f5f095d Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Mon, 6 Nov 2023 19:38:41 +0500 Subject: [PATCH 01/10] feat: pre-login mobile app exploration - Feature is implemented behind a feature flag `preLoginExperienceEnabled` - User will be able to navigate to Signup, Signin, DiscoveryCourses & SearchCourses screen - Back button is added on required screens for back navigation - Navigation from SignIn to Signup is removed fix: LEARNER-9663 --- .../main/java/org/openedx/app/AppActivity.kt | 24 ++- .../main/java/org/openedx/app/AppRouter.kt | 43 +++- .../openedx/auth/presentation/AuthRouter.kt | 8 +- .../presentation/preAuth/PreAuthFragment.kt | 203 ++++++++++++++++++ .../presentation/signin/SignInFragment.kt | 59 +++-- auth/src/main/res/values/strings.xml | 6 +- config.yaml | 0 .../presentation/DiscoveryFragment.kt | 52 ++++- .../discovery/presentation/DiscoveryRouter.kt | 5 +- .../search/CourseSearchFragment.kt | 27 ++- 10 files changed, 383 insertions(+), 44 deletions(-) create mode 100644 auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt create mode 100644 config.yaml diff --git a/app/src/main/java/org/openedx/app/AppActivity.kt b/app/src/main/java/org/openedx/app/AppActivity.kt index d0bc68d05..90b057441 100644 --- a/app/src/main/java/org/openedx/app/AppActivity.kt +++ b/app/src/main/java/org/openedx/app/AppActivity.kt @@ -10,6 +10,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat +import androidx.fragment.app.Fragment import androidx.window.layout.WindowMetricsCalculator import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel @@ -24,6 +25,7 @@ import org.openedx.core.ui.WindowType import org.openedx.profile.presentation.ProfileRouter import org.openedx.whatsnew.WhatsNewManager import org.openedx.whatsnew.presentation.whatsnew.WhatsNewFragment +import org.openedx.core.BuildConfig as coreBuildConfig class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder { @@ -110,21 +112,19 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder { if (savedInstanceState == null) { when { corePreferencesManager.user == null -> { - supportFragmentManager.beginTransaction() - .add(R.id.container, SignInFragment()) - .commit() + if (coreBuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { + addFragment(PreAuthFragment()) + } else { + addFragment(SignInFragment()) + } } whatsNewManager.shouldShowWhatsNew() -> { - supportFragmentManager.beginTransaction() - .add(R.id.container, WhatsNewFragment()) - .commit() + addFragment(WhatsNewFragment()) } corePreferencesManager.user != null -> { - supportFragmentManager.beginTransaction() - .add(R.id.container, MainFragment()) - .commit() + addFragment(MainFragment()) } } } @@ -134,6 +134,12 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder { } } + private fun addFragment(fragment: Fragment) { + supportFragmentManager.beginTransaction() + .add(R.id.container, fragment) + .commit() + } + private fun computeWindowSizeClasses() { val metrics = WindowMetricsCalculator.getOrCreate() .computeCurrentWindowMetrics(this) diff --git a/app/src/main/java/org/openedx/app/AppRouter.kt b/app/src/main/java/org/openedx/app/AppRouter.kt index a5c16ab28..d015c2f35 100644 --- a/app/src/main/java/org/openedx/app/AppRouter.kt +++ b/app/src/main/java/org/openedx/app/AppRouter.kt @@ -4,9 +4,11 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentTransaction import org.openedx.auth.presentation.AuthRouter +import org.openedx.auth.presentation.preAuth.PreAuthFragment 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.BuildConfig import org.openedx.core.FragmentViewType import org.openedx.core.domain.model.CoursewareAccess import org.openedx.core.presentation.course.CourseViewMode @@ -23,6 +25,7 @@ import org.openedx.course.presentation.unit.container.CourseUnitContainerFragmen 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.DiscoveryFragment import org.openedx.discovery.presentation.DiscoveryRouter import org.openedx.discovery.presentation.search.CourseSearchFragment import org.openedx.discussion.domain.model.DiscussionComment @@ -56,6 +59,10 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di .commit() } + override fun navigateToSignIn(fm: FragmentManager) { + replaceFragmentWithBackStack(fm, SignInFragment()) + } + override fun navigateToSignUp(fm: FragmentManager) { replaceFragmentWithBackStack(fm, SignUpFragment()) } @@ -64,6 +71,10 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di replaceFragmentWithBackStack(fm, RestorePasswordFragment()) } + override fun navigateToDiscoverCourses(fm: FragmentManager, querySearch: String) { + replaceFragmentWithBackStack(fm, DiscoveryFragment.newInstance(querySearch)) + } + override fun navigateToWhatsNew(fm: FragmentManager) { fm.popBackStack() fm.beginTransaction() @@ -77,8 +88,8 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di replaceFragmentWithBackStack(fm, CourseDetailsFragment.newInstance(courseId)) } - override fun navigateToCourseSearch(fm: FragmentManager) { - replaceFragmentWithBackStack(fm, CourseSearchFragment()) + override fun navigateToCourseSearch(fm: FragmentManager, querySearch: String) { + replaceFragmentWithBackStack(fm, CourseSearchFragment.newInstance(querySearch)) } override fun navigateToUpgradeRequired(fm: FragmentManager) { @@ -105,7 +116,10 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di coursewareAccess: CoursewareAccess, auditAccessExpires: Date? ) { - replaceFragment(fm, NoAccessCourseContainerFragment.newInstance(title,coursewareAccess, auditAccessExpires)) + replaceFragment( + fm, + NoAccessCourseContainerFragment.newInstance(title, coursewareAccess, auditAccessExpires) + ) } //endregion @@ -174,7 +188,13 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di ) { replaceFragmentWithBackStack( fm, - YoutubeVideoFullScreenFragment.newInstance(videoUrl, videoTime, blockId, courseId, isPlaying) + YoutubeVideoFullScreenFragment.newInstance( + videoUrl, + videoTime, + blockId, + courseId, + isPlaying + ) ) } @@ -276,8 +296,11 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di beginTransaction().remove(fragment).commit() } popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) - beginTransaction().replace(R.id.container, SignInFragment()) - .commit() + if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { + replaceFragment(fm, PreAuthFragment()) + } else { + replaceFragment(fm, SignInFragment()) + } } } //endregion @@ -289,7 +312,11 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di .commit() } - private fun replaceFragment(fm: FragmentManager, fragment: Fragment, transaction: Int = FragmentTransaction.TRANSIT_NONE) { + private fun replaceFragment( + fm: FragmentManager, + fragment: Fragment, + transaction: Int = FragmentTransaction.TRANSIT_NONE + ) { fm.beginTransaction() .setTransition(transaction) .replace(R.id.container, fragment, fragment.javaClass.simpleName) @@ -303,4 +330,4 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di .replace(R.id.container, ProfileFragment()) .commit() } -} \ No newline at end of file +} diff --git a/auth/src/main/java/org/openedx/auth/presentation/AuthRouter.kt b/auth/src/main/java/org/openedx/auth/presentation/AuthRouter.kt index e7a16805a..f47244526 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/AuthRouter.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/AuthRouter.kt @@ -6,9 +6,13 @@ interface AuthRouter { fun navigateToMain(fm: FragmentManager) + fun navigateToSignIn(fm: FragmentManager) + fun navigateToSignUp(fm: FragmentManager) fun navigateToRestorePassword(fm: FragmentManager) - fun navigateToWhatsNew(fm : FragmentManager) -} \ No newline at end of file + fun navigateToWhatsNew(fm: FragmentManager) + + fun navigateToDiscoverCourses(fm: FragmentManager, querySearch: String) +} diff --git a/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt b/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt new file mode 100644 index 000000000..e07f84139 --- /dev/null +++ b/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt @@ -0,0 +1,203 @@ +package org.openedx.auth.presentation.preAuth + +import android.content.res.Configuration +import android.os.Bundle +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Scaffold +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.material.rememberScaffoldState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +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.ui.OpenEdXButton +import org.openedx.core.ui.OpenEdXOutlinedButton +import org.openedx.core.ui.SearchBar +import org.openedx.core.ui.displayCutoutForLandscape +import org.openedx.core.ui.noRippleClickable +import org.openedx.core.ui.theme.OpenEdXTheme +import org.openedx.core.ui.theme.appColors +import org.openedx.core.ui.theme.appTypography + +class PreAuthFragment : Fragment() { + + private val router: AuthRouter by inject() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ) = ComposeView(requireContext()).apply { + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) + setContent { + OpenEdXTheme { + PreLoginScreen( + onLoginClick = { + router.navigateToSignIn(parentFragmentManager) + }, + onRegisterClick = { + router.navigateToSignUp(parentFragmentManager) + }, + onSearchClick = { querySearch -> + router.navigateToDiscoverCourses(parentFragmentManager, querySearch) + } + ) + } + } + } +} + +@Composable +private fun PreLoginScreen( + onSearchClick: (query: String) -> Unit, + onRegisterClick: () -> Unit, + onLoginClick: () -> Unit, +) { + + var textFieldValue by rememberSaveable(stateSaver = TextFieldValue.Saver) { + mutableStateOf(TextFieldValue("")) + } + val scaffoldState = rememberScaffoldState() + val scrollState = rememberScrollState() + Scaffold( + scaffoldState = scaffoldState, + modifier = Modifier + .fillMaxSize(), + backgroundColor = MaterialTheme.appColors.background + ) { + Surface( + modifier = Modifier + .padding(it) + .fillMaxSize() + .verticalScroll(scrollState) + .displayCutoutForLandscape(), + color = MaterialTheme.appColors.background + ) { + Column( + modifier = Modifier.padding( + start = 16.dp, + end = 16.dp, + top = 32.dp, + bottom = 32.dp + ) + ) { + Image( + painter = painterResource(id = org.openedx.core.R.drawable.core_ic_logo), + contentDescription = null, + modifier = Modifier + .padding(top = 32.dp, bottom = 32.dp) + .width(170.dp) + .height(48.dp), + colorFilter = ColorFilter.tint(MaterialTheme.appColors.primary) + ) + Text( + text = stringResource(id = R.string.pre_auth_title), + color = MaterialTheme.appColors.textPrimary, + style = MaterialTheme.appTypography.headlineSmall, + modifier = Modifier.padding(bottom = 32.dp) + ) + val focusManager = LocalFocusManager.current + Column(Modifier.padding(bottom = 8.dp)) { + Text( + modifier = Modifier.padding(bottom = 8.dp), + style = MaterialTheme.appTypography.titleMedium, + text = stringResource(id = R.string.pre_auth_search_title), + ) + SearchBar( + modifier = Modifier + .fillMaxWidth() + .height(48.dp), + label = stringResource(id = R.string.pre_auth_search_hint), + requestFocus = false, + searchValue = textFieldValue, + keyboardActions = { + focusManager.clearFocus() + onSearchClick(textFieldValue.text) + }, + onValueChanged = { text -> + textFieldValue = text + }, + onClearValue = { + textFieldValue = TextFieldValue("") + } + ) + } + + Text( + modifier = Modifier + .padding(bottom = 32.dp) + .noRippleClickable { + onSearchClick("") + }, + text = stringResource(id = R.string.pre_auth_explore_all_courses), + color = MaterialTheme.appColors.primary, + style = MaterialTheme.appTypography.labelLarge + ) + + Spacer(modifier = Modifier.weight(1f)) + + Row { + OpenEdXButton( + width = Modifier + .width(0.dp) + .weight(1f), + text = stringResource(id = R.string.auth_register), + onClick = { onRegisterClick() } + ) + + OpenEdXOutlinedButton( + modifier = Modifier + .width(100.dp) + .padding(start = 16.dp), + text = stringResource(id = R.string.auth_sign_in), + onClick = { onLoginClick() }, + borderColor = MaterialTheme.appColors.textFieldBorder, + textColor = MaterialTheme.appColors.primary + ) + } + } + } + } +} + +@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun SignInScreenPreview() { + OpenEdXTheme { + PreLoginScreen( + onSearchClick = {}, + onLoginClick = {}, + onRegisterClick = {} + ) + } +} diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt index bf1e6e280..435e87483 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt @@ -17,6 +17,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.rememberScrollState @@ -41,6 +42,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.LocalFocusManager @@ -61,8 +63,12 @@ import org.koin.androidx.viewmodel.ext.android.viewModel import org.openedx.auth.R import org.openedx.auth.presentation.AuthRouter import org.openedx.auth.presentation.ui.LoginTextField +import org.openedx.core.AppUpdateState +import org.openedx.core.BuildConfig import org.openedx.core.UIMessage +import org.openedx.core.presentation.global.AppDataHolder import org.openedx.core.presentation.global.app_upgrade.AppUpgradeRequiredScreen +import org.openedx.core.ui.BackBtn import org.openedx.core.ui.HandleUIMessage import org.openedx.core.ui.OpenEdXButton import org.openedx.core.ui.WindowSize @@ -75,7 +81,6 @@ import org.openedx.core.ui.theme.appColors import org.openedx.core.ui.theme.appShapes import org.openedx.core.ui.theme.appTypography import org.openedx.core.ui.windowSizeValue -import org.openedx.core.AppUpdateState import org.openedx.core.presentation.global.WhatsNewGlobalManager class SignInFragment : Fragment() { @@ -114,11 +119,14 @@ class SignInFragment : Fragment() { onForgotPasswordClick = { viewModel.forgotPasswordClickedEvent() router.navigateToRestorePassword(parentFragmentManager) + }, + onBackClick = { + requireActivity().supportFragmentManager.popBackStackImmediate() } ) - LaunchedEffect(loginSuccess) { - val isNeedToShowWhatsNew = whatsNewGlobalManager.shouldShowWhatsNew() + val isNeedToShowWhatsNew = + whatsNewGlobalManager.shouldShowWhatsNew() if (loginSuccess) { if (isNeedToShowWhatsNew) { router.navigateToWhatsNew(parentFragmentManager) @@ -126,8 +134,8 @@ class SignInFragment : Fragment() { router.navigateToMain(parentFragmentManager) } } - } + } } else { AppUpgradeRequiredScreen( onUpdateClick = { @@ -147,7 +155,8 @@ private fun LoginScreen( uiMessage: UIMessage?, onLoginClick: (login: String, password: String) -> Unit, onRegisterClick: () -> Unit, - onForgotPasswordClick: () -> Unit + onForgotPasswordClick: () -> Unit, + onBackClick: () -> Unit, ) { val scaffoldState = rememberScaffoldState() val scrollState = rememberScrollState() @@ -196,7 +205,21 @@ private fun LoginScreen( uiMessage = uiMessage, scaffoldState = scaffoldState ) - + if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { + Box( + modifier = Modifier + .statusBarsPadding() + .fillMaxWidth(), + contentAlignment = Alignment.CenterStart + ) { + BackBtn( + modifier = Modifier.padding(end = 16.dp), + tint = Color.White + ) { + onBackClick() + } + } + } Column( Modifier.padding(it), horizontalAlignment = Alignment.CenterHorizontally @@ -292,14 +315,16 @@ private fun AuthForm( .fillMaxWidth() .padding(top = 20.dp, bottom = 36.dp) ) { - Text( - modifier = Modifier.noRippleClickable { - onRegisterClick() - }, - text = stringResource(id = R.string.auth_register), - color = MaterialTheme.appColors.primary, - style = MaterialTheme.appTypography.labelLarge - ) + if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED.not()) { + Text( + modifier = Modifier.noRippleClickable { + onRegisterClick() + }, + text = stringResource(id = R.string.auth_register), + color = MaterialTheme.appColors.primary, + style = MaterialTheme.appTypography.labelLarge + ) + } Spacer(modifier = Modifier.weight(1f)) Text( modifier = Modifier.noRippleClickable { @@ -393,7 +418,8 @@ private fun SignInScreenPreview() { }, onRegisterClick = {}, - onForgotPasswordClick = {} + onForgotPasswordClick = {}, + onBackClick = {}, ) } } @@ -412,7 +438,8 @@ private fun SignInScreenTabletPreview() { }, onRegisterClick = {}, - onForgotPasswordClick = {} + onForgotPasswordClick = {}, + onBackClick = {}, ) } } \ No newline at end of file diff --git a/auth/src/main/res/values/strings.xml b/auth/src/main/res/values/strings.xml index 57b333598..25bf31694 100644 --- a/auth/src/main/res/values/strings.xml +++ b/auth/src/main/res/values/strings.xml @@ -1,5 +1,9 @@ - + + Courses and Programs from the world\'s best universities in your pocket. + What do you want to learn? + Search our 3000+ courses + Explore all courses Sign in Sign up Register diff --git a/config.yaml b/config.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt index 541d1af07..03a84cbe6 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import androidx.core.os.bundleOf import androidx.fragment.app.Fragment import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel @@ -62,6 +63,7 @@ class DiscoveryFragment : Fragment() { val refreshing by viewModel.isUpdating.observeAsState(false) val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState() val wasUpdateDialogClosed by remember { wasUpdateDialogClosed } + val querySearch = arguments?.getString(ARG_SEARCH_QUERY, "") ?: "" DiscoveryScreen( windowSize = windowSize, @@ -93,7 +95,7 @@ class DiscoveryFragment : Fragment() { onSearchClick = { viewModel.discoverySearchBarClickedEvent() router.navigateToCourseSearch( - requireActivity().supportFragmentManager + requireActivity().supportFragmentManager, "" ) }, paginationCallback = { @@ -111,10 +113,34 @@ class DiscoveryFragment : Fragment() { requireParentFragment().parentFragmentManager, course.id ) + }, + onBackClick = { + requireActivity().supportFragmentManager.popBackStackImmediate() }) + LaunchedEffect(key1 = uiState) { + if (querySearch.isNotEmpty()) { + router.navigateToCourseSearch( + requireActivity().supportFragmentManager, querySearch + ) + arguments?.let { + it.putString(ARG_SEARCH_QUERY, "") + } + } + } } } } + + companion object { + private const val ARG_SEARCH_QUERY = "query_search" + fun newInstance(querySearch: String): DiscoveryFragment { + val fragment = DiscoveryFragment() + fragment.arguments = bundleOf( + ARG_SEARCH_QUERY to querySearch + ) + return fragment + } + } } @@ -133,7 +159,8 @@ internal fun DiscoveryScreen( onSwipeRefresh: () -> Unit, onReloadClick: () -> Unit, paginationCallback: () -> Unit, - onItemClick: (Course) -> Unit + onItemClick: (Course) -> Unit, + onBackClick: () -> Unit ) { val scaffoldState = rememberScaffoldState() val scrollState = rememberLazyListState() @@ -185,6 +212,21 @@ internal fun DiscoveryScreen( HandleUIMessage(uiMessage = uiMessage, scaffoldState = scaffoldState) + if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { + Box( + modifier = Modifier + .statusBarsPadding() + .fillMaxWidth(), + contentAlignment = Alignment.CenterStart + ) { + BackBtn( + modifier = Modifier.padding(end = 16.dp), + tint = MaterialTheme.appColors.primary + ) { + onBackClick() + } + } + } Column( Modifier .fillMaxSize() @@ -391,7 +433,8 @@ private fun DiscoveryScreenPreview() { canLoadMore = false, refreshing = false, hasInternetConnection = true, - appUpgradeParameters = AppUpdateState.AppUpgradeParameters() + appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), + onBackClick = {}, ) } } @@ -426,7 +469,8 @@ private fun DiscoveryScreenTabletPreview() { canLoadMore = false, refreshing = false, hasInternetConnection = true, - appUpgradeParameters = AppUpdateState.AppUpgradeParameters() + appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), + onBackClick = {}, ) } } diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryRouter.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryRouter.kt index 408507d46..ada679ce4 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryRouter.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryRouter.kt @@ -6,8 +6,7 @@ interface DiscoveryRouter { fun navigateToCourseDetail(fm: FragmentManager, courseId: String) - fun navigateToCourseSearch(fm: FragmentManager) + fun navigateToCourseSearch(fm: FragmentManager, querySearch: String) fun navigateToUpgradeRequired(fm: FragmentManager) - -} \ No newline at end of file +} diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt index 5a78f8fe3..0535a061d 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt @@ -47,6 +47,7 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow @@ -55,6 +56,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex +import androidx.core.os.bundleOf import androidx.fragment.app.Fragment import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel @@ -101,6 +103,7 @@ class CourseSearchFragment : Fragment() { val uiMessage by viewModel.uiMessage.observeAsState() val canLoadMore by viewModel.canLoadMore.observeAsState(false) val refreshing by viewModel.isUpdating.observeAsState(false) + val querySearch = arguments?.getString(ARG_SEARCH_QUERY, "") ?: "" CourseSearchScreen( windowSize = windowSize, @@ -109,6 +112,7 @@ class CourseSearchFragment : Fragment() { apiHostUrl = viewModel.apiHostUrl, canLoadMore = canLoadMore, refreshing = refreshing, + querySearch = querySearch, onBackClick = { requireActivity().supportFragmentManager.popBackStack() }, @@ -128,10 +132,23 @@ class CourseSearchFragment : Fragment() { ) } ) + LaunchedEffect(key1 = uiState) { + viewModel.search(querySearch) + } } } } + companion object { + private const val ARG_SEARCH_QUERY = "query_search" + fun newInstance(querySearch: String): CourseSearchFragment { + val fragment = CourseSearchFragment() + fragment.arguments = bundleOf( + ARG_SEARCH_QUERY to querySearch + ) + return fragment + } + } } @@ -144,6 +161,7 @@ private fun CourseSearchScreen( apiHostUrl: String, canLoadMore: Boolean, refreshing: Boolean, + querySearch: String, onBackClick: () -> Unit, onSearchTextChanged: (String) -> Unit, onSwipeRefresh: () -> Unit, @@ -159,7 +177,12 @@ private fun CourseSearchScreen( rememberPullRefreshState(refreshing = refreshing, onRefresh = { onSwipeRefresh() }) var textFieldValue by rememberSaveable(stateSaver = TextFieldValue.Saver) { - mutableStateOf(TextFieldValue("")) + mutableStateOf( + TextFieldValue( + text = querySearch, + selection = TextRange(querySearch.length) + ) + ) } val keyboardController = LocalSoftwareKeyboardController.current val focusManager = LocalFocusManager.current @@ -373,6 +396,7 @@ fun CourseSearchScreenPreview() { apiHostUrl = "", canLoadMore = false, refreshing = false, + querySearch = "", onBackClick = {}, onSearchTextChanged = {}, onSwipeRefresh = {}, @@ -394,6 +418,7 @@ fun CourseSearchScreenTabletPreview() { apiHostUrl = "", canLoadMore = false, refreshing = false, + querySearch = "", onBackClick = {}, onSearchTextChanged = {}, onSwipeRefresh = {}, From 8d47e4d45db642379d516016ed7dc982742a03a9 Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Tue, 14 Nov 2023 18:48:01 +0500 Subject: [PATCH 02/10] fix: Address PR comments --- .../presentation/preAuth/PreAuthFragment.kt | 21 +++++++++++-------- auth/src/main/res/values/strings.xml | 2 +- .../search/CourseSearchFragment.kt | 7 ++++--- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt b/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt index e07f84139..7ba0f442f 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.MaterialTheme @@ -33,6 +34,7 @@ import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.fragment.app.Fragment @@ -61,7 +63,7 @@ class PreAuthFragment : Fragment() { setContent { OpenEdXTheme { PreLoginScreen( - onLoginClick = { + onSignInClick = { router.navigateToSignIn(parentFragmentManager) }, onRegisterClick = { @@ -80,7 +82,7 @@ class PreAuthFragment : Fragment() { private fun PreLoginScreen( onSearchClick: (query: String) -> Unit, onRegisterClick: () -> Unit, - onLoginClick: () -> Unit, + onSignInClick: () -> Unit, ) { var textFieldValue by rememberSaveable(stateSaver = TextFieldValue.Saver) { @@ -114,21 +116,20 @@ private fun PreLoginScreen( painter = painterResource(id = org.openedx.core.R.drawable.core_ic_logo), contentDescription = null, modifier = Modifier - .padding(top = 32.dp, bottom = 32.dp) - .width(170.dp) - .height(48.dp), + .padding(top = 64.dp, bottom = 20.dp) + .wrapContentWidth(), colorFilter = ColorFilter.tint(MaterialTheme.appColors.primary) ) Text( text = stringResource(id = R.string.pre_auth_title), color = MaterialTheme.appColors.textPrimary, style = MaterialTheme.appTypography.headlineSmall, - modifier = Modifier.padding(bottom = 32.dp) + modifier = Modifier.padding(bottom = 40.dp) ) val focusManager = LocalFocusManager.current Column(Modifier.padding(bottom = 8.dp)) { Text( - modifier = Modifier.padding(bottom = 8.dp), + modifier = Modifier.padding(bottom = 10.dp), style = MaterialTheme.appTypography.titleMedium, text = stringResource(id = R.string.pre_auth_search_title), ) @@ -179,7 +180,7 @@ private fun PreLoginScreen( .width(100.dp) .padding(start = 16.dp), text = stringResource(id = R.string.auth_sign_in), - onClick = { onLoginClick() }, + onClick = { onSignInClick() }, borderColor = MaterialTheme.appColors.textFieldBorder, textColor = MaterialTheme.appColors.primary ) @@ -191,12 +192,14 @@ private fun PreLoginScreen( @Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) +@Preview(name = "NEXUS_9_Light", device = Devices.NEXUS_9, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "NEXUS_9_Night", device = Devices.NEXUS_9, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable private fun SignInScreenPreview() { OpenEdXTheme { PreLoginScreen( onSearchClick = {}, - onLoginClick = {}, + onSignInClick = {}, onRegisterClick = {} ) } diff --git a/auth/src/main/res/values/strings.xml b/auth/src/main/res/values/strings.xml index 25bf31694..ef197a17e 100644 --- a/auth/src/main/res/values/strings.xml +++ b/auth/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ - Courses and Programs from the world\'s best universities in your pocket. + Courses and programs from the world\'s best universities in your pocket. What do you want to learn? Search our 3000+ courses Explore all courses diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt index 0535a061d..530013b16 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt @@ -132,9 +132,6 @@ class CourseSearchFragment : Fragment() { ) } ) - LaunchedEffect(key1 = uiState) { - viewModel.search(querySearch) - } } } } @@ -382,6 +379,10 @@ private fun CourseSearchScreen( } } } + var isPageLoaded = rememberSaveable { true } + LaunchedEffect(key1 = isPageLoaded) { + onSearchTextChanged(querySearch) + } } @Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) From f7917a73120a6e41ba3767476ae3cf5742668537 Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Thu, 16 Nov 2023 00:42:37 +0500 Subject: [PATCH 03/10] fix: Address PR comments - 2 --- .../main/java/org/openedx/app/AppActivity.kt | 3 ++- .../main/java/org/openedx/app/AppRouter.kt | 4 +-- .../Logistration.kt} | 13 +++++---- .../presentation/DiscoveryScreenTest.kt | 27 ++++++++++++++----- .../presentation/DiscoveryFragment.kt | 13 ++++++--- .../search/CourseSearchFragment.kt | 3 +-- 6 files changed, 42 insertions(+), 21 deletions(-) rename auth/src/main/java/org/openedx/auth/presentation/{preAuth/PreAuthFragment.kt => logistration/Logistration.kt} (96%) diff --git a/app/src/main/java/org/openedx/app/AppActivity.kt b/app/src/main/java/org/openedx/app/AppActivity.kt index 90b057441..0e9011fa2 100644 --- a/app/src/main/java/org/openedx/app/AppActivity.kt +++ b/app/src/main/java/org/openedx/app/AppActivity.kt @@ -15,6 +15,7 @@ import androidx.window.layout.WindowMetricsCalculator import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel import org.openedx.app.databinding.ActivityAppBinding +import org.openedx.auth.presentation.logistration.Logistration import org.openedx.auth.presentation.signin.SignInFragment import org.openedx.core.data.storage.CorePreferences import org.openedx.core.extension.requestApplyInsetsWhenAttached @@ -113,7 +114,7 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder { when { corePreferencesManager.user == null -> { if (coreBuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { - addFragment(PreAuthFragment()) + addFragment(Logistration()) } else { addFragment(SignInFragment()) } diff --git a/app/src/main/java/org/openedx/app/AppRouter.kt b/app/src/main/java/org/openedx/app/AppRouter.kt index d015c2f35..b75a632a0 100644 --- a/app/src/main/java/org/openedx/app/AppRouter.kt +++ b/app/src/main/java/org/openedx/app/AppRouter.kt @@ -4,7 +4,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentTransaction import org.openedx.auth.presentation.AuthRouter -import org.openedx.auth.presentation.preAuth.PreAuthFragment +import org.openedx.auth.presentation.logistration.Logistration import org.openedx.auth.presentation.restore.RestorePasswordFragment import org.openedx.auth.presentation.signin.SignInFragment import org.openedx.auth.presentation.signup.SignUpFragment @@ -297,7 +297,7 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di } popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { - replaceFragment(fm, PreAuthFragment()) + replaceFragment(fm, Logistration()) } else { replaceFragment(fm, SignInFragment()) } diff --git a/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt b/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt similarity index 96% rename from auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt rename to auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt index 7ba0f442f..090a8bbae 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/preAuth/PreAuthFragment.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt @@ -1,4 +1,4 @@ -package org.openedx.auth.presentation.preAuth +package org.openedx.auth.presentation.logistration import android.content.res.Configuration import android.os.Bundle @@ -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.R as coreR import org.openedx.core.ui.OpenEdXButton import org.openedx.core.ui.OpenEdXOutlinedButton import org.openedx.core.ui.SearchBar @@ -50,7 +51,7 @@ import org.openedx.core.ui.theme.OpenEdXTheme import org.openedx.core.ui.theme.appColors import org.openedx.core.ui.theme.appTypography -class PreAuthFragment : Fragment() { +class Logistration : Fragment() { private val router: AuthRouter by inject() @@ -106,14 +107,12 @@ private fun PreLoginScreen( ) { Column( modifier = Modifier.padding( - start = 16.dp, - end = 16.dp, - top = 32.dp, - bottom = 32.dp + horizontal = 16.dp, + vertical = 32.dp, ) ) { Image( - painter = painterResource(id = org.openedx.core.R.drawable.core_ic_logo), + painter = painterResource(id = coreR.drawable.core_ic_logo), contentDescription = null, modifier = Modifier .padding(top = 64.dp, bottom = 20.dp) diff --git a/discovery/src/androidTest/java/org/openedx/discovery/presentation/DiscoveryScreenTest.kt b/discovery/src/androidTest/java/org/openedx/discovery/presentation/DiscoveryScreenTest.kt index 3975cb6c7..b30dbff5c 100644 --- a/discovery/src/androidTest/java/org/openedx/discovery/presentation/DiscoveryScreenTest.kt +++ b/discovery/src/androidTest/java/org/openedx/discovery/presentation/DiscoveryScreenTest.kt @@ -2,14 +2,20 @@ package org.openedx.discovery.presentation import androidx.activity.ComponentActivity import androidx.compose.ui.semantics.ProgressBarRangeInfo -import androidx.compose.ui.test.* +import androidx.compose.ui.test.assertAny +import androidx.compose.ui.test.hasAnyChild +import androidx.compose.ui.test.hasProgressBarRangeInfo +import androidx.compose.ui.test.hasScrollAction +import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onChildren +import org.junit.Rule +import org.junit.Test +import org.openedx.core.AppUpdateState import org.openedx.core.domain.model.Course import org.openedx.core.domain.model.Media import org.openedx.core.ui.WindowSize import org.openedx.core.ui.WindowType -import org.junit.Rule -import org.junit.Test import java.util.Date class DiscoveryScreenTest { @@ -53,11 +59,14 @@ class DiscoveryScreenTest { canLoadMore = false, refreshing = false, hasInternetConnection = true, + isUserLoggedIn = false, + appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onSearchClick = {}, onSwipeRefresh = {}, paginationCallback = {}, onItemClick = {}, - onReloadClick = {} + onReloadClick = {}, + onBackClick = {}, ) } @@ -85,11 +94,14 @@ class DiscoveryScreenTest { canLoadMore = false, refreshing = false, hasInternetConnection = true, + isUserLoggedIn = false, + appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onSearchClick = {}, onSwipeRefresh = {}, paginationCallback = {}, onItemClick = {}, - onReloadClick = {} + onReloadClick = {}, + onBackClick = {}, ) } @@ -108,11 +120,14 @@ class DiscoveryScreenTest { canLoadMore = true, refreshing = false, hasInternetConnection = true, + isUserLoggedIn = false, + appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onSearchClick = {}, onSwipeRefresh = {}, paginationCallback = {}, onItemClick = {}, - onReloadClick = {} + onReloadClick = {}, + onBackClick = {}, ) } diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt index 03a84cbe6..6b2adc9fb 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt @@ -31,6 +31,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel import org.openedx.core.AppUpdateState import org.openedx.core.AppUpdateState.wasUpdateDialogClosed import org.openedx.core.UIMessage +import org.openedx.core.data.storage.CorePreferences import org.openedx.core.domain.model.Course import org.openedx.core.domain.model.Media import org.openedx.core.presentation.dialog.appupgrade.AppUpgradeDialogFragment @@ -46,6 +47,7 @@ class DiscoveryFragment : Fragment() { private val viewModel by viewModel() private val router: DiscoveryRouter by inject() + private val corePreferencesManager by inject() override fun onCreateView( inflater: LayoutInflater, @@ -64,6 +66,7 @@ class DiscoveryFragment : Fragment() { val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState() val wasUpdateDialogClosed by remember { wasUpdateDialogClosed } val querySearch = arguments?.getString(ARG_SEARCH_QUERY, "") ?: "" + val isUserLoggedIn = corePreferencesManager.user != null DiscoveryScreen( windowSize = windowSize, @@ -73,6 +76,7 @@ class DiscoveryFragment : Fragment() { canLoadMore = canLoadMore, refreshing = refreshing, hasInternetConnection = viewModel.hasInternetConnection, + isUserLoggedIn = isUserLoggedIn, appUpgradeParameters = AppUpdateState.AppUpgradeParameters( appUpgradeEvent = appUpgradeEvent, wasUpdateDialogClosed = wasUpdateDialogClosed, @@ -117,7 +121,7 @@ class DiscoveryFragment : Fragment() { onBackClick = { requireActivity().supportFragmentManager.popBackStackImmediate() }) - LaunchedEffect(key1 = uiState) { + LaunchedEffect(uiState) { if (querySearch.isNotEmpty()) { router.navigateToCourseSearch( requireActivity().supportFragmentManager, querySearch @@ -154,6 +158,7 @@ internal fun DiscoveryScreen( canLoadMore: Boolean, refreshing: Boolean, hasInternetConnection: Boolean, + isUserLoggedIn: Boolean, appUpgradeParameters: AppUpdateState.AppUpgradeParameters, onSearchClick: () -> Unit, onSwipeRefresh: () -> Unit, @@ -212,7 +217,7 @@ internal fun DiscoveryScreen( HandleUIMessage(uiMessage = uiMessage, scaffoldState = scaffoldState) - if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { + if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED && isUserLoggedIn.not()) { Box( modifier = Modifier .statusBarsPadding() @@ -435,6 +440,7 @@ private fun DiscoveryScreenPreview() { hasInternetConnection = true, appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onBackClick = {}, + isUserLoggedIn = false ) } } @@ -471,6 +477,7 @@ private fun DiscoveryScreenTabletPreview() { hasInternetConnection = true, appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onBackClick = {}, + isUserLoggedIn = false ) } } @@ -497,4 +504,4 @@ private val mockCourse = Course( startType = "startType", overview = "", isEnrolled = false -) \ No newline at end of file +) diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt index 530013b16..13e4996de 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/search/CourseSearchFragment.kt @@ -379,8 +379,7 @@ private fun CourseSearchScreen( } } } - var isPageLoaded = rememberSaveable { true } - LaunchedEffect(key1 = isPageLoaded) { + LaunchedEffect(rememberSaveable { true }) { onSearchTextChanged(querySearch) } } From 7f852f2bc094d84b2c63b8c8c012a4165fd3210d Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Sat, 25 Nov 2023 01:11:38 +0500 Subject: [PATCH 04/10] fix: Address PR comments --- app/src/main/java/org/openedx/app/AppActivity.kt | 1 + .../auth/presentation/logistration/Logistration.kt | 6 ++++-- .../auth/presentation/signin/SignInFragment.kt | 11 +++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/openedx/app/AppActivity.kt b/app/src/main/java/org/openedx/app/AppActivity.kt index 0e9011fa2..b7f793afb 100644 --- a/app/src/main/java/org/openedx/app/AppActivity.kt +++ b/app/src/main/java/org/openedx/app/AppActivity.kt @@ -23,6 +23,7 @@ import org.openedx.core.presentation.global.InsetHolder import org.openedx.core.presentation.global.WindowSizeHolder import org.openedx.core.ui.WindowSize import org.openedx.core.ui.WindowType +import org.openedx.core.BuildConfig as coreBuildConfig import org.openedx.profile.presentation.ProfileRouter import org.openedx.whatsnew.WhatsNewManager import org.openedx.whatsnew.presentation.whatsnew.WhatsNewFragment diff --git a/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt b/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt index 090a8bbae..f25d0330c 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentWidth @@ -81,7 +82,7 @@ class Logistration : Fragment() { @Composable private fun PreLoginScreen( - onSearchClick: (query: String) -> Unit, + onSearchClick: (String) -> Unit, onRegisterClick: () -> Unit, onSignInClick: () -> Unit, ) { @@ -94,7 +95,8 @@ private fun PreLoginScreen( Scaffold( scaffoldState = scaffoldState, modifier = Modifier - .fillMaxSize(), + .fillMaxSize() + .navigationBarsPadding(), backgroundColor = MaterialTheme.appColors.background ) { Surface( diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt index 435e87483..01c095785 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt @@ -103,11 +103,13 @@ class SignInFragment : Fragment() { val uiMessage by viewModel.uiMessage.observeAsState() val loginSuccess by viewModel.loginSuccess.observeAsState(initial = false) val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState(null) + val isLogistrationEnabled = BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED if (appUpgradeEvent == null) { LoginScreen( windowSize = windowSize, showProgress = showProgress, + isLogistrationEnabled = isLogistrationEnabled, uiMessage = uiMessage, onLoginClick = { login, password -> viewModel.login(login, password) @@ -152,6 +154,7 @@ class SignInFragment : Fragment() { private fun LoginScreen( windowSize: WindowSize, showProgress: Boolean, + isLogistrationEnabled: Boolean, uiMessage: UIMessage?, onLoginClick: (login: String, password: String) -> Unit, onRegisterClick: () -> Unit, @@ -205,7 +208,7 @@ private fun LoginScreen( uiMessage = uiMessage, scaffoldState = scaffoldState ) - if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { + if (isLogistrationEnabled) { Box( modifier = Modifier .statusBarsPadding() @@ -268,6 +271,7 @@ private fun LoginScreen( AuthForm( buttonWidth, showProgress, + isLogistrationEnabled, onLoginClick, onRegisterClick, onForgotPasswordClick @@ -283,6 +287,7 @@ private fun LoginScreen( private fun AuthForm( buttonWidth: Modifier, isLoading: Boolean = false, + isLogistrationEnabled: Boolean, onLoginClick: (login: String, password: String) -> Unit, onRegisterClick: () -> Unit, onForgotPasswordClick: () -> Unit @@ -315,7 +320,7 @@ private fun AuthForm( .fillMaxWidth() .padding(top = 20.dp, bottom = 36.dp) ) { - if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED.not()) { + if (isLogistrationEnabled.not()) { Text( modifier = Modifier.noRippleClickable { onRegisterClick() @@ -413,6 +418,7 @@ private fun SignInScreenPreview() { LoginScreen( windowSize = WindowSize(WindowType.Compact, WindowType.Compact), showProgress = false, + isLogistrationEnabled = false, uiMessage = null, onLoginClick = { _, _ -> @@ -433,6 +439,7 @@ private fun SignInScreenTabletPreview() { LoginScreen( windowSize = WindowSize(WindowType.Expanded, WindowType.Expanded), showProgress = false, + isLogistrationEnabled = false, uiMessage = null, onLoginClick = { _, _ -> From ebff6d7b54680d29f2f5b86de7664e26dccbb5d7 Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Sat, 25 Nov 2023 01:29:42 +0500 Subject: [PATCH 05/10] fix: resolve test cases --- app/src/main/java/org/openedx/app/AppActivity.kt | 1 - .../java/org/openedx/auth/presentation/signin/SignInFragment.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/app/src/main/java/org/openedx/app/AppActivity.kt b/app/src/main/java/org/openedx/app/AppActivity.kt index b7f793afb..0e9011fa2 100644 --- a/app/src/main/java/org/openedx/app/AppActivity.kt +++ b/app/src/main/java/org/openedx/app/AppActivity.kt @@ -23,7 +23,6 @@ import org.openedx.core.presentation.global.InsetHolder import org.openedx.core.presentation.global.WindowSizeHolder import org.openedx.core.ui.WindowSize import org.openedx.core.ui.WindowType -import org.openedx.core.BuildConfig as coreBuildConfig import org.openedx.profile.presentation.ProfileRouter import org.openedx.whatsnew.WhatsNewManager import org.openedx.whatsnew.presentation.whatsnew.WhatsNewFragment diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt index 01c095785..6cb8443aa 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt @@ -66,7 +66,6 @@ import org.openedx.auth.presentation.ui.LoginTextField import org.openedx.core.AppUpdateState import org.openedx.core.BuildConfig import org.openedx.core.UIMessage -import org.openedx.core.presentation.global.AppDataHolder import org.openedx.core.presentation.global.app_upgrade.AppUpgradeRequiredScreen import org.openedx.core.ui.BackBtn import org.openedx.core.ui.HandleUIMessage From eaf71dc39b7f383c4969e0648a92c8eced27a6e5 Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Thu, 30 Nov 2023 18:17:35 +0500 Subject: [PATCH 06/10] fix: Address PR comments + crash fix --- .../auth/presentation/logistration/Logistration.kt | 8 ++++---- .../auth/presentation/signin/SignInFragment.kt | 5 ++--- .../auth/presentation/signin/SignInViewModel.kt | 5 +++++ .../discovery/presentation/DiscoveryScreenTest.kt | 6 +++--- .../discovery/presentation/DiscoveryFragment.kt | 13 +++++++------ .../discovery/presentation/DiscoveryViewModel.kt | 5 +++++ 6 files changed, 26 insertions(+), 16 deletions(-) diff --git a/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt b/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt index f25d0330c..6591adc9d 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt @@ -64,7 +64,7 @@ class Logistration : Fragment() { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { OpenEdXTheme { - PreLoginScreen( + LogistrationScreen( onSignInClick = { router.navigateToSignIn(parentFragmentManager) }, @@ -81,7 +81,7 @@ class Logistration : Fragment() { } @Composable -private fun PreLoginScreen( +private fun LogistrationScreen( onSearchClick: (String) -> Unit, onRegisterClick: () -> Unit, onSignInClick: () -> Unit, @@ -196,9 +196,9 @@ private fun PreLoginScreen( @Preview(name = "NEXUS_9_Light", device = Devices.NEXUS_9, uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(name = "NEXUS_9_Night", device = Devices.NEXUS_9, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun SignInScreenPreview() { +private fun LogistrationPreview() { OpenEdXTheme { - PreLoginScreen( + LogistrationScreen( onSearchClick = {}, onSignInClick = {}, onRegisterClick = {} diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt index 6cb8443aa..0db83051f 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt @@ -64,8 +64,8 @@ import org.openedx.auth.R import org.openedx.auth.presentation.AuthRouter import org.openedx.auth.presentation.ui.LoginTextField import org.openedx.core.AppUpdateState -import org.openedx.core.BuildConfig import org.openedx.core.UIMessage +import org.openedx.core.presentation.global.WhatsNewGlobalManager import org.openedx.core.presentation.global.app_upgrade.AppUpgradeRequiredScreen import org.openedx.core.ui.BackBtn import org.openedx.core.ui.HandleUIMessage @@ -80,7 +80,6 @@ import org.openedx.core.ui.theme.appColors import org.openedx.core.ui.theme.appShapes import org.openedx.core.ui.theme.appTypography import org.openedx.core.ui.windowSizeValue -import org.openedx.core.presentation.global.WhatsNewGlobalManager class SignInFragment : Fragment() { @@ -102,7 +101,7 @@ class SignInFragment : Fragment() { val uiMessage by viewModel.uiMessage.observeAsState() val loginSuccess by viewModel.loginSuccess.observeAsState(initial = false) val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState(null) - val isLogistrationEnabled = BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED + val isLogistrationEnabled by viewModel.isLogistrationEnabled.observeAsState(initial = false) if (appUpgradeEvent == null) { LoginScreen( diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt index c1a4d1126..02c79efb5 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt @@ -8,6 +8,7 @@ import org.openedx.auth.R import org.openedx.auth.domain.interactor.AuthInteractor import org.openedx.auth.presentation.AuthAnalytics import org.openedx.core.BaseViewModel +import org.openedx.core.BuildConfig import org.openedx.core.SingleEventLiveData import org.openedx.core.UIMessage import org.openedx.core.Validator @@ -44,7 +45,11 @@ class SignInViewModel( val appUpgradeEvent: LiveData get() = _appUpgradeEvent + private val _isLogistrationEnabled = MutableLiveData() + val isLogistrationEnabled: LiveData = _isLogistrationEnabled + init { + _isLogistrationEnabled.value = BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED collectAppUpgradeEvent() } diff --git a/discovery/src/androidTest/java/org/openedx/discovery/presentation/DiscoveryScreenTest.kt b/discovery/src/androidTest/java/org/openedx/discovery/presentation/DiscoveryScreenTest.kt index b30dbff5c..6a70f334b 100644 --- a/discovery/src/androidTest/java/org/openedx/discovery/presentation/DiscoveryScreenTest.kt +++ b/discovery/src/androidTest/java/org/openedx/discovery/presentation/DiscoveryScreenTest.kt @@ -59,7 +59,7 @@ class DiscoveryScreenTest { canLoadMore = false, refreshing = false, hasInternetConnection = true, - isUserLoggedIn = false, + canShowBackButton = false, appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onSearchClick = {}, onSwipeRefresh = {}, @@ -94,7 +94,7 @@ class DiscoveryScreenTest { canLoadMore = false, refreshing = false, hasInternetConnection = true, - isUserLoggedIn = false, + canShowBackButton = false, appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onSearchClick = {}, onSwipeRefresh = {}, @@ -120,7 +120,7 @@ class DiscoveryScreenTest { canLoadMore = true, refreshing = false, hasInternetConnection = true, - isUserLoggedIn = false, + canShowBackButton = false, appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onSearchClick = {}, onSwipeRefresh = {}, diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt index 6b2adc9fb..a63e40e03 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt @@ -66,7 +66,8 @@ class DiscoveryFragment : Fragment() { val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState() val wasUpdateDialogClosed by remember { wasUpdateDialogClosed } val querySearch = arguments?.getString(ARG_SEARCH_QUERY, "") ?: "" - val isUserLoggedIn = corePreferencesManager.user != null + val isLogistrationEnabled by viewModel.isLogistrationEnabled.observeAsState(false) + val canShowBackButton = isLogistrationEnabled && corePreferencesManager.user == null DiscoveryScreen( windowSize = windowSize, @@ -76,7 +77,7 @@ class DiscoveryFragment : Fragment() { canLoadMore = canLoadMore, refreshing = refreshing, hasInternetConnection = viewModel.hasInternetConnection, - isUserLoggedIn = isUserLoggedIn, + canShowBackButton = canShowBackButton, appUpgradeParameters = AppUpdateState.AppUpgradeParameters( appUpgradeEvent = appUpgradeEvent, wasUpdateDialogClosed = wasUpdateDialogClosed, @@ -158,7 +159,7 @@ internal fun DiscoveryScreen( canLoadMore: Boolean, refreshing: Boolean, hasInternetConnection: Boolean, - isUserLoggedIn: Boolean, + canShowBackButton: Boolean, appUpgradeParameters: AppUpdateState.AppUpgradeParameters, onSearchClick: () -> Unit, onSwipeRefresh: () -> Unit, @@ -217,7 +218,7 @@ internal fun DiscoveryScreen( HandleUIMessage(uiMessage = uiMessage, scaffoldState = scaffoldState) - if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED && isUserLoggedIn.not()) { + if (canShowBackButton) { Box( modifier = Modifier .statusBarsPadding() @@ -440,7 +441,7 @@ private fun DiscoveryScreenPreview() { hasInternetConnection = true, appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onBackClick = {}, - isUserLoggedIn = false + canShowBackButton = false ) } } @@ -477,7 +478,7 @@ private fun DiscoveryScreenTabletPreview() { hasInternetConnection = true, appUpgradeParameters = AppUpdateState.AppUpgradeParameters(), onBackClick = {}, - isUserLoggedIn = false + canShowBackButton = false ) } } diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt index e53a230a1..862e93899 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.launch import org.openedx.core.BaseViewModel +import org.openedx.core.BuildConfig import org.openedx.core.R import org.openedx.core.SingleEventLiveData import org.openedx.core.UIMessage @@ -50,6 +51,9 @@ class DiscoveryViewModel( val appUpgradeEvent: LiveData get() = _appUpgradeEvent + private val _isLogistrationEnabled = MutableLiveData() + val isLogistrationEnabled: LiveData = _isLogistrationEnabled + val hasInternetConnection: Boolean get() = networkConnection.isOnline() @@ -58,6 +62,7 @@ class DiscoveryViewModel( private var isLoading = false init { + _isLogistrationEnabled.value = BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED getCoursesList() collectAppUpgradeEvent() } From d1d52ca92963a7d7248a6d68440a7ab05e383c87 Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Thu, 30 Nov 2023 18:23:26 +0500 Subject: [PATCH 07/10] fix: App crash on Discovery Fragment --- .../org/openedx/discovery/presentation/DiscoveryFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt index a63e40e03..87f307041 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt @@ -115,7 +115,7 @@ class DiscoveryFragment : Fragment() { onItemClick = { course -> viewModel.discoveryCourseClicked(course.id, course.name) router.navigateToCourseDetail( - requireParentFragment().parentFragmentManager, + requireActivity().supportFragmentManager, course.id ) }, From 50f3a35c80cfa6f28bf7dabcce893c99ad55554c Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Fri, 1 Dec 2023 23:35:52 +0500 Subject: [PATCH 08/10] fix: small code improvement --- .../presentation/DiscoveryFragment.kt | 5 +---- .../presentation/DiscoveryViewModel.kt | 11 ++++++---- .../presentation/DiscoveryViewModelTest.kt | 21 +++++++++++-------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt index 87f307041..605b260ed 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt @@ -31,7 +31,6 @@ import org.koin.androidx.viewmodel.ext.android.viewModel import org.openedx.core.AppUpdateState import org.openedx.core.AppUpdateState.wasUpdateDialogClosed import org.openedx.core.UIMessage -import org.openedx.core.data.storage.CorePreferences import org.openedx.core.domain.model.Course import org.openedx.core.domain.model.Media import org.openedx.core.presentation.dialog.appupgrade.AppUpgradeDialogFragment @@ -47,7 +46,6 @@ class DiscoveryFragment : Fragment() { private val viewModel by viewModel() private val router: DiscoveryRouter by inject() - private val corePreferencesManager by inject() override fun onCreateView( inflater: LayoutInflater, @@ -66,8 +64,7 @@ class DiscoveryFragment : Fragment() { val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState() val wasUpdateDialogClosed by remember { wasUpdateDialogClosed } val querySearch = arguments?.getString(ARG_SEARCH_QUERY, "") ?: "" - val isLogistrationEnabled by viewModel.isLogistrationEnabled.observeAsState(false) - val canShowBackButton = isLogistrationEnabled && corePreferencesManager.user == null + val canShowBackButton by viewModel.canShowBackButton.observeAsState(false) DiscoveryScreen( windowSize = windowSize, diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt index 862e93899..fad5a016f 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt @@ -11,6 +11,7 @@ import org.openedx.core.BuildConfig import org.openedx.core.R import org.openedx.core.SingleEventLiveData import org.openedx.core.UIMessage +import org.openedx.core.data.storage.CorePreferences import org.openedx.core.config.Config import org.openedx.core.domain.model.Course import org.openedx.core.extension.isInternetError @@ -26,7 +27,8 @@ class DiscoveryViewModel( private val interactor: DiscoveryInteractor, private val resourceManager: ResourceManager, private val analytics: DiscoveryAnalytics, - private val appUpgradeNotifier: AppUpgradeNotifier + private val appUpgradeNotifier: AppUpgradeNotifier, + private val corePreferences: CorePreferences ) : BaseViewModel() { val apiHostUrl get() = config.getApiHostURL() @@ -51,8 +53,8 @@ class DiscoveryViewModel( val appUpgradeEvent: LiveData get() = _appUpgradeEvent - private val _isLogistrationEnabled = MutableLiveData() - val isLogistrationEnabled: LiveData = _isLogistrationEnabled + private val _canShowBackButton = MutableLiveData() + val canShowBackButton: LiveData = _canShowBackButton val hasInternetConnection: Boolean get() = networkConnection.isOnline() @@ -62,7 +64,8 @@ class DiscoveryViewModel( private var isLoading = false init { - _isLogistrationEnabled.value = BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED + _canShowBackButton.value = + BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED && corePreferences.user == null getCoursesList() collectAppUpgradeEvent() } diff --git a/discovery/src/test/java/org/openedx/discovery/presentation/DiscoveryViewModelTest.kt b/discovery/src/test/java/org/openedx/discovery/presentation/DiscoveryViewModelTest.kt index 4c0fc45bb..d16f6e59c 100644 --- a/discovery/src/test/java/org/openedx/discovery/presentation/DiscoveryViewModelTest.kt +++ b/discovery/src/test/java/org/openedx/discovery/presentation/DiscoveryViewModelTest.kt @@ -16,6 +16,7 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule +import org.openedx.core.data.storage.CorePreferences import org.openedx.core.R import org.openedx.core.UIMessage import org.openedx.core.config.Config @@ -42,6 +43,7 @@ class DiscoveryViewModelTest { private val networkConnection = mockk() private val analytics = mockk() private val appUpgradeNotifier = mockk() + private val corePreferences = mockk() private val noInternet = "Slow or no internet connection" private val somethingWrong = "Something went wrong" @@ -52,6 +54,7 @@ class DiscoveryViewModelTest { every { resourceManager.getString(R.string.core_error_no_connection) } returns noInternet every { resourceManager.getString(R.string.core_error_unknown_error) } returns somethingWrong every { appUpgradeNotifier.notifier } returns emptyFlow() + every { corePreferences.user } returns null every { config.getApiHostURL() } returns "http://localhost:8000" } @@ -62,7 +65,7 @@ class DiscoveryViewModelTest { @Test fun `getCoursesList no internet connection`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns true coEvery { interactor.getCoursesList(any(), any(), any()) } throws UnknownHostException() advanceUntilIdle() @@ -79,7 +82,7 @@ class DiscoveryViewModelTest { @Test fun `getCoursesList unknown exception`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns true coEvery { interactor.getCoursesList(any(), any(), any()) } throws Exception() advanceUntilIdle() @@ -95,7 +98,7 @@ class DiscoveryViewModelTest { @Test fun `getCoursesList from cache`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns false coEvery { interactor.getCoursesListFromCache() } returns emptyList() advanceUntilIdle() @@ -110,7 +113,7 @@ class DiscoveryViewModelTest { @Test fun `getCoursesList from network with next page`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns true coEvery { interactor.getCoursesList(any(), any(), any()) } returns CourseList( Pagination( @@ -132,7 +135,7 @@ class DiscoveryViewModelTest { @Test fun `getCoursesList from network without next page`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns true coEvery { interactor.getCoursesList(any(), any(), any()) } returns CourseList( Pagination( @@ -155,7 +158,7 @@ class DiscoveryViewModelTest { @Test fun `updateData no internet connection`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns true coEvery { interactor.getCoursesList(any(), any(), any()) } throws UnknownHostException() viewModel.updateData() @@ -172,7 +175,7 @@ class DiscoveryViewModelTest { @Test fun `updateData unknown exception`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns true coEvery { interactor.getCoursesList(any(), any(), any()) } throws Exception() viewModel.updateData() @@ -189,7 +192,7 @@ class DiscoveryViewModelTest { @Test fun `updateData success with next page`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns true coEvery { interactor.getCoursesList(any(), any(), any()) } returns CourseList( Pagination( @@ -212,7 +215,7 @@ class DiscoveryViewModelTest { @Test fun `updateData success without next page`() = runTest { - val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier) + val viewModel = DiscoveryViewModel(config, networkConnection, interactor, resourceManager, analytics, appUpgradeNotifier, corePreferences) every { networkConnection.isOnline() } returns true coEvery { interactor.getCoursesList(any(), any(), any()) } returns CourseList( Pagination( From 84752408a3a4b0cb5eb6c4b4c9a92033a773a9cd Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Mon, 4 Dec 2023 16:21:37 +0500 Subject: [PATCH 09/10] fix: Resolve conflicts + Update code according to new config architecture --- .../main/java/org/openedx/app/AppActivity.kt | 9 +- .../main/java/org/openedx/app/AppRouter.kt | 9 +- .../main/java/org/openedx/app/AppViewModel.kt | 4 + .../java/org/openedx/app/di/ScreenModule.kt | 150 ++++++++++++++++-- .../test/java/org/openedx/AppViewModelTest.kt | 44 ++--- ...ogistration.kt => LogistrationFragment.kt} | 2 +- .../presentation/signin/SignInViewModel.kt | 5 +- .../signin/SignInViewModelTest.kt | 99 ++++++++++-- .../java/org/openedx/core/config/Config.kt | 6 +- .../presentation/DiscoveryFragment.kt | 3 +- .../presentation/DiscoveryViewModel.kt | 9 +- .../presentation/DiscoveryViewModelTest.kt | 1 + .../profile/presentation/ProfileRouter.kt | 5 +- .../delete/DeleteProfileFragment.kt | 40 ++++- .../presentation/profile/ProfileFragment.kt | 2 +- .../presentation/profile/ProfileViewModel.kt | 4 + .../profile/ProfileViewModelTest.kt | 32 ++-- 17 files changed, 327 insertions(+), 97 deletions(-) rename auth/src/main/java/org/openedx/auth/presentation/logistration/{Logistration.kt => LogistrationFragment.kt} (99%) diff --git a/app/src/main/java/org/openedx/app/AppActivity.kt b/app/src/main/java/org/openedx/app/AppActivity.kt index 0e9011fa2..3f3e1e738 100644 --- a/app/src/main/java/org/openedx/app/AppActivity.kt +++ b/app/src/main/java/org/openedx/app/AppActivity.kt @@ -15,7 +15,7 @@ import androidx.window.layout.WindowMetricsCalculator import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel import org.openedx.app.databinding.ActivityAppBinding -import org.openedx.auth.presentation.logistration.Logistration +import org.openedx.auth.presentation.logistration.LogistrationFragment import org.openedx.auth.presentation.signin.SignInFragment import org.openedx.core.data.storage.CorePreferences import org.openedx.core.extension.requestApplyInsetsWhenAttached @@ -26,7 +26,6 @@ import org.openedx.core.ui.WindowType import org.openedx.profile.presentation.ProfileRouter import org.openedx.whatsnew.WhatsNewManager import org.openedx.whatsnew.presentation.whatsnew.WhatsNewFragment -import org.openedx.core.BuildConfig as coreBuildConfig class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder { @@ -113,8 +112,8 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder { if (savedInstanceState == null) { when { corePreferencesManager.user == null -> { - if (coreBuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { - addFragment(Logistration()) + if (viewModel.isLogistrationEnabled) { + addFragment(LogistrationFragment()) } else { addFragment(SignInFragment()) } @@ -131,7 +130,7 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder { } viewModel.logoutUser.observe(this) { - profileRouter.restartApp(supportFragmentManager) + profileRouter.restartApp(supportFragmentManager, viewModel.isLogistrationEnabled) } } diff --git a/app/src/main/java/org/openedx/app/AppRouter.kt b/app/src/main/java/org/openedx/app/AppRouter.kt index b75a632a0..49e766abb 100644 --- a/app/src/main/java/org/openedx/app/AppRouter.kt +++ b/app/src/main/java/org/openedx/app/AppRouter.kt @@ -4,11 +4,10 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentTransaction import org.openedx.auth.presentation.AuthRouter -import org.openedx.auth.presentation.logistration.Logistration +import org.openedx.auth.presentation.logistration.LogistrationFragment 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.BuildConfig import org.openedx.core.FragmentViewType import org.openedx.core.domain.model.CoursewareAccess import org.openedx.core.presentation.course.CourseViewMode @@ -290,14 +289,14 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di replaceFragmentWithBackStack(fm, DeleteProfileFragment()) } - override fun restartApp(fm: FragmentManager) { + override fun restartApp(fm: FragmentManager, isLogistrationEnabled: Boolean) { fm.apply { for (fragment in fragments) { beginTransaction().remove(fragment).commit() } popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) - if (BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED) { - replaceFragment(fm, Logistration()) + if (isLogistrationEnabled) { + replaceFragment(fm, LogistrationFragment()) } else { replaceFragment(fm, SignInFragment()) } diff --git a/app/src/main/java/org/openedx/app/AppViewModel.kt b/app/src/main/java/org/openedx/app/AppViewModel.kt index a5200d907..9092f603c 100644 --- a/app/src/main/java/org/openedx/app/AppViewModel.kt +++ b/app/src/main/java/org/openedx/app/AppViewModel.kt @@ -11,9 +11,11 @@ import org.openedx.app.system.notifier.AppNotifier import org.openedx.app.system.notifier.LogoutEvent import org.openedx.core.BaseViewModel import org.openedx.core.SingleEventLiveData +import org.openedx.core.config.Config import org.openedx.core.data.storage.CorePreferences class AppViewModel( + private val config: Config, private val notifier: AppNotifier, private val room: RoomDatabase, private val preferencesManager: CorePreferences, @@ -25,6 +27,8 @@ class AppViewModel( val logoutUser: LiveData get() = _logoutUser + val isLogistrationEnabled get() = config.isPreLoginExperienceEnabled() + private var logoutHandledAt: Long = 0 override fun onCreate(owner: LifecycleOwner) { diff --git a/app/src/main/java/org/openedx/app/di/ScreenModule.kt b/app/src/main/java/org/openedx/app/di/ScreenModule.kt index 4fa4e148a..87bab9b15 100644 --- a/app/src/main/java/org/openedx/app/di/ScreenModule.kt +++ b/app/src/main/java/org/openedx/app/di/ScreenModule.kt @@ -54,57 +54,173 @@ import org.openedx.whatsnew.presentation.whatsnew.WhatsNewViewModel val screenModule = module { - viewModel { AppViewModel(get(), get(), get(), get(named("IODispatcher")), get()) } + viewModel { AppViewModel(get(), get(), get(), get(), get(named("IODispatcher")), get()) } viewModel { MainViewModel() } factory { AuthRepository(get(), get(), get()) } factory { AuthInteractor(get()) } factory { Validator() } - viewModel { SignInViewModel(get(), get(), get(), get(), get(), get()) } + viewModel { SignInViewModel(get(), get(), get(), get(), get(), get(), get()) } viewModel { SignUpViewModel(get(), get(), get(), get(), get()) } viewModel { RestorePasswordViewModel(get(), get(), get(), get()) } - factory { DashboardRepository(get(), get(),get()) } + factory { DashboardRepository(get(), get(), get()) } factory { DashboardInteractor(get()) } viewModel { DashboardViewModel(get(), get(), get(), get(), get(), get(), get()) } factory { DiscoveryRepository(get(), get()) } factory { DiscoveryInteractor(get()) } - viewModel { DiscoveryViewModel(get(), get(), get(), get(), get(), get()) } + viewModel { DiscoveryViewModel(get(), get(), get(), get(), get(), get(), get()) } factory { ProfileRepository(get(), get(), get(), get(), get()) } factory { ProfileInteractor(get()) } - viewModel { ProfileViewModel(get(), get(), get(), get(named("IODispatcher")), get(), get(), get(), get()) } + viewModel { + ProfileViewModel( + get(), + get(), + get(), + get(), + get(named("IODispatcher")), + get(), + get(), + get(), + get() + ) + } viewModel { (account: Account) -> EditProfileViewModel(get(), get(), get(), get(), account) } viewModel { VideoSettingsViewModel(get(), get()) } viewModel { VideoQualityViewModel(get(), get()) } viewModel { DeleteProfileViewModel(get(), get(), get(), get()) } viewModel { (username: String) -> AnothersProfileViewModel(get(), get(), username) } - single { CourseRepository(get(), get(), get(),get()) } + single { CourseRepository(get(), get(), get(), get()) } factory { CourseInteractor(get()) } - viewModel { (courseId: String) -> CourseDetailsViewModel(courseId, get(), get(), get(), get(), get(), get()) } - viewModel { (courseId: String) -> CourseContainerViewModel(courseId, get(), get(), get(), get(), get()) } - viewModel { (courseId: String) -> CourseOutlineViewModel(courseId, get(), get(), get(), get(), get(), get(), get(), get(), get()) } - viewModel { (courseId: String) -> CourseSectionViewModel(get(), get(), get(), get(), get(), get(), get(), get(), courseId) } + viewModel { (courseId: String) -> + CourseDetailsViewModel( + courseId, + get(), + get(), + get(), + get(), + get(), + get() + ) + } + viewModel { (courseId: String) -> + CourseContainerViewModel( + courseId, + get(), + get(), + get(), + get(), + get() + ) + } + viewModel { (courseId: String) -> + CourseOutlineViewModel( + courseId, + get(), + get(), + get(), + get(), + get(), + get(), + get(), + get(), + get() + ) + } + viewModel { (courseId: String) -> + CourseSectionViewModel( + get(), + get(), + get(), + get(), + get(), + get(), + get(), + get(), + courseId + ) + } viewModel { (courseId: String) -> CourseUnitContainerViewModel(get(), get(), get(), courseId) } - viewModel { (courseId: String) -> CourseVideoViewModel(courseId, get(), get(), get(), get(), get(), get(), get(), get()) } + viewModel { (courseId: String) -> + CourseVideoViewModel( + courseId, + get(), + get(), + get(), + get(), + get(), + get(), + get(), + get() + ) + } viewModel { (courseId: String) -> VideoViewModel(courseId, get(), get(), get()) } viewModel { (courseId: String) -> VideoUnitViewModel(courseId, get(), get(), get(), get()) } - viewModel { (courseId: String, blockId: String) -> EncodedVideoUnitViewModel(courseId, blockId, get(), get(), get(), get(), get(), get()) } + viewModel { (courseId: String, blockId: String) -> + EncodedVideoUnitViewModel( + courseId, + blockId, + get(), + get(), + get(), + get(), + get(), + get() + ) + } viewModel { (courseId: String) -> CourseDatesViewModel(courseId, get(), get(), get()) } - viewModel { (courseId:String, handoutsType: String) -> HandoutsViewModel(courseId, get(), handoutsType, get()) } + viewModel { (courseId: String, handoutsType: String) -> + HandoutsViewModel( + courseId, + get(), + handoutsType, + get() + ) + } viewModel { CourseSearchViewModel(get(), get(), get(), get()) } viewModel { SelectDialogViewModel(get()) } single { DiscussionRepository(get(), get()) } factory { DiscussionInteractor(get()) } viewModel { (courseId: String) -> DiscussionTopicsViewModel(get(), get(), get(), courseId) } - viewModel { (courseId: String, topicId: String, threadType: String) -> DiscussionThreadsViewModel(get(), get(), get(), courseId, topicId, threadType) } - viewModel { (thread: org.openedx.discussion.domain.model.Thread) -> DiscussionCommentsViewModel(get(), get(), get(), thread) } - viewModel { (comment: DiscussionComment) -> DiscussionResponsesViewModel(get(), get(), get(), comment) } + viewModel { (courseId: String, topicId: String, threadType: String) -> + DiscussionThreadsViewModel( + get(), + get(), + get(), + courseId, + topicId, + threadType + ) + } + viewModel { (thread: org.openedx.discussion.domain.model.Thread) -> + DiscussionCommentsViewModel( + get(), + get(), + get(), + thread + ) + } + viewModel { (comment: DiscussionComment) -> + DiscussionResponsesViewModel( + get(), + get(), + get(), + comment + ) + } viewModel { (courseId: String) -> DiscussionAddThreadViewModel(get(), get(), get(), courseId) } - viewModel { (courseId: String) -> DiscussionSearchThreadViewModel(get(), get(), get(), courseId) } + viewModel { (courseId: String) -> + DiscussionSearchThreadViewModel( + get(), + get(), + get(), + courseId + ) + } viewModel { WhatsNewViewModel(get()) } } \ No newline at end of file diff --git a/app/src/test/java/org/openedx/AppViewModelTest.kt b/app/src/test/java/org/openedx/AppViewModelTest.kt index 1324d26fb..40b3e813d 100644 --- a/app/src/test/java/org/openedx/AppViewModelTest.kt +++ b/app/src/test/java/org/openedx/AppViewModelTest.kt @@ -4,13 +4,6 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry -import org.openedx.app.data.storage.PreferencesManager -import org.openedx.core.data.model.User -import org.openedx.app.room.AppDatabase -import org.openedx.app.system.notifier.AppNotifier -import org.openedx.app.system.notifier.LogoutEvent -import org.openedx.app.AppAnalytics -import org.openedx.app.AppViewModel import io.mockk.every import io.mockk.mockk import io.mockk.verify @@ -27,6 +20,14 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule +import org.openedx.app.AppAnalytics +import org.openedx.app.AppViewModel +import org.openedx.app.data.storage.PreferencesManager +import org.openedx.app.room.AppDatabase +import org.openedx.app.system.notifier.AppNotifier +import org.openedx.app.system.notifier.LogoutEvent +import org.openedx.core.config.Config +import org.openedx.core.data.model.User @ExperimentalCoroutinesApi class AppViewModelTest { @@ -36,6 +37,7 @@ class AppViewModelTest { private val dispatcher = StandardTestDispatcher()//UnconfinedTestDispatcher() + private val config = mockk() private val notifier = mockk() private val room = mockk() private val preferencesManager = mockk() @@ -58,7 +60,8 @@ class AppViewModelTest { every { analytics.setUserIdForSession(any()) } returns Unit every { preferencesManager.user } returns user every { notifier.notifier } returns flow { } - val viewModel = AppViewModel(notifier, room, preferencesManager, dispatcher, analytics) + val viewModel = + AppViewModel(config, notifier, room, preferencesManager, dispatcher, analytics) val mockLifeCycleOwner: LifecycleOwner = mockk() val lifecycleRegistry = LifecycleRegistry(mockLifeCycleOwner) @@ -79,7 +82,8 @@ class AppViewModelTest { every { preferencesManager.user } returns user every { room.clearAllTables() } returns Unit every { analytics.logoutEvent(true) } returns Unit - val viewModel = AppViewModel(notifier, room, preferencesManager, dispatcher, analytics) + val viewModel = + AppViewModel(config, notifier, room, preferencesManager, dispatcher, analytics) val mockLifeCycleOwner: LifecycleOwner = mockk() val lifecycleRegistry = LifecycleRegistry(mockLifeCycleOwner) @@ -87,8 +91,8 @@ class AppViewModelTest { lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START) advanceUntilIdle() - verify(exactly = 1) { analytics.logoutEvent(true) } - assert(viewModel.logoutUser.value != null) + verify(exactly = 1) { analytics.logoutEvent(true) } + assert(viewModel.logoutUser.value != null) } @Test @@ -102,7 +106,8 @@ class AppViewModelTest { every { preferencesManager.user } returns user every { room.clearAllTables() } returns Unit every { analytics.logoutEvent(true) } returns Unit - val viewModel = AppViewModel(notifier, room, preferencesManager, dispatcher, analytics) + val viewModel = + AppViewModel(config, notifier, room, preferencesManager, dispatcher, analytics) val mockLifeCycleOwner: LifecycleOwner = mockk() val lifecycleRegistry = LifecycleRegistry(mockLifeCycleOwner) @@ -110,12 +115,11 @@ class AppViewModelTest { lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START) advanceUntilIdle() - verify(exactly = 1) { analytics.logoutEvent(true) } - verify(exactly = 1) { preferencesManager.clear() } - verify(exactly = 1) { analytics.setUserIdForSession(any()) } - verify(exactly = 1) { preferencesManager.user } - verify(exactly = 1) { room.clearAllTables() } - verify(exactly = 1) { analytics.logoutEvent(true) } + verify(exactly = 1) { analytics.logoutEvent(true) } + verify(exactly = 1) { preferencesManager.clear() } + verify(exactly = 1) { analytics.setUserIdForSession(any()) } + verify(exactly = 1) { preferencesManager.user } + verify(exactly = 1) { room.clearAllTables() } + verify(exactly = 1) { analytics.logoutEvent(true) } } - -} \ No newline at end of file +} diff --git a/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt b/auth/src/main/java/org/openedx/auth/presentation/logistration/LogistrationFragment.kt similarity index 99% rename from auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt rename to auth/src/main/java/org/openedx/auth/presentation/logistration/LogistrationFragment.kt index 6591adc9d..c2736b86f 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/logistration/Logistration.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/logistration/LogistrationFragment.kt @@ -52,7 +52,7 @@ import org.openedx.core.ui.theme.OpenEdXTheme import org.openedx.core.ui.theme.appColors import org.openedx.core.ui.theme.appTypography -class Logistration : Fragment() { +class LogistrationFragment : Fragment() { private val router: AuthRouter by inject() diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt index 02c79efb5..51e06335e 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt @@ -8,10 +8,10 @@ import org.openedx.auth.R import org.openedx.auth.domain.interactor.AuthInteractor import org.openedx.auth.presentation.AuthAnalytics import org.openedx.core.BaseViewModel -import org.openedx.core.BuildConfig import org.openedx.core.SingleEventLiveData import org.openedx.core.UIMessage import org.openedx.core.Validator +import org.openedx.core.config.Config import org.openedx.core.data.storage.CorePreferences import org.openedx.core.extension.isInternetError import org.openedx.core.system.EdxError @@ -21,6 +21,7 @@ import org.openedx.core.system.notifier.AppUpgradeNotifier import org.openedx.core.R as CoreRes class SignInViewModel( + private val config: Config, private val interactor: AuthInteractor, private val resourceManager: ResourceManager, private val preferencesManager: CorePreferences, @@ -49,7 +50,7 @@ class SignInViewModel( val isLogistrationEnabled: LiveData = _isLogistrationEnabled init { - _isLogistrationEnabled.value = BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED + _isLogistrationEnabled.value = config.isPreLoginExperienceEnabled() collectAppUpgradeEvent() } diff --git a/auth/src/test/java/org/openedx/auth/presentation/signin/SignInViewModelTest.kt b/auth/src/test/java/org/openedx/auth/presentation/signin/SignInViewModelTest.kt index b608bd479..92ed3a1bf 100644 --- a/auth/src/test/java/org/openedx/auth/presentation/signin/SignInViewModelTest.kt +++ b/auth/src/test/java/org/openedx/auth/presentation/signin/SignInViewModelTest.kt @@ -1,14 +1,6 @@ package org.openedx.auth.presentation.signin import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import org.openedx.auth.R -import org.openedx.auth.domain.interactor.AuthInteractor -import org.openedx.auth.presentation.AuthAnalytics -import org.openedx.core.UIMessage -import org.openedx.core.Validator -import org.openedx.core.data.model.User -import org.openedx.core.system.EdxError -import org.openedx.core.system.ResourceManager import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every @@ -28,7 +20,16 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule +import org.openedx.auth.R +import org.openedx.auth.domain.interactor.AuthInteractor +import org.openedx.auth.presentation.AuthAnalytics +import org.openedx.core.UIMessage +import org.openedx.core.Validator +import org.openedx.core.config.Config +import org.openedx.core.data.model.User import org.openedx.core.data.storage.CorePreferences +import org.openedx.core.system.EdxError +import org.openedx.core.system.ResourceManager import org.openedx.core.system.notifier.AppUpgradeNotifier import java.net.UnknownHostException import org.openedx.core.R as CoreRes @@ -41,6 +42,7 @@ class SignInViewModelTest { private val dispatcher = StandardTestDispatcher() + private val config = mockk() private val validator = mockk() private val resourceManager = mockk() private val preferencesManager = mockk() @@ -65,6 +67,7 @@ class SignInViewModelTest { every { resourceManager.getString(R.string.auth_invalid_email) } returns invalidEmail every { resourceManager.getString(R.string.auth_invalid_password) } returns invalidPassword every { appUpgradeNotifier.notifier } returns emptyFlow() + every { config.isPreLoginExperienceEnabled() } returns false } @After @@ -77,7 +80,15 @@ class SignInViewModelTest { every { validator.isEmailValid(any()) } returns false every { preferencesManager.user } returns user every { analytics.setUserIdForSession(any()) } returns Unit - val viewModel = SignInViewModel(interactor, resourceManager, preferencesManager, validator, analytics, appUpgradeNotifier) + val viewModel = SignInViewModel( + config, + interactor, + resourceManager, + preferencesManager, + validator, + analytics, + appUpgradeNotifier + ) viewModel.login("", "") coVerify(exactly = 0) { interactor.login(any(), any()) } verify(exactly = 0) { analytics.setUserIdForSession(any()) } @@ -95,7 +106,15 @@ class SignInViewModelTest { every { preferencesManager.user } returns user every { analytics.setUserIdForSession(any()) } returns Unit val viewModel = - SignInViewModel(interactor, resourceManager, preferencesManager, validator, analytics, appUpgradeNotifier) + SignInViewModel( + config, + interactor, + resourceManager, + preferencesManager, + validator, + analytics, + appUpgradeNotifier + ) viewModel.login("acc@test.o", "") coVerify(exactly = 0) { interactor.login(any(), any()) } verify(exactly = 0) { analytics.setUserIdForSession(any()) } @@ -115,7 +134,15 @@ class SignInViewModelTest { every { analytics.setUserIdForSession(any()) } returns Unit coVerify(exactly = 0) { interactor.login(any(), any()) } val viewModel = - SignInViewModel(interactor, resourceManager, preferencesManager, validator, analytics, appUpgradeNotifier) + SignInViewModel( + config, + interactor, + resourceManager, + preferencesManager, + validator, + analytics, + appUpgradeNotifier + ) viewModel.login("acc@test.org", "") verify(exactly = 0) { analytics.setUserIdForSession(any()) } @@ -133,7 +160,15 @@ class SignInViewModelTest { every { preferencesManager.user } returns user every { analytics.setUserIdForSession(any()) } returns Unit val viewModel = - SignInViewModel(interactor, resourceManager, preferencesManager, validator, analytics, appUpgradeNotifier) + SignInViewModel( + config, + interactor, + resourceManager, + preferencesManager, + validator, + analytics, + appUpgradeNotifier + ) viewModel.login("acc@test.org", "ed") coVerify(exactly = 0) { interactor.login(any(), any()) } @@ -152,7 +187,15 @@ class SignInViewModelTest { every { analytics.userLoginEvent(any()) } returns Unit every { preferencesManager.user } returns user every { analytics.setUserIdForSession(any()) } returns Unit - val viewModel = SignInViewModel(interactor, resourceManager, preferencesManager, validator, analytics, appUpgradeNotifier) + val viewModel = SignInViewModel( + config, + interactor, + resourceManager, + preferencesManager, + validator, + analytics, + appUpgradeNotifier + ) coEvery { interactor.login("acc@test.org", "edx") } returns Unit viewModel.login("acc@test.org", "edx") advanceUntilIdle() @@ -174,7 +217,15 @@ class SignInViewModelTest { every { preferencesManager.user } returns user every { analytics.setUserIdForSession(any()) } returns Unit val viewModel = - SignInViewModel(interactor, resourceManager, preferencesManager, validator, analytics, appUpgradeNotifier) + SignInViewModel( + config, + interactor, + resourceManager, + preferencesManager, + validator, + analytics, + appUpgradeNotifier + ) coEvery { interactor.login("acc@test.org", "edx") } throws UnknownHostException() viewModel.login("acc@test.org", "edx") advanceUntilIdle() @@ -196,7 +247,15 @@ class SignInViewModelTest { every { preferencesManager.user } returns user every { analytics.setUserIdForSession(any()) } returns Unit val viewModel = - SignInViewModel(interactor, resourceManager, preferencesManager, validator, analytics, appUpgradeNotifier) + SignInViewModel( + config, + interactor, + resourceManager, + preferencesManager, + validator, + analytics, + appUpgradeNotifier + ) coEvery { interactor.login("acc@test.org", "edx") } throws EdxError.InvalidGrantException() viewModel.login("acc@test.org", "edx") advanceUntilIdle() @@ -218,7 +277,15 @@ class SignInViewModelTest { every { preferencesManager.user } returns user every { analytics.setUserIdForSession(any()) } returns Unit val viewModel = - SignInViewModel(interactor, resourceManager, preferencesManager, validator, analytics, appUpgradeNotifier) + SignInViewModel( + config, + interactor, + resourceManager, + preferencesManager, + validator, + analytics, + appUpgradeNotifier + ) coEvery { interactor.login("acc@test.org", "edx") } throws IllegalStateException() viewModel.login("acc@test.org", "edx") advanceUntilIdle() diff --git a/core/src/main/java/org/openedx/core/config/Config.kt b/core/src/main/java/org/openedx/core/config/Config.kt index b48eae19b..2b4ca4410 100644 --- a/core/src/main/java/org/openedx/core/config/Config.kt +++ b/core/src/main/java/org/openedx/core/config/Config.kt @@ -5,7 +5,6 @@ import com.google.gson.Gson import com.google.gson.JsonElement import com.google.gson.JsonObject import com.google.gson.JsonParser -import org.openedx.core.R import java.io.InputStreamReader class Config(context: Context) { @@ -51,6 +50,10 @@ class Config(context: Context) { return getBoolean(WHATS_NEW_ENABLED, false) } + fun isPreLoginExperienceEnabled(): Boolean { + return getBoolean(PRE_LOGIN_EXPERIENCE_ENABLED, true) + } + private fun getString(key: String, defaultValue: String): String { val element = getObject(key) return if (element != null) { @@ -93,5 +96,6 @@ class Config(context: Context) { private const val AGREEMENT_URLS = "AGREEMENT_URLS" private const val WHATS_NEW_ENABLED = "WHATS_NEW_ENABLED" private const val FIREBASE = "FIREBASE" + private const val PRE_LOGIN_EXPERIENCE_ENABLED = "PRE_LOGIN_EXPERIENCE_ENABLED" } } diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt index 605b260ed..dce9a13d9 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryFragment.kt @@ -64,7 +64,6 @@ class DiscoveryFragment : Fragment() { val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState() val wasUpdateDialogClosed by remember { wasUpdateDialogClosed } val querySearch = arguments?.getString(ARG_SEARCH_QUERY, "") ?: "" - val canShowBackButton by viewModel.canShowBackButton.observeAsState(false) DiscoveryScreen( windowSize = windowSize, @@ -74,7 +73,7 @@ class DiscoveryFragment : Fragment() { canLoadMore = canLoadMore, refreshing = refreshing, hasInternetConnection = viewModel.hasInternetConnection, - canShowBackButton = canShowBackButton, + canShowBackButton = viewModel.canShowBackButton, appUpgradeParameters = AppUpdateState.AppUpgradeParameters( appUpgradeEvent = appUpgradeEvent, wasUpdateDialogClosed = wasUpdateDialogClosed, diff --git a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt index fad5a016f..23ae62ac3 100644 --- a/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt +++ b/discovery/src/main/java/org/openedx/discovery/presentation/DiscoveryViewModel.kt @@ -7,12 +7,11 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.launch import org.openedx.core.BaseViewModel -import org.openedx.core.BuildConfig import org.openedx.core.R import org.openedx.core.SingleEventLiveData import org.openedx.core.UIMessage -import org.openedx.core.data.storage.CorePreferences import org.openedx.core.config.Config +import org.openedx.core.data.storage.CorePreferences import org.openedx.core.domain.model.Course import org.openedx.core.extension.isInternetError import org.openedx.core.system.ResourceManager @@ -32,6 +31,7 @@ class DiscoveryViewModel( ) : BaseViewModel() { val apiHostUrl get() = config.getApiHostURL() + val canShowBackButton get() = config.isPreLoginExperienceEnabled() && corePreferences.user == null private val _uiState = MutableLiveData(DiscoveryUIState.Loading) val uiState: LiveData @@ -53,9 +53,6 @@ class DiscoveryViewModel( val appUpgradeEvent: LiveData get() = _appUpgradeEvent - private val _canShowBackButton = MutableLiveData() - val canShowBackButton: LiveData = _canShowBackButton - val hasInternetConnection: Boolean get() = networkConnection.isOnline() @@ -64,8 +61,6 @@ class DiscoveryViewModel( private var isLoading = false init { - _canShowBackButton.value = - BuildConfig.PRE_LOGIN_EXPERIENCE_ENABLED && corePreferences.user == null getCoursesList() collectAppUpgradeEvent() } diff --git a/discovery/src/test/java/org/openedx/discovery/presentation/DiscoveryViewModelTest.kt b/discovery/src/test/java/org/openedx/discovery/presentation/DiscoveryViewModelTest.kt index d16f6e59c..bcd1f2c66 100644 --- a/discovery/src/test/java/org/openedx/discovery/presentation/DiscoveryViewModelTest.kt +++ b/discovery/src/test/java/org/openedx/discovery/presentation/DiscoveryViewModelTest.kt @@ -56,6 +56,7 @@ class DiscoveryViewModelTest { every { appUpgradeNotifier.notifier } returns emptyFlow() every { corePreferences.user } returns null every { config.getApiHostURL() } returns "http://localhost:8000" + every { config.isPreLoginExperienceEnabled() } returns false } @After diff --git a/profile/src/main/java/org/openedx/profile/presentation/ProfileRouter.kt b/profile/src/main/java/org/openedx/profile/presentation/ProfileRouter.kt index 457b02035..fda55061e 100644 --- a/profile/src/main/java/org/openedx/profile/presentation/ProfileRouter.kt +++ b/profile/src/main/java/org/openedx/profile/presentation/ProfileRouter.kt @@ -13,6 +13,5 @@ interface ProfileRouter { fun navigateToDeleteAccount(fm: FragmentManager) - fun restartApp(fm: FragmentManager) - -} \ No newline at end of file + fun restartApp(fm: FragmentManager, isLogistrationEnabled: Boolean) +} diff --git a/profile/src/main/java/org/openedx/profile/presentation/delete/DeleteProfileFragment.kt b/profile/src/main/java/org/openedx/profile/presentation/delete/DeleteProfileFragment.kt index cf5a393ee..701fa4bb0 100644 --- a/profile/src/main/java/org/openedx/profile/presentation/delete/DeleteProfileFragment.kt +++ b/profile/src/main/java/org/openedx/profile/presentation/delete/DeleteProfileFragment.kt @@ -5,16 +5,31 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.material.rememberScaffoldState -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView @@ -33,17 +48,27 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager +import org.koin.android.ext.android.inject +import org.koin.androidx.viewmodel.ext.android.viewModel import org.openedx.core.R import org.openedx.core.UIMessage -import org.openedx.core.ui.* +import org.openedx.core.ui.BackBtn +import org.openedx.core.ui.HandleUIMessage +import org.openedx.core.ui.IconText +import org.openedx.core.ui.OpenEdXButton +import org.openedx.core.ui.OpenEdXOutlinedTextField +import org.openedx.core.ui.WindowSize +import org.openedx.core.ui.WindowType +import org.openedx.core.ui.displayCutoutForLandscape +import org.openedx.core.ui.rememberWindowSize +import org.openedx.core.ui.statusBarsInset import org.openedx.core.ui.theme.OpenEdXTheme import org.openedx.core.ui.theme.appColors import org.openedx.core.ui.theme.appTypography +import org.openedx.core.ui.windowSizeValue import org.openedx.profile.presentation.ProfileRouter import org.openedx.profile.presentation.edit.EditProfileFragment import org.openedx.profile.presentation.profile.ProfileViewModel -import org.koin.android.ext.android.inject -import org.koin.androidx.viewmodel.ext.android.viewModel import org.openedx.profile.R as profileR class DeleteProfileFragment : Fragment() { @@ -91,7 +116,10 @@ class DeleteProfileFragment : Fragment() { LaunchedEffect(logoutSuccess) { if (logoutSuccess) { - router.restartApp(requireActivity().supportFragmentManager) + router.restartApp( + requireActivity().supportFragmentManager, + logoutViewModel.isLogistrationEnabled + ) } } } diff --git a/profile/src/main/java/org/openedx/profile/presentation/profile/ProfileFragment.kt b/profile/src/main/java/org/openedx/profile/presentation/profile/ProfileFragment.kt index b091ce47f..cbafc859a 100644 --- a/profile/src/main/java/org/openedx/profile/presentation/profile/ProfileFragment.kt +++ b/profile/src/main/java/org/openedx/profile/presentation/profile/ProfileFragment.kt @@ -121,7 +121,7 @@ class ProfileFragment : Fragment() { LaunchedEffect(logoutSuccess) { if (logoutSuccess) { - router.restartApp(requireParentFragment().parentFragmentManager) + router.restartApp(requireParentFragment().parentFragmentManager, viewModel.isLogistrationEnabled) } } } diff --git a/profile/src/main/java/org/openedx/profile/presentation/profile/ProfileViewModel.kt b/profile/src/main/java/org/openedx/profile/presentation/profile/ProfileViewModel.kt index 7f8bc5405..044fa5b65 100644 --- a/profile/src/main/java/org/openedx/profile/presentation/profile/ProfileViewModel.kt +++ b/profile/src/main/java/org/openedx/profile/presentation/profile/ProfileViewModel.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.withContext import org.openedx.core.BaseViewModel import org.openedx.core.R import org.openedx.core.UIMessage +import org.openedx.core.config.Config import org.openedx.core.extension.isInternetError import org.openedx.core.module.DownloadWorkerController import org.openedx.core.system.AppCookieManager @@ -23,6 +24,7 @@ import org.openedx.profile.system.notifier.AccountUpdated import org.openedx.profile.system.notifier.ProfileNotifier class ProfileViewModel( + private val config: Config, private val interactor: ProfileInteractor, private val resourceManager: ResourceManager, private val notifier: ProfileNotifier, @@ -53,6 +55,8 @@ class ProfileViewModel( val appUpgradeEvent: LiveData get() = _appUpgradeEvent + val isLogistrationEnabled get() = config.isPreLoginExperienceEnabled() + init { getAccount() collectAppUpgradeEvent() diff --git a/profile/src/test/java/org/openedx/profile/presentation/profile/ProfileViewModelTest.kt b/profile/src/test/java/org/openedx/profile/presentation/profile/ProfileViewModelTest.kt index 6cdbbd5b1..c7cea7cfb 100644 --- a/profile/src/test/java/org/openedx/profile/presentation/profile/ProfileViewModelTest.kt +++ b/profile/src/test/java/org/openedx/profile/presentation/profile/ProfileViewModelTest.kt @@ -4,15 +4,6 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry -import org.openedx.core.R -import org.openedx.core.UIMessage -import org.openedx.core.module.DownloadWorkerController -import org.openedx.core.system.AppCookieManager -import org.openedx.core.system.ResourceManager -import org.openedx.profile.domain.interactor.ProfileInteractor -import org.openedx.profile.presentation.ProfileAnalytics -import org.openedx.profile.system.notifier.AccountUpdated -import org.openedx.profile.system.notifier.ProfileNotifier import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every @@ -29,8 +20,18 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule +import org.openedx.core.R +import org.openedx.core.UIMessage +import org.openedx.core.config.Config import org.openedx.core.domain.model.ProfileImage +import org.openedx.core.module.DownloadWorkerController +import org.openedx.core.system.AppCookieManager +import org.openedx.core.system.ResourceManager import org.openedx.core.system.notifier.AppUpgradeNotifier +import org.openedx.profile.domain.interactor.ProfileInteractor +import org.openedx.profile.presentation.ProfileAnalytics +import org.openedx.profile.system.notifier.AccountUpdated +import org.openedx.profile.system.notifier.ProfileNotifier import java.net.UnknownHostException @OptIn(ExperimentalCoroutinesApi::class) @@ -41,6 +42,7 @@ class ProfileViewModelTest { private val dispatcher = StandardTestDispatcher() + private val config = mockk() private val resourceManager = mockk() private val interactor = mockk() private val notifier = mockk() @@ -77,6 +79,7 @@ class ProfileViewModelTest { every { resourceManager.getString(R.string.core_error_no_connection) } returns noInternet every { resourceManager.getString(R.string.core_error_unknown_error) } returns somethingWrong every { appUpgradeNotifier.notifier } returns emptyFlow() + every { config.isPreLoginExperienceEnabled() } returns false } @After @@ -87,6 +90,7 @@ class ProfileViewModelTest { @Test fun `getAccount no internetConnection and cache is null`() = runTest { val viewModel = ProfileViewModel( + config, interactor, resourceManager, notifier, @@ -111,6 +115,7 @@ class ProfileViewModelTest { @Test fun `getAccount no internetConnection and cache is not null`() = runTest { val viewModel = ProfileViewModel( + config, interactor, resourceManager, notifier, @@ -135,6 +140,7 @@ class ProfileViewModelTest { @Test fun `getAccount unknown exception`() = runTest { val viewModel = ProfileViewModel( + config, interactor, resourceManager, notifier, @@ -159,6 +165,7 @@ class ProfileViewModelTest { @Test fun `getAccount success`() = runTest { val viewModel = ProfileViewModel( + config, interactor, resourceManager, notifier, @@ -182,6 +189,7 @@ class ProfileViewModelTest { @Test fun `logout no internet connection`() = runTest { val viewModel = ProfileViewModel( + config, interactor, resourceManager, notifier, @@ -209,6 +217,7 @@ class ProfileViewModelTest { @Test fun `logout unknown exception`() = runTest { val viewModel = ProfileViewModel( + config, interactor, resourceManager, notifier, @@ -238,6 +247,7 @@ class ProfileViewModelTest { @Test fun `logout success`() = runTest { val viewModel = ProfileViewModel( + config, interactor, resourceManager, notifier, @@ -267,6 +277,7 @@ class ProfileViewModelTest { @Test fun `AccountUpdated notifier test`() = runTest { val viewModel = ProfileViewModel( + config, interactor, resourceManager, notifier, @@ -288,5 +299,4 @@ class ProfileViewModelTest { coVerify(exactly = 2) { interactor.getAccount() } verify(exactly = 1) { appUpgradeNotifier.notifier } } - -} \ No newline at end of file +} From 67a160b26433416f6775d4abd59c754f1e387681 Mon Sep 17 00:00:00 2001 From: Omer Habib Date: Mon, 4 Dec 2023 17:52:06 +0500 Subject: [PATCH 10/10] fix: addressed minor nits --- README.md | 2 +- .../org/openedx/auth/presentation/signin/SignInFragment.kt | 3 +-- .../org/openedx/auth/presentation/signin/SignInViewModel.kt | 6 ++---- config.yaml | 0 4 files changed, 4 insertions(+), 7 deletions(-) delete mode 100644 config.yaml diff --git a/README.md b/README.md index 8e2c85867..1d4039253 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Modern vision of the mobile application for the Open EdX platform from Raccoon G 3. Choose ``openedx-app-android``. -4. Configure the [config.yaml](config.yaml) with URLs and OAuth credentials for your Open edX instance. +4. Configure the [config.yaml](default_config/dev/config.yaml) with URLs and OAuth credentials for your Open edX instance. 5. Select the build variant ``develop``, ``stage``, or ``prod``. diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt index 0db83051f..fdc3eb847 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt @@ -101,13 +101,12 @@ class SignInFragment : Fragment() { val uiMessage by viewModel.uiMessage.observeAsState() val loginSuccess by viewModel.loginSuccess.observeAsState(initial = false) val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState(null) - val isLogistrationEnabled by viewModel.isLogistrationEnabled.observeAsState(initial = false) if (appUpgradeEvent == null) { LoginScreen( windowSize = windowSize, showProgress = showProgress, - isLogistrationEnabled = isLogistrationEnabled, + isLogistrationEnabled = viewModel.isLogistrationEnabled, uiMessage = uiMessage, onLoginClick = { login, password -> viewModel.login(login, password) diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt index 51e06335e..7e67965cc 100644 --- a/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt +++ b/auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt @@ -30,6 +30,8 @@ class SignInViewModel( private val appUpgradeNotifier: AppUpgradeNotifier ) : BaseViewModel() { + val isLogistrationEnabled get() = config.isPreLoginExperienceEnabled() + private val _showProgress = MutableLiveData() val showProgress: LiveData get() = _showProgress @@ -46,11 +48,7 @@ class SignInViewModel( val appUpgradeEvent: LiveData get() = _appUpgradeEvent - private val _isLogistrationEnabled = MutableLiveData() - val isLogistrationEnabled: LiveData = _isLogistrationEnabled - init { - _isLogistrationEnabled.value = config.isPreLoginExperienceEnabled() collectAppUpgradeEvent() } diff --git a/config.yaml b/config.yaml deleted file mode 100644 index e69de29bb..000000000