react-native-keyboard-controller 1.9.3 → 1.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,10 +22,10 @@ Keyboard manager which works in identical way on both iOS and Android.
22
22
 
23
23
  Install `react-native-keyboard-controller` package from npm:
24
24
 
25
- ```sh
25
+ ```shell
26
26
  yarn add react-native-keyboard-controller
27
27
  # or
28
- # npm install react-native-keyboard-controller --save
28
+ npm install react-native-keyboard-controller --save
29
29
  ```
30
30
 
31
31
  ## Documentation
@@ -43,6 +43,9 @@ android {
43
43
  def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
44
44
  if (agpVersion.tokenize('.')[0].toInteger() >= 7) {
45
45
  namespace "com.reactnativekeyboardcontroller"
46
+ buildFeatures {
47
+ buildConfig true
48
+ }
46
49
  }
47
50
 
48
51
  compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
@@ -22,7 +22,7 @@ val noFocusedInputEvent = FocusedInputLayoutChangedEventData(
22
22
  target = -1,
23
23
  )
24
24
 
25
- class FocusedInputLayoutObserver(val view: ReactViewGroup, private val context: ThemedReactContext?) {
25
+ class FocusedInputObserver(val view: ReactViewGroup, private val context: ThemedReactContext?) {
26
26
  // constructor variables
27
27
  private val surfaceId = UIManagerHelper.getSurfaceId(view)
28
28
 
@@ -41,6 +41,7 @@ class KeyboardAnimationCallback(
41
41
  private var isTransitioning = false
42
42
  private var duration = 0
43
43
  private var viewTagFocused = -1
44
+ private var animation: ValueAnimator? = null
44
45
 
45
46
  // listeners
46
47
  private val focusListener = OnGlobalFocusChangeListener { oldFocus, newFocus ->
@@ -83,7 +84,7 @@ class KeyboardAnimationCallback(
83
84
  }
84
85
  }
85
86
  }
86
- private var layoutObserver: FocusedInputLayoutObserver? = null
87
+ private var layoutObserver: FocusedInputObserver? = null
87
88
 
88
89
  init {
89
90
  require(persistentInsetTypes and deferredInsetTypes == 0) {
@@ -91,7 +92,7 @@ class KeyboardAnimationCallback(
91
92
  " same WindowInsetsCompat.Type values"
92
93
  }
93
94
 
94
- layoutObserver = FocusedInputLayoutObserver(view = view, context = context)
95
+ layoutObserver = FocusedInputObserver(view = view, context = context)
95
96
  view.viewTreeObserver.addOnGlobalFocusChangeListener(focusListener)
96
97
  }
97
98
 
@@ -104,10 +105,6 @@ class KeyboardAnimationCallback(
104
105
  * behavior should be consistent across all versions of platform. To level the difference we
105
106
  * have to implement `onApplyWindowInsets` listener and simulate onStart/onProgress/onEnd
106
107
  * events when keyboard changes its size.
107
- * In the method below we fully recreate the logic that is implemented on old android versions:
108
- * - we dispatch `keyboardWillShow` (onStart);
109
- * - we dispatch change height/progress as animated values (onProgress);
110
- * - we dispatch `keyboardDidShow` (onEnd).
111
108
  */
112
109
  override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
113
110
  val keyboardHeight = getCurrentKeyboardHeight()
@@ -133,57 +130,9 @@ class KeyboardAnimationCallback(
133
130
  val isKeyboardSizeEqual = this.persistentKeyboardHeight == keyboardHeight
134
131
 
135
132
  if (isKeyboardFullyVisible && !isKeyboardSizeEqual && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
133
+ Log.i(TAG, "onApplyWindowInsets: ${this.persistentKeyboardHeight} -> $keyboardHeight")
136
134
  layoutObserver?.syncUpLayout()
137
- this.emitEvent("KeyboardController::keyboardWillShow", getEventParams(keyboardHeight))
138
- context.dispatchEvent(
139
- view.id,
140
- KeyboardTransitionEvent(
141
- surfaceId,
142
- view.id,
143
- "topKeyboardMoveStart",
144
- keyboardHeight,
145
- 1.0,
146
- DEFAULT_ANIMATION_TIME,
147
- viewTagFocused,
148
- ),
149
- )
150
-
151
- val animation =
152
- ValueAnimator.ofFloat(this.persistentKeyboardHeight.toFloat(), keyboardHeight.toFloat())
153
- animation.addUpdateListener { animator ->
154
- val toValue = animator.animatedValue as Float
155
- context.dispatchEvent(
156
- view.id,
157
- KeyboardTransitionEvent(
158
- surfaceId,
159
- view.id,
160
- "topKeyboardMove",
161
- toValue.toDouble(),
162
- toValue.toDouble() / keyboardHeight,
163
- DEFAULT_ANIMATION_TIME,
164
- viewTagFocused,
165
- ),
166
- )
167
- }
168
- animation.doOnEnd {
169
- this.emitEvent("KeyboardController::keyboardDidShow", getEventParams(keyboardHeight))
170
- context.dispatchEvent(
171
- view.id,
172
- KeyboardTransitionEvent(
173
- surfaceId,
174
- view.id,
175
- "topKeyboardMoveEnd",
176
- keyboardHeight,
177
- 1.0,
178
- DEFAULT_ANIMATION_TIME,
179
- viewTagFocused,
180
- ),
181
- )
182
- }
183
- animation.setDuration(DEFAULT_ANIMATION_TIME.toLong()).startDelay = 0
184
- animation.start()
185
-
186
- this.persistentKeyboardHeight = keyboardHeight
135
+ this.onKeyboardResized(keyboardHeight)
187
136
  }
188
137
 
189
138
  return insets
@@ -320,6 +269,78 @@ class KeyboardAnimationCallback(
320
269
  layoutObserver?.destroy()
321
270
  }
322
271
 
272
+ /*
273
+ * In the method below we recreate the logic that used when keyboard appear/disappear:
274
+ * - we dispatch `keyboardWillShow` (onStart);
275
+ * - we dispatch change height/progress as animated values (onProgress);
276
+ * - we dispatch `keyboardDidShow` (onEnd).
277
+ */
278
+ private fun onKeyboardResized(keyboardHeight: Double) {
279
+ if (this.animation?.isRunning == true) {
280
+ Log.i(TAG, "onKeyboardResized -> cancelling animation that is in progress")
281
+ // if animation is in progress, then we are:
282
+ // - removing listeners (update, onEnd)
283
+ // - updating `persistentKeyboardHeight` to latest animated value
284
+ // - cancelling animation to free up CPU resources
285
+ this.animation?.removeAllListeners()
286
+ this.persistentKeyboardHeight = (this.animation?.animatedValue as Float).toDouble()
287
+ this.animation?.cancel()
288
+ }
289
+
290
+ this.emitEvent("KeyboardController::keyboardWillShow", getEventParams(keyboardHeight))
291
+ context.dispatchEvent(
292
+ view.id,
293
+ KeyboardTransitionEvent(
294
+ surfaceId,
295
+ view.id,
296
+ "topKeyboardMoveStart",
297
+ keyboardHeight,
298
+ 1.0,
299
+ DEFAULT_ANIMATION_TIME,
300
+ viewTagFocused,
301
+ ),
302
+ )
303
+
304
+ val animation =
305
+ ValueAnimator.ofFloat(this.persistentKeyboardHeight.toFloat(), keyboardHeight.toFloat())
306
+ animation.addUpdateListener { animator ->
307
+ val toValue = animator.animatedValue as Float
308
+ context.dispatchEvent(
309
+ view.id,
310
+ KeyboardTransitionEvent(
311
+ surfaceId,
312
+ view.id,
313
+ "topKeyboardMove",
314
+ toValue.toDouble(),
315
+ toValue.toDouble() / keyboardHeight,
316
+ DEFAULT_ANIMATION_TIME,
317
+ viewTagFocused,
318
+ ),
319
+ )
320
+ }
321
+ animation.doOnEnd {
322
+ this.emitEvent("KeyboardController::keyboardDidShow", getEventParams(keyboardHeight))
323
+ context.dispatchEvent(
324
+ view.id,
325
+ KeyboardTransitionEvent(
326
+ surfaceId,
327
+ view.id,
328
+ "topKeyboardMoveEnd",
329
+ keyboardHeight,
330
+ 1.0,
331
+ DEFAULT_ANIMATION_TIME,
332
+ viewTagFocused,
333
+ ),
334
+ )
335
+ this.animation = null
336
+ }
337
+ animation.setDuration(DEFAULT_ANIMATION_TIME.toLong()).startDelay = 0
338
+ animation.start()
339
+
340
+ this.animation = animation
341
+ this.persistentKeyboardHeight = keyboardHeight
342
+ }
343
+
323
344
  private fun isKeyboardVisible(): Boolean {
324
345
  val insets = ViewCompat.getRootWindowInsets(view)
325
346
 
@@ -9,7 +9,7 @@
9
9
  /* Begin PBXBuildFile section */
10
10
  0807071E2A34807B00C05A19 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0807071D2A34807B00C05A19 /* Extensions.swift */; };
11
11
  084AEEC62ACF49A8001A3069 /* FocusedInputLayoutChangedEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 084AEEC52ACF49A8001A3069 /* FocusedInputLayoutChangedEvent.m */; };
12
- 084AEEC82ACF4AB2001A3069 /* FocusedInputLayoutObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 084AEEC72ACF4AB2001A3069 /* FocusedInputLayoutObserver.swift */; };
12
+ 084AEEC82ACF4AB2001A3069 /* FocusedInputObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 084AEEC72ACF4AB2001A3069 /* FocusedInputObserver.swift */; };
13
13
  F333F8D428996B8D0015B05F /* KeyboardControllerView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F333F8D228996B8D0015B05F /* KeyboardControllerView.mm */; };
14
14
  F359D34F28133C26000B6AFE /* KeyboardControllerModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = F359D34E28133C26000B6AFE /* KeyboardControllerModule.mm */; };
15
15
  F3626A0728B3FE760021B2D9 /* KeyboardMovementObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3626A0628B3FE760021B2D9 /* KeyboardMovementObserver.swift */; };
@@ -33,7 +33,7 @@
33
33
  0807071D2A34807B00C05A19 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
34
34
  084AEEC22ACF479A001A3069 /* FocusedInputLayoutChangedEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FocusedInputLayoutChangedEvent.h; sourceTree = "<group>"; };
35
35
  084AEEC52ACF49A8001A3069 /* FocusedInputLayoutChangedEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FocusedInputLayoutChangedEvent.m; sourceTree = "<group>"; };
36
- 084AEEC72ACF4AB2001A3069 /* FocusedInputLayoutObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusedInputLayoutObserver.swift; sourceTree = "<group>"; };
36
+ 084AEEC72ACF4AB2001A3069 /* FocusedInputObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusedInputObserver.swift; sourceTree = "<group>"; };
37
37
  134814201AA4EA6300B7C361 /* libKeyboardController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKeyboardController.a; sourceTree = BUILT_PRODUCTS_DIR; };
38
38
  B3E7B5891CC2AC0600A0062D /* KeyboardControllerViewManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyboardControllerViewManager.mm; sourceTree = "<group>"; };
39
39
  F333F8D128996B1C0015B05F /* KeyboardControllerView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyboardControllerView.h; sourceTree = "<group>"; };
@@ -73,7 +73,7 @@
73
73
  isa = PBXGroup;
74
74
  children = (
75
75
  F3626A0628B3FE760021B2D9 /* KeyboardMovementObserver.swift */,
76
- 084AEEC72ACF4AB2001A3069 /* FocusedInputLayoutObserver.swift */,
76
+ 084AEEC72ACF4AB2001A3069 /* FocusedInputObserver.swift */,
77
77
  );
78
78
  path = observers;
79
79
  sourceTree = "<group>";
@@ -172,7 +172,7 @@
172
172
  F3626A0728B3FE760021B2D9 /* KeyboardMovementObserver.swift in Sources */,
173
173
  0807071E2A34807B00C05A19 /* Extensions.swift in Sources */,
174
174
  F359D34F28133C26000B6AFE /* KeyboardControllerModule.mm in Sources */,
175
- 084AEEC82ACF4AB2001A3069 /* FocusedInputLayoutObserver.swift in Sources */,
175
+ 084AEEC82ACF4AB2001A3069 /* FocusedInputObserver.swift in Sources */,
176
176
  F4FF95D7245B92E800C19C63 /* KeyboardControllerViewManager.swift in Sources */,
177
177
  F333F8D428996B8D0015B05F /* KeyboardControllerView.mm in Sources */,
178
178
  F3F50669289E653B003091D6 /* KeyboardMoveEvent.m in Sources */,
@@ -1,5 +1,5 @@
1
1
  //
2
- // FocusedInputLayoutObserver.swift
2
+ // FocusedInputObserver.swift
3
3
  // KeyboardController
4
4
  //
5
5
  // Created by Kiryl Ziusko on 05/10/2023.
@@ -21,8 +21,8 @@ let noFocusedInputEvent: [String: Any] = [
21
21
  ],
22
22
  ]
23
23
 
24
- @objc(FocusedInputLayoutObserver)
25
- public class FocusedInputLayoutObserver: NSObject {
24
+ @objc(FocusedInputObserver)
25
+ public class FocusedInputObserver: NSObject {
26
26
  // class members
27
27
  var onEvent: (NSDictionary) -> Void
28
28
  // state variables
@@ -31,7 +31,7 @@ using namespace facebook::react;
31
31
 
32
32
  @implementation KeyboardControllerView {
33
33
  KeyboardMovementObserver *keyboardObserver;
34
- FocusedInputLayoutObserver *inputObserver;
34
+ FocusedInputObserver *inputObserver;
35
35
  }
36
36
 
37
37
  + (ComponentDescriptorProvider)componentDescriptorProvider
@@ -45,7 +45,7 @@ using namespace facebook::react;
45
45
  static const auto defaultProps = std::make_shared<const KeyboardControllerViewProps>();
46
46
  _props = defaultProps;
47
47
 
48
- inputObserver = [[FocusedInputLayoutObserver alloc] initWithHandler:^(NSDictionary *event) {
48
+ inputObserver = [[FocusedInputObserver alloc] initWithHandler:^(NSDictionary *event) {
49
49
  if (self->_eventEmitter) {
50
50
  int target = [event[@"target"] integerValue];
51
51
  double absoluteY = [event[@"layout"][@"absoluteY"] doubleValue];
@@ -12,7 +12,7 @@ class KeyboardControllerViewManager: RCTViewManager {
12
12
  class KeyboardControllerView: UIView {
13
13
  // internal variables
14
14
  private var keyboardObserver: KeyboardMovementObserver?
15
- private var inputObserver: FocusedInputLayoutObserver?
15
+ private var inputObserver: FocusedInputObserver?
16
16
  private var eventDispatcher: RCTEventDispatcherProtocol
17
17
  private var bridge: RCTBridge
18
18
  // react callbacks
@@ -35,7 +35,7 @@ class KeyboardControllerView: UIView {
35
35
  self.bridge = bridge
36
36
  eventDispatcher = bridge.eventDispatcher()
37
37
  super.init(frame: frame)
38
- inputObserver = FocusedInputLayoutObserver(handler: onInput)
38
+ inputObserver = FocusedInputObserver(handler: onInput)
39
39
  keyboardObserver = KeyboardMovementObserver(handler: onEvent, onNotify: onNotify)
40
40
  }
41
41
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-keyboard-controller",
3
- "version": "1.9.3",
3
+ "version": "1.9.5",
4
4
  "description": "Keyboard manager which works in identical way on both iOS and Android",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",