diff --git a/app/src/androidTest/java/org/dhis2/usescases/main/MainRobot.kt b/app/src/androidTest/java/org/dhis2/usescases/main/MainRobot.kt index f30b9162cd..e0940974b3 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/main/MainRobot.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/main/MainRobot.kt @@ -1,5 +1,6 @@ package org.dhis2.usescases.main +import androidx.compose.ui.semantics.getOrNull import androidx.compose.ui.test.SemanticsMatcher import androidx.compose.ui.test.assert import androidx.compose.ui.test.assertIsDisplayed @@ -49,6 +50,10 @@ class MainRobot : BaseRobot() { } fun checkViewIsNotEmpty(composeTestRule: ComposeTestRule) { + composeTestRule.waitUntil() { + composeTestRule.onNodeWithTag(HOME_ITEMS) + .fetchSemanticsNode().config.getOrNull(HasPrograms) == true + } composeTestRule.onNodeWithTag(HOME_ITEMS).assert( SemanticsMatcher.expectValue(HasPrograms, true) ) diff --git a/app/src/androidTest/java/org/dhis2/usescases/main/MainTest.kt b/app/src/androidTest/java/org/dhis2/usescases/main/MainTest.kt index db251e45a7..3feb340078 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/main/MainTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/main/MainTest.kt @@ -31,6 +31,7 @@ class MainTest : BaseTest() { fun checkHomeScreenRecyclerviewHasElements() { startActivity() homeRobot { + composeTestRule.waitForIdle() checkViewIsNotEmpty(composeTestRule) } } diff --git a/app/src/main/java/org/dhis2/usescases/main/MainActivity.kt b/app/src/main/java/org/dhis2/usescases/main/MainActivity.kt index c7a4d6679d..fa380c4841 100644 --- a/app/src/main/java/org/dhis2/usescases/main/MainActivity.kt +++ b/app/src/main/java/org/dhis2/usescases/main/MainActivity.kt @@ -27,6 +27,7 @@ import androidx.drawerlayout.widget.DrawerLayout import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar +import dispatch.core.dispatcherProvider import kotlinx.coroutines.launch import org.dhis2.BuildConfig import org.dhis2.R @@ -93,13 +94,7 @@ class MainActivity : private var isPinLayoutVisible = false - private val mainNavigator = MainNavigator( - supportFragmentManager, - { /*no-op*/ }, - ) { titleRes, _, showBottomNavigation -> - setTitle(getString(titleRes)) - setBottomNavigationVisibility(showBottomNavigation) - } + private lateinit var mainNavigator: MainNavigator private val navigationLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { } @@ -138,6 +133,14 @@ class MainActivity : ) mainComponent.inject(this@MainActivity) } ?: navigateTo(true) + mainNavigator = MainNavigator( + dispatcherProvider = presenter.dispatcherProvider, + supportFragmentManager, + { /*no-op*/ }, + ) { titleRes, _, showBottomNavigation -> + setTitle(getString(titleRes)) + setBottomNavigationVisibility(showBottomNavigation) + } super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_main) diff --git a/app/src/main/java/org/dhis2/usescases/main/MainNavigator.kt b/app/src/main/java/org/dhis2/usescases/main/MainNavigator.kt index 8a3fa8cd72..272a051ff9 100644 --- a/app/src/main/java/org/dhis2/usescases/main/MainNavigator.kt +++ b/app/src/main/java/org/dhis2/usescases/main/MainNavigator.kt @@ -10,6 +10,9 @@ import androidx.fragment.app.FragmentTransaction import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import dhis2.org.analytics.charts.ui.GroupAnalyticsFragment +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.dhis2.R import org.dhis2.usescases.about.AboutFragment import org.dhis2.usescases.main.program.ProgramFragment @@ -18,6 +21,7 @@ import org.dhis2.usescases.settings.SyncManagerFragment import org.dhis2.usescases.troubleshooting.TroubleshootingFragment class MainNavigator( + private val dispatcherProvider: dispatch.core.DispatcherProvider, private val fragmentManager: FragmentManager, private val onTransitionStart: () -> Unit, private val onScreenChanged: ( @@ -133,38 +137,50 @@ class MainNavigator( onTransitionStart() currentScreen.value = screen currentFragment = fragment - val transaction: FragmentTransaction = fragmentManager.beginTransaction() - transaction.apply { - if (sharedView == null) { - val (enterAnimation, exitAnimation) = if (useFadeInTransition) { - Pair(android.R.anim.fade_in, android.R.anim.fade_out) - } else { - Pair(R.anim.fragment_enter_right, R.anim.fragment_exit_left) - } - val (enterPopAnimation, exitPopAnimation) = if (useFadeInTransition) { - Pair(android.R.anim.fade_in, android.R.anim.fade_out) - } else { - Pair(R.anim.fragment_enter_left, R.anim.fragment_exit_right) + + CoroutineScope(dispatcherProvider.main).launch { + withContext(dispatcherProvider.io) { + val transaction: FragmentTransaction = fragmentManager.beginTransaction() + transaction.apply { + if (sharedView == null) { + val (enterAnimation, exitAnimation) = getEnterExitAnimation(useFadeInTransition) + val (enterPopAnimation, exitPopAnimation) = getEnterExitPopAnimation(useFadeInTransition) + setCustomAnimations( + enterAnimation, + exitAnimation, + enterPopAnimation, + exitPopAnimation, + ) + } else { + setReorderingAllowed(true) + addSharedElement(sharedView, "contenttest") + } } - setCustomAnimations( - enterAnimation, - exitAnimation, - enterPopAnimation, - exitPopAnimation, - ) - } else { - setReorderingAllowed(true) - addSharedElement(sharedView, "contenttest") + .replace(R.id.fragment_container, fragment, fragment::class.simpleName) + .commitAllowingStateLoss() } + onScreenChanged( + screen.title, + isPrograms(), + isHome(), + ) } - .replace(R.id.fragment_container, fragment, fragment::class.simpleName) - .commitAllowingStateLoss() - - onScreenChanged( - screen.title, - isPrograms(), - isHome(), - ) + } + } + + private fun getEnterExitPopAnimation(useFadeInTransition: Boolean): Pair { + return if (useFadeInTransition) { + Pair(android.R.anim.fade_in, android.R.anim.fade_out) + } else { + Pair(R.anim.fragment_enter_left, R.anim.fragment_exit_right) + } + } + + private fun getEnterExitAnimation(useFadeInTransition: Boolean): Pair { + return if (useFadeInTransition) { + Pair(android.R.anim.fade_in, android.R.anim.fade_out) + } else { + Pair(R.anim.fragment_enter_right, R.anim.fragment_exit_left) } } }