@react-native-ohos/react-native-reanimated 4.0.2-beta.1 → 4.0.3-beta.1

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.
@@ -6,6 +6,7 @@
6
6
  #define HARMONY_REANIMATEDSENSOR_H
7
7
  #include <functional>
8
8
  #include <mutex>
9
+ #include <vector>
9
10
  #include <sensors/oh_sensor_type.h>
10
11
  #include "RNOH/TaskExecutor/TaskExecutor.h"
11
12
 
@@ -18,6 +19,17 @@ public:
18
19
  bool initialize();
19
20
  void cancel();
20
21
  void castSensorType(int sensorType);
22
+ /**
23
+ * @brief 传入传感器数据,异步投递到主线程执行 setter_。
24
+ * @param value 传感器数据(按值捕获,生命周期随 lambda 绑定)。
25
+ */
26
+ void runSensor(std::vector<double> value);
27
+ /**
28
+ * @deprecated: 改用 `runSensor(std::vector<double> value)`。
29
+ * 保留以免外部 C++ 插件因签名变更编译失败。内部按 sensorType_ 推导
30
+ * 数据元素个数后拷贝到堆上 vector,再委托给新接口。
31
+ * 调用方需保证 value 在本函数返回前有效(返回后已拷贝无需保持)。
32
+ */
21
33
  void runSensor(double *value);
22
34
  std::function<void(double[], int)> setter_;
23
35
  Sensor_Type sensorType_{SENSOR_TYPE_ACCELEROMETER};
@@ -3,15 +3,16 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import { RNOHLogger, Tag, UITurboModule, UITurboModuleContext } from "@rnoh/react-native-openharmony/ts";
6
- import { window } from '@kit.ArkUI';
7
- import { AnimationManager } from './AnimationManager'
8
- import settings from '@ohos.settings';
9
- import { } from "@ohos.display"
6
+ import { Animator, AnimatorResult, window } from '@kit.ArkUI';
7
+ import { KeyboardState } from './AnimationManager'
8
+ import deviceInfo from '@ohos.deviceInfo';
9
+ import { accessibility } from '@kit.AccessibilityKit';
10
10
 
11
11
  export class ReanimatedModule extends UITurboModule {
12
12
  static NAME = "ReanimatedModule"
13
13
  private logger: RNOHLogger
14
- private keyBordHeight = 0;
14
+ private currentAnimator: AnimatorResult;
15
+ private currentAnimatedHeight = 0;
15
16
 
16
17
  constructor(ctx: UITurboModuleContext) {
17
18
  super(ctx);
@@ -23,24 +24,107 @@ export class ReanimatedModule extends UITurboModule {
23
24
 
24
25
  }
25
26
 
26
- public async subscribeKeyBordListeners() {
27
- const windowInstance = await window.getLastWindow(this.ctx.uiAbilityContext);
27
+ public async subscribeKeyBordListeners(isStatusBarTranslucent: boolean, isNavigationBarTranslucent: boolean) {
28
+ let windowInstance: window.Window;
29
+ try {
30
+ windowInstance = await window.getLastWindow(this.ctx.uiAbilityContext);
31
+ } catch (e: ESObject) {
32
+ this.logger.error(`subscribeKeyBordListeners failed: ${e?.message ?? e}`);
33
+ return;
34
+ }
35
+
28
36
  windowInstance.on('keyboardHeightChange', async (height) => {
29
- let keyBordHeight = this.ctx.getUIContext().px2vp(height);
30
- const animationManager = new AnimationManager();
31
- animationManager.setUpdateCallback((value, status) => {
32
- this.ctx.rnInstance.postMessageToCpp("REANIMATED_KEY_BOARD_CHANGE",
33
- { keyboardHeight: value, status: status.valueOf() });
34
- });
35
- animationManager.startAnimation(this.keyBordHeight, keyBordHeight, 200);
36
- this.keyBordHeight = keyBordHeight;
37
+ const keyBordHeight = this.calculateKeyboardHeight(windowInstance, height, isNavigationBarTranslucent);
38
+ // Unchanged height, skip handle
39
+ if (Math.abs(keyBordHeight - this.currentAnimatedHeight) < 0.01) {
40
+ return;
41
+ }
42
+ this.startKeyboardAnimator(keyBordHeight);
37
43
  })
38
44
  }
39
45
 
46
+ private calculateKeyboardHeight(windowInstance: window.Window, height: number, isNavigationBarTranslucent: boolean): number {
47
+ let navIndicatorHeight = 0;
48
+ try {
49
+ const navIndicatorArea = windowInstance.getWindowAvoidArea(
50
+ window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR
51
+ );
52
+ navIndicatorHeight = this.ctx.getUIContext().px2vp(
53
+ navIndicatorArea?.bottomRect?.height ?? 0
54
+ );
55
+ } catch (e) {
56
+ navIndicatorHeight = 0;
57
+ }
58
+ const isEdgeToEdge = this.isEdgeToEdgeMode(windowInstance);
59
+ const effectiveNavBarTranslucent = isEdgeToEdge && isNavigationBarTranslucent;
60
+ const rawKeyboardHeight = this.ctx.getUIContext().px2vp(height);
61
+ return effectiveNavBarTranslucent
62
+ ? rawKeyboardHeight
63
+ : Math.max(0, rawKeyboardHeight - navIndicatorHeight);
64
+ }
65
+
66
+ private startKeyboardAnimator(keyBordHeight: number) {
67
+ const isOpening = keyBordHeight > this.currentAnimatedHeight;
68
+ this.cancelCurrentAnimator();
69
+ this.currentAnimator = Animator.create({
70
+ duration: isOpening ? 480 : 350,
71
+ delay: 0,
72
+ //simulate the keyboard pop-up and retraction animations in harmony
73
+ easing: isOpening ? "cubic-bezier(0.2, 0.0, 0.1, 1.0)"
74
+ : "cubic-bezier(0.0, 0.0, 0.1, 1.0)",
75
+ fill: "forwards",
76
+ direction: "normal",
77
+ iterations: 1,
78
+ begin: this.currentAnimatedHeight,
79
+ end: keyBordHeight
80
+ }
81
+ )
82
+ this.currentAnimator.onFrame = (progress: number) => {
83
+ this.currentAnimatedHeight = progress;
84
+ if (Math.abs(progress - keyBordHeight) < 0.01) { //The final instruction is sent by "onFinish".
85
+ return;
86
+ }
87
+ let status = isOpening ? KeyboardState.OPENING : KeyboardState.CLOSING;
88
+ this.ctx.rnInstance.postMessageToCpp("REANIMATED_KEY_BOARD_CHANGE",
89
+ { keyboardHeight: progress, status: status.valueOf() });
90
+ }
91
+ this.currentAnimator.onFinish = () => {
92
+ this.currentAnimatedHeight = keyBordHeight;
93
+ let status = isOpening ? KeyboardState.OPEN : KeyboardState.CLOSED;
94
+ this.ctx.rnInstance.postMessageToCpp("REANIMATED_KEY_BOARD_CHANGE",
95
+ { keyboardHeight: keyBordHeight, status: status.valueOf() });
96
+ }
97
+ this.currentAnimator.play();
98
+ }
99
+
100
+ private cancelCurrentAnimator() {
101
+ if (this.currentAnimator) {
102
+ this.currentAnimator.onFrame = null;
103
+ this.currentAnimator.onFinish = null;
104
+ this.currentAnimator.cancel();
105
+ this.currentAnimator = null;
106
+ }
107
+ }
108
+
109
+ private isEdgeToEdgeMode(windowInstance: window.Window): boolean {
110
+ try {
111
+ return windowInstance.getWindowProperties().isLayoutFullScreen;
112
+ } catch (e) {
113
+ return false;
114
+ }
115
+ }
116
+
40
117
  public async unsubscribeKeyBordListeners() {
41
- const windowInstance = await window.getLastWindow(this.ctx.uiAbilityContext);
42
- windowInstance.off('keyboardHeightChange', (v) => {
43
- })
118
+ let windowInstance: window.Window;
119
+ try {
120
+ windowInstance = await window.getLastWindow(this.ctx.uiAbilityContext);
121
+ } catch (e: ESObject) {
122
+ this.logger.error(`unsubscribeKeyBordListeners failed: ${e?.message ?? e}`);
123
+ return;
124
+ }
125
+ windowInstance.off('keyboardHeightChange')
126
+ this.cancelCurrentAnimator();
127
+ this.currentAnimatedHeight = 0;
44
128
  }
45
129
 
46
130
  public setGestureHandlerState(handlerTag: Tag, newState: number) {
@@ -49,4 +133,15 @@ export class ReanimatedModule extends UITurboModule {
49
133
  module.setGestureHandlerState(handlerTag, newState);
50
134
  }
51
135
  }
136
+
137
+ public isReducedMotionEnabled(): boolean {
138
+ try {
139
+ if (deviceInfo.sdkApiVersion >= 23) {
140
+ return (accessibility as ESObject).isAnimationReduceEnabledSync();
141
+ }
142
+ } catch (e) {
143
+ this.logger.warn(`isReducedMotionEnabled failed: ${JSON.stringify(e)}`);
144
+ }
145
+ return false;
146
+ }
52
147
  }
Binary file
package/package.json CHANGED
@@ -4,14 +4,21 @@
4
4
  "alias": "react-native-reanimated",
5
5
  "redirectInternalImports": true
6
6
  },
7
- "version": "4.0.2-beta.1",
7
+ "version": "4.0.3-beta.1",
8
8
  "description": "",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://gitcode.com/CPF-RN/rntpc_react-native-reanimated.git",
12
+ "directory": "package/react-native-reanimated"
13
+ },
14
+ "homepage": "https://gitcode.com/CPF-RN/rntpc_react-native-reanimated/blob/br_rnoh0.82/README.md",
9
15
  "main": "lib/index.js",
10
16
  "scripts": {
11
17
  "build": "tsc",
12
18
  "pack":"npm pack",
13
19
  "pack:prod": "npm pack",
14
- "prepack": "npm run build",
20
+ "prepack": "npm run build && node -e \"require('fs').copyFileSync('../../CHANGELOG.md','./CHANGELOG.md')\" && node -e \"require('fs').copyFileSync('../../README.md','./README.md')\"",
21
+ "postpack": "node -e \"require('fs').rmSync('./CHANGELOG.md',{force:true})\" && node -e \"require('fs').rmSync('./README.md',{force:true})\"",
15
22
  "prepublishOnly": "npm run prepack && react-native verify-package-harmony --package-path . --skip-checks oh_package_name_is_derived_from_npm_package_name",
16
23
  "update_version": "node ./scripts/update-version.js",
17
24
  "deploy": "node ./scripts/deploy.js"
@@ -62,9 +69,10 @@
62
69
  "files": [
63
70
  "lib",
64
71
  "harmony",
65
- "scripts",
72
+ "scripts",
66
73
  "src",
67
74
  "./harmony.tar.gz",
68
- "compatibility.json"
75
+ "compatibility.json",
76
+ "CHANGELOG.md"
69
77
  ]
70
78
  }