-
-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: incorrect Modal
layout (if it was open while keyboard was visible)
#624
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
kirillzyusko
added
π bug
Something isn't working
π€ android
Android specific
π modal
Anything that involves Modal usage
labels
Oct 9, 2024
π Package size report
|
kirillzyusko
force-pushed
the
fix/619-modal-incorrect-layout
branch
from
October 9, 2024 16:39
db835f6
to
7cf54fe
Compare
This is awesome @kirillzyusko! Excited to test it out when a new package is published. |
2 tasks
kirillzyusko
added a commit
that referenced
this pull request
Dec 3, 2024
## π Description Fixed a crash when `progress` value becomes `Infinity` and can not be serialized to JS. ## π‘ Motivation and Context It happens when we try to divide any double/float number (except `0`) by `0.0`. In our case we were trying to divide `height / persistentKeyboardHeight`. To shed more light on the issue I modified condition `it.isNan()` to `it.isNaN() || it.isInfinite()`, and we get: ```bash LOG {"duration": 160, "eventName": "onKeyboardMoveStart", "height": 0, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 47.71428680419922, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 47.71428680419922, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 47.71428680419922, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 46.57143020629883, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 42.85714340209961, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 36.57143020629883, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 28, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 17.714284896850586, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 9.142857551574707, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 2.2857143878936768, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 0, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMove", "height": 0, "progress": 0, "target": -1} LOG {"duration": 160, "eventName": "onKeyboardMoveEnd", "height": 0, "progress": 0, "target": -1} ``` In `onStart` the `keyboardHeight=0`, `isKeyboardVisible-false` and we don't update `this.persistentKeyboardHeight` (it's 0.0 by default). From logs above it looks like keyboard is animating from `47` pixels to `0`, but in fact there is no keyboard animation on the screen at all! π€― So in my understand it's a bug somewhere in google code (or in my code - but such animation is not correct). Below are the options that I considered for a fix: ### 1οΈβ£ add a condition, that will check if a prev `height !== 0` and if `nextHeight === 0` then ignore an animation Such solution will add more complexity, more if-statements without an explicit benefits and warranty that it will fix/work for other similar scenarios. ### 2οΈβ£ check that target == -1 and ignore animation then Not a reliable solution, because we start to depend on 3rd party variables state. And it's a known fact, that if you get a transitive dependencies, then the solution drastically becomes more complex. ### 3οΈβ£ add `isInfinite` check and set progress to `0` then While it fixes a crash we still get an incorrect `height` values so any animation that depends on these values will be running and it will look strange π¬ ### 4οΈβ£ don't attach keyboard callbacks to Modal window on Android 9 The most perspective solution - on Android < 12 all events are passing through the main window (and actually attaching a callback is not necessary there, but when I implemented #466 and #624 I decided to keep the code for consistency). So if we remove these callbacks (if we attach them to window only for Android 12) then all code works well on both platforms. Closes #714 ## π’ Changelog ### Android - don't attach keyboard callbacks on Android < 12 to `Modal` window; ## π€ How Has This Been Tested? Tested in reproduction example and on CI. ## πΈ Screenshots (if appropriate): https://github.com/user-attachments/assets/76331e0d-6779-4a4b-a837-ba4802ac4139 ## π Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was change
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
π€ android
Android specific
π bug
Something isn't working
e2e
Anything about E2E tests
π modal
Anything that involves Modal usage
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
π Description
Fixed a problem of
Modal
window not stretching to full height of the screen ifModal
was opened when keyboard was open.π‘ Motivation and Context
The problem was caused by the fact that I attached
OnApplyWindowListener
to arootView
. Somehow it was breaking a layout and always keptkeyboard space
if Modal was opened when keyboard is visible.The first approach was an attempt to resize that window. I've tried to specify
.layoutParams
but it was a failed attempt. Why? Because in the end I had two options:After some time I wrote a code where I set
OnApplyWindowListener
conditionally:DialogRootViewGroup
(I was getting an instance ofReactModalHostView.hostVIew
via reflection);While it was working approach it has several downsides:
isKeyboardVisible
public one);So I decided to look for a more robust approach - and I decided to apply changes that I used in
EdgeToEdgeReactViewGroup
. I created a custom view (0 width and height) and was attaching it to therootView
of the modal. In this case I don't inject my custom handler intorootView
, so the layout is managed properly.While it works I noticed that sometimes red (animated) or gray (reanimated) circles may behave differently and eventually they have a broken state. The problem is that sometimes
onProgress
/onEnd
may be triggered from main callback. I addedSuspense
mechanism where I can toggle off the functionality on demand and pause callbacks events.While it was working good on Android 12+ it wasn't working on Android < 12. The problem comes from the fact that on these OS versions Android emulates keyboard transitions, and listens to main window. So if we pause main window callback then all transitions are not working - the obvious way to fix is to make
.suspense
call conditional.I refactored that part (reduced code duplication, moved everything to reusable code, etc.) and now this PR is ready to be merged π
Closes #619
π’ Changelog
JS
suspendable
tocspell
ignore;E2E
Android
constants
package with newKeyboard
class (withIS_ANIMATION_EMULATED
field);Suspendable
interface;KeyboardAnimationCallback
now implementsSuspendable
;onStart
/onProgress
/onEnd
callbacks if callback is suspended;WindowInsetsCompat.CONSUMED
back toinsets
;syncKeyboardPosition
now can acceptheight
andvisible
as params;KeyboardAnimationCallback
instance toModalAttachedWatcher
fromEdgeToEdgeReactViewGroup
;eventView
torootView
ofModal
when modal is shown;setOnApplyWindowInsetsListener
toeventView
;eventView
whenModal
dismissed;syncKeyboardPosition
to closed keyboard state whenModal
is shown on Android 12+;KeyboardAnimationCallback
whenModal
is shown on Android 12+;KeyboardAnimationCallback
whenModal
is dismissed;π€ How Has This Been Tested?
Tested manually on:
Additionally covered everything with e2e tests π
πΈ Screenshots (if appropriate):
π Checklist