diff --git a/android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetDialogManager.kt b/android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetDialogManager.kt index 92ffb760b2..26f312f0c4 100644 --- a/android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetDialogManager.kt +++ b/android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetDialogManager.kt @@ -15,7 +15,7 @@ class FormSheetDialogManager( ) { private var formSheetConfig = FormSheetConfig() - private var resolvedDetents: FormSheetDetents? = null + internal val invalidationFlags = FormSheetInvalidationFlags() private val themedContext = ContextThemeWrapper( @@ -89,29 +89,57 @@ class FormSheetDialogManager( internal fun applyConfig(newConfig: FormSheetConfig) { if (formSheetConfig.isOpen != newConfig.isOpen) { - presentationManager.updatePresentationState(newConfig.isOpen) + invalidationFlags.isPresentationInvalidated = true + if (newConfig.isOpen) { + // ALWAYS refresh the sheet configuration when reopening to ensure that BottomSheet + // state and layout are synchronized with native behavior. + invalidationFlags.isAppearanceInvalidated = true + invalidationFlags.isBehaviorInvalidated = true + } } if (formSheetConfig.prefersGrabberVisible != newConfig.prefersGrabberVisible) { - container.setGrabberVisible(newConfig.prefersGrabberVisible) + invalidationFlags.isAppearanceInvalidated = true } - // TODO: @t0maboro - // - invalidation flags logic should be implemented following other components convention - val isOpening = newConfig.isOpen && !formSheetConfig.isOpen - val detentsChanged = resolvedDetents == null || formSheetConfig.detents != newConfig.detents + if (formSheetConfig.detents != newConfig.detents) { + invalidationFlags.isBehaviorInvalidated = true + } + + formSheetConfig = newConfig + + flushPendingUpdates() + } + + private fun flushPendingUpdates() { + if (!invalidationFlags.any()) return - if (detentsChanged) { - resolvedDetents = resolveDetents(newConfig.detents) + if (invalidationFlags.isBehaviorInvalidated) { + invalidationFlags.isBehaviorInvalidated = false + updateSheetBehavior() } - if (detentsChanged || isOpening) { - dimensionsCoordinator.updateFormSheetDetents( - detents = resolvedDetents, - ) + if (invalidationFlags.isAppearanceInvalidated) { + invalidationFlags.isAppearanceInvalidated = false + updateSheetAppearance() } - formSheetConfig = newConfig + if (invalidationFlags.isPresentationInvalidated) { + invalidationFlags.isPresentationInvalidated = false + updateSheetPresentation() + } + } + + private fun updateSheetBehavior() { + dimensionsCoordinator.updateFormSheetDetents(resolveDetents(formSheetConfig.detents)) + } + + private fun updateSheetAppearance() { + container.setGrabberVisible(formSheetConfig.prefersGrabberVisible) + } + + private fun updateSheetPresentation() { + presentationManager.updatePresentationState(formSheetConfig.isOpen) } private fun resolveDetents(rawDetents: List): FormSheetDetents { diff --git a/android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetInvalidationFlags.kt b/android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetInvalidationFlags.kt new file mode 100644 index 0000000000..82c3c65db2 --- /dev/null +++ b/android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetInvalidationFlags.kt @@ -0,0 +1,10 @@ +package com.swmansion.rnscreens.gamma.modals.formsheet + +internal class FormSheetInvalidationFlags( + var isPresentationInvalidated: Boolean = false, + var isAppearanceInvalidated: Boolean = false, + var isBehaviorInvalidated: Boolean = false, +) { + internal fun any(): Boolean = + isPresentationInvalidated || isAppearanceInvalidated || isBehaviorInvalidated +}