Skip to content

Commit

Permalink
fix: [ANDROAPP-6652] Crash when showing snackbar
Browse files Browse the repository at this point in the history
  • Loading branch information
Balcan committed Nov 27, 2024
1 parent 2ec595a commit 1a1db5d
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,18 @@ import android.transition.ChangeBounds
import android.transition.Transition
import android.transition.TransitionManager
import android.view.View
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.constraintlayout.widget.ConstraintSet
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.viewModelScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import dhis2.org.analytics.charts.ui.GroupAnalyticsFragment
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.dhis2.R
import org.dhis2.bindings.app
import org.dhis2.bindings.clipWithRoundedCorners
import org.dhis2.bindings.dp
import org.dhis2.bindings.userComponent
import org.dhis2.commons.Constants
import org.dhis2.commons.date.DateUtils
import org.dhis2.commons.date.DateUtils.OnFromToSelector
Expand Down Expand Up @@ -60,12 +47,10 @@ import org.dhis2.utils.analytics.DATA_CREATION
import org.dhis2.utils.category.CategoryDialog
import org.dhis2.utils.category.CategoryDialog.Companion.TAG
import org.dhis2.utils.customviews.RxDateDialog
import org.dhis2.utils.customviews.navigationbar.NavigationPage
import org.dhis2.utils.granularsync.SyncStatusDialog
import org.dhis2.utils.granularsync.shouldLaunchSyncDialog
import org.hisp.dhis.android.core.period.DatePeriod
import org.hisp.dhis.android.core.program.Program
import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBar
import org.hisp.dhis.mobile.ui.designsystem.theme.DHIS2Theme
import timber.log.Timber
import java.util.Date
Expand Down Expand Up @@ -110,17 +95,22 @@ class ProgramEventDetailActivity :
initInjection()
themeManager?.setProgramTheme(programUid)
super.onCreate(savedInstanceState)
initEventFilters()
initViewModel()
binding = DataBindingUtil.setContentView(this, R.layout.activity_program_event_detail)
binding.presenter = presenter
binding.totalFilters = FilterManager.getInstance().totalFilters

setupBottomNavigation()
binding.fragmentContainer.clipWithRoundedCorners(16.dp)
binding.filterLayout.adapter = filtersAdapter
presenter.init()
binding.syncButton.setOnClickListener { showSyncDialogProgram() }
setContent {
DHIS2Theme {
ProgramEventDetailScreen(
programEventsViewModel,
presenter,
networkUtils,
{ binding = it },
{
initBindings()
initEventFilters()
initViewModel()
},
)
}
}

if (intent.shouldLaunchSyncDialog()) {
showSyncDialogProgram()
Expand All @@ -140,73 +130,21 @@ class ProgramEventDetailActivity :
}
}

private fun setupBottomNavigation() {
binding.navigationBar.setContent {
DHIS2Theme {
val uiState by programEventsViewModel.navigationBarUIState
val isBackdropActive by programEventsViewModel.backdropActive.observeAsState(false)
var selectedItemIndex by remember(uiState) {
mutableIntStateOf(
uiState.items.indexOfFirst {
it.id == uiState.selectedItem
},
)
}

LaunchedEffect(uiState.selectedItem) {
when (uiState.selectedItem) {
NavigationPage.LIST_VIEW -> {
programEventsViewModel.showList()
}

NavigationPage.MAP_VIEW -> {
networkUtils.performIfOnline(
context = this@ProgramEventDetailActivity,
action = {
presenter.trackEventProgramMap()
programEventsViewModel.showMap()
},
onDialogDismissed = {
selectedItemIndex = 0
},
noNetworkMessage = getString(R.string.msg_network_connection_maps),
)
}

NavigationPage.ANALYTICS -> {
presenter.trackEventProgramAnalytics()
programEventsViewModel.showAnalytics()
}

else -> {
// no-op
}
}
}

AnimatedVisibility(
visible = uiState.items.size > 1 && isBackdropActive.not(),
enter = slideInVertically(animationSpec = tween(200)) { it },
exit = slideOutVertically(animationSpec = tween(200)) { it },
) {
NavigationBar(
modifier = Modifier.fillMaxWidth(),
items = uiState.items,
selectedItemIndex = selectedItemIndex,
) { page ->
programEventsViewModel.onNavigationPageChanged(page)
}
}
}
}
private fun initBindings() {
binding.presenter = presenter
binding.totalFilters = FilterManager.getInstance().totalFilters
binding.fragmentContainer.clipWithRoundedCorners(16.dp)
binding.filterLayout.adapter = filtersAdapter
binding.syncButton.setOnClickListener { showSyncDialogProgram() }
binding.totalFilters = FilterManager.getInstance().totalFilters
}

private fun initExtras() {
programUid = intent.getStringExtra(EXTRA_PROGRAM_UID) ?: ""
}

private fun initInjection() {
component = app().userComponent()
component = userComponent()
?.plus(
ProgramEventDetailModule(
this,
Expand Down Expand Up @@ -243,9 +181,7 @@ class ProgramEventDetailActivity :
programEventsViewModel.onRecreationActivity(false)
}
}
programEventsViewModel.writePermission.observe(this) { canWrite: Boolean ->
binding.addEventButton.visibility = if (canWrite) View.VISIBLE else View.GONE
}

programEventsViewModel.currentScreen.observe(this) { currentScreen: EventProgramScreen? ->
currentScreen?.let {
when (it) {
Expand All @@ -257,12 +193,6 @@ class ProgramEventDetailActivity :
}
}

override fun onResume() {
super.onResume()
binding.addEventButton.isEnabled = true
binding.totalFilters = FilterManager.getInstance().totalFilters
}

private fun showSyncDialogProgram() {
SyncStatusDialog.Builder()
.withContext(this)
Expand All @@ -273,12 +203,9 @@ class ProgramEventDetailActivity :
}
})
.onNoConnectionListener {
val contextView = findViewById<View>(R.id.navigationBar)
Snackbar.make(
contextView,
R.string.sync_offline_check_connection,
Snackbar.LENGTH_SHORT,
).show()
programEventsViewModel.displayMessage(
getString(R.string.sync_offline_check_connection),
)
}
.show("EVENT_SYNC")
}
Expand Down Expand Up @@ -368,13 +295,6 @@ class ProgramEventDetailActivity :
ConstraintSet.BOTTOM,
0,
)
initSet.connect(
R.id.addEventButton,
ConstraintSet.BOTTOM,
R.id.fragmentContainer,
ConstraintSet.BOTTOM,
16.dp,
)
} else {
initSet.connect(
R.id.fragmentContainer,
Expand All @@ -390,13 +310,6 @@ class ProgramEventDetailActivity :
ConstraintSet.TOP,
0,
)
initSet.connect(
R.id.addEventButton,
ConstraintSet.BOTTOM,
R.id.navigationBar,
ConstraintSet.TOP,
16.dp,
)
}
initSet.applyTo(binding.backdropLayout)
}
Expand Down Expand Up @@ -429,19 +342,13 @@ class ProgramEventDetailActivity :
programStageUid = it,
)
}
} else {
enableAddEventButton(true)
}
}
.build()
.show(supportFragmentManager, "ORG_UNIT_DIALOG")
}
}

private fun enableAddEventButton(enable: Boolean) {
binding.addEventButton.isEnabled = enable
}

override fun setWritePermission(canWrite: Boolean) {
programEventsViewModel.writePermission.value = canWrite
}
Expand Down Expand Up @@ -524,47 +431,36 @@ class ProgramEventDetailActivity :
}
})
.onNoConnectionListener {
val contextView = findViewById<View>(R.id.rootView)
Snackbar.make(
contextView,
R.string.sync_offline_check_connection,
Snackbar.LENGTH_SHORT,
).show()
programEventsViewModel.displayMessage(
getString(R.string.sync_offline_check_connection),
)
}
.show(FRAGMENT_TAG)
}

private fun showList() {
supportFragmentManager.beginTransaction().replace(
R.id.fragmentContainer,
binding.fragmentContainer.id,
EventListFragment(),
"EVENT_LIST",
).commitNow()
binding.addEventButton.visibility =
if (programEventsViewModel.writePermission.value == true) {
View.VISIBLE
} else {
View.GONE
}
binding.filter.visibility = View.VISIBLE
}

private fun showMap() {
supportFragmentManager.beginTransaction().replace(
R.id.fragmentContainer,
binding.fragmentContainer.id,
EventMapFragment(),
"EVENT_MAP",
).commitNow()
binding.addEventButton.visibility = View.GONE
binding.filter.visibility = View.VISIBLE
}

private fun showAnalytics() {
supportFragmentManager.beginTransaction().replace(
R.id.fragmentContainer,
binding.fragmentContainer.id,
GroupAnalyticsFragment.forProgram(programUid),
).commitNow()
binding.addEventButton.visibility = View.GONE
binding.filter.visibility = View.GONE
}

Expand Down
Loading

0 comments on commit 1a1db5d

Please sign in to comment.