Skip to content

Commit

Permalink
fix: ignore non-keyboard animations (#300)
Browse files Browse the repository at this point in the history
## 📜 Description

Check that current animation is a keyboard one. If not, then do not send
any events to JS.

## 💡 Motivation and Context

Since we add generic `WindowInsetsAnimationCompat.Callback` -> its
callbacks (`onStart`/`onProgress`/`onEnd`) can be called even when
keyboard is not performing an animation. Thus it's important to filter
out which events are keyboard-related and which one are not.

Initially I copied an example from [Google
samples](https://github.com/android/platform-samples/tree/main/samples/user-interface/window-insets),
but their example code didn't have these checks. I assume it's because
they had only one screen and it wasn't possible to run other insets
animation.

However in [Android
documentation](https://developer.android.com/develop/ui/views/layout/sw-keyboard#synchronize-animation)
in code sample they added a check to filter out non-keyboard animations.
So taking all the information from above I decided to add these checks
and add early return statements to react only on keyboard animation
events.

The similar approach was added in next projects:
-
[Telegram](https://github.com/DrKLO/Telegram/blob/33a48d8945654afdb99df778647251cc2fca4bcc/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanLayoutHelper.java#L411-L423)
-
[Signal](https://github.com/signalapp/Signal-Android/blob/10a363248ea7bba0cacac3385bee5cc2fff280cd/app/src/main/java/org/thoughtcrime/securesms/components/InsetAwareConstraintLayout.kt#L244-L247)

## 📢 Changelog

### Android
- added `WindowInsetsAnimationCompat` extension (new
`isKeyboardAnimation` field);
- return from `onStart`/`onProgress`/`onEnd` callbacks if provided
animation is not keyboard animation.

## 🤔 How Has This Been Tested?

Tested on:
- e2e

## 📸 Screenshots (if appropriate):

No visual difference 🤷‍♂️ 

## 📝 Checklist

- [x] CI successfully passed
  • Loading branch information
kirillzyusko committed Dec 19, 2023
1 parent 5492356 commit 702a669
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.reactnativekeyboardcontroller.extensions

import androidx.core.view.WindowInsetsAnimationCompat
import androidx.core.view.WindowInsetsCompat

val WindowInsetsAnimationCompat.isKeyboardAnimation: Boolean
get() = typeMask and WindowInsetsCompat.Type.ime() != 0
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.reactnativekeyboardcontroller.InteractiveKeyboardProvider
import com.reactnativekeyboardcontroller.events.KeyboardTransitionEvent
import com.reactnativekeyboardcontroller.extensions.dispatchEvent
import com.reactnativekeyboardcontroller.extensions.dp
import com.reactnativekeyboardcontroller.extensions.isKeyboardAnimation
import kotlin.math.abs

private val TAG = KeyboardAnimationCallback::class.qualifiedName
Expand Down Expand Up @@ -142,6 +143,10 @@ class KeyboardAnimationCallback(
animation: WindowInsetsAnimationCompat,
bounds: WindowInsetsAnimationCompat.BoundsCompat,
): WindowInsetsAnimationCompat.BoundsCompat {
if (!animation.isKeyboardAnimation) {
return bounds
}

isTransitioning = true
isKeyboardVisible = isKeyboardVisible()
duration = animation.durationMillis.toInt()
Expand Down Expand Up @@ -181,6 +186,9 @@ class KeyboardAnimationCallback(
): WindowInsetsCompat {
// onProgress() is called when any of the running animations progress...

// ignore non-keyboard animation
runningAnimations.find { it.isKeyboardAnimation } ?: return insets

// First we get the insets which are potentially deferred
val typesInset = insets.getInsets(deferredInsetTypes)
// Then we get the persistent inset types which are applied as padding during layout
Expand Down Expand Up @@ -226,6 +234,10 @@ class KeyboardAnimationCallback(
override fun onEnd(animation: WindowInsetsAnimationCompat) {
super.onEnd(animation)

if (!animation.isKeyboardAnimation) {
return
}

isTransitioning = false
duration = animation.durationMillis.toInt()

Expand Down

0 comments on commit 702a669

Please sign in to comment.