Skip to content

Commit

Permalink
fix: [ANDROAPP-6477] surround lateral menu navigation with async coro…
Browse files Browse the repository at this point in the history
…utine and adapt tests
  • Loading branch information
xavimolloy committed Nov 22, 2024
1 parent d7b6042 commit e7601f2
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MainTest : BaseTest() {
fun checkHomeScreenRecyclerviewHasElements() {
startActivity()
homeRobot {
composeTestRule.waitForIdle()
checkViewIsNotEmpty(composeTestRule)
}
}
Expand Down
17 changes: 10 additions & 7 deletions app/src/main/java/org/dhis2/usescases/main/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()) { }
Expand Down Expand Up @@ -138,6 +133,14 @@ class MainActivity :
)
mainComponent.inject(this@MainActivity)
} ?: navigateTo<LoginActivity>(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)

Expand Down
74 changes: 45 additions & 29 deletions app/src/main/java/org/dhis2/usescases/main/MainNavigator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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: (
Expand Down Expand Up @@ -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<Int, Int> {
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<Int, Int> {
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)
}
}
}

0 comments on commit e7601f2

Please sign in to comment.