@react-native-ohos/react-native-reanimated 3.18.2-rc.2 → 3.18.3-beta.2
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 +2 -2
- package/harmony/reanimated/BuildProfile.ets +1 -1
- package/harmony/reanimated/oh-package-lock.json5 +29 -0
- package/harmony/reanimated/oh-package.json5 +1 -1
- package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/PropsRegistry.h +5 -0
- package/harmony/reanimated/src/main/cpp/ReanimatedModule.cpp +4 -3
- package/harmony/reanimated/src/main/cpp/patches/NativeModules/ReanimatedModuleProxy.cpp +22 -0
- package/harmony/reanimated/src/main/ets/ReanimatedModule.ts +88 -13
- package/harmony/reanimated.har +0 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
This project is based on [react-native-reanimated@v3.18.0](https://github.com/software-mansion/react-native-reanimated/tree/3.18.0)
|
|
3
3
|
|
|
4
4
|
## Documentation
|
|
5
|
-
[中文](https://
|
|
5
|
+
[中文](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/zh-cn/react-native-reanimated.md)
|
|
6
6
|
|
|
7
|
-
[English](https://
|
|
7
|
+
[English](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/en/react-native-reanimated.md)
|
|
8
8
|
|
|
9
9
|
## License
|
|
10
10
|
This library is licensed under [The MIT License (MIT)](https://github.com/react-native-oh-library/react-native-harmony-reanimated/blob/sig/LICENSE).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Use these variables when you tailor your ArkTS code. They must be of the const type.
|
|
3
3
|
*/
|
|
4
|
-
export const HAR_VERSION = '3.18.
|
|
4
|
+
export const HAR_VERSION = '3.18.3-beta.2';
|
|
5
5
|
export const BUILD_MODE_NAME = 'debug';
|
|
6
6
|
export const DEBUG = true;
|
|
7
7
|
export const TARGET_NAME = 'default';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"stableOrder": true
|
|
4
|
+
},
|
|
5
|
+
"lockfileVersion": 3,
|
|
6
|
+
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
|
7
|
+
"specifiers": {
|
|
8
|
+
"@ppd/ffrt@1.1.5": "@ppd/ffrt@1.1.5",
|
|
9
|
+
"@rnoh/react-native-openharmony@../../example/node_modules/react-native-harmony/react_native_openharmony.har": "@rnoh/react-native-openharmony@../../example/node_modules/react-native-harmony/react_native_openharmony.har"
|
|
10
|
+
},
|
|
11
|
+
"packages": {
|
|
12
|
+
"@ppd/ffrt@1.1.5": {
|
|
13
|
+
"name": "@ppd/ffrt",
|
|
14
|
+
"version": "1.1.5",
|
|
15
|
+
"integrity": "sha512-MbXdRqeNHQQv4ALTGdosvOCQI+xH8nt0+E2/aFLS4UuGJ5541MAeenRCDOrgIG05k7SnSJ4WngsCfjj3FbTCQg==",
|
|
16
|
+
"resolved": "https://ohpm.openharmony.cn/ohpm/@ppd/ffrt/-/ffrt-1.1.5.har",
|
|
17
|
+
"registryType": "ohpm"
|
|
18
|
+
},
|
|
19
|
+
"@rnoh/react-native-openharmony@../../example/node_modules/react-native-harmony/react_native_openharmony.har": {
|
|
20
|
+
"name": "@rnoh/react-native-openharmony",
|
|
21
|
+
"version": "0.77.71",
|
|
22
|
+
"resolved": "../../example/node_modules/react-native-harmony/react_native_openharmony.har",
|
|
23
|
+
"registryType": "local",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@ppd/ffrt": "1.1.5"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -17,6 +17,11 @@ class PropsRegistry {
|
|
|
17
17
|
std::lock_guard<std::mutex> createLock() const;
|
|
18
18
|
// returns a lock you need to hold when calling any of the methods below
|
|
19
19
|
|
|
20
|
+
void clear() {
|
|
21
|
+
map_.clear();
|
|
22
|
+
removableShadowNodes_.clear();
|
|
23
|
+
}
|
|
24
|
+
|
|
20
25
|
void update(const ShadowNode::Shared &shadowNode, folly::dynamic &&props);
|
|
21
26
|
|
|
22
27
|
void for_each(std::function<void(
|
|
@@ -105,11 +105,12 @@ void ReanimatedModule::installTurboModule(facebook::jsi::Runtime &rt)
|
|
|
105
105
|
self->keyboardEventDataUpdater_ = std::move(keyboardEventDataUpdater);
|
|
106
106
|
auto weakExecutor = std::weak_ptr(self->m_ctx.taskExecutor);
|
|
107
107
|
if (auto taskExecutor = weakExecutor.lock()) {
|
|
108
|
-
taskExecutor->runTask(TaskThread::MAIN, [ctx = self->m_ctx, isStatusBarTranslucent]() {
|
|
108
|
+
taskExecutor->runTask(TaskThread::MAIN, [ctx = self->m_ctx, isStatusBarTranslucent, isNavigationBarTranslucent]() {
|
|
109
109
|
ArkJS arkJs(ctx.env);
|
|
110
|
-
|
|
110
|
+
auto isStatusBarTranslucentValue = arkJs.createBoolean(isStatusBarTranslucent);
|
|
111
|
+
auto isNavigationBarTranslucentValue = arkJs.createBoolean(isNavigationBarTranslucent);
|
|
111
112
|
auto napiTurboModuleObject = arkJs.getObject(ctx.arkTSTurboModuleInstanceRef);
|
|
112
|
-
napiTurboModuleObject.call("subscribeKeyBordListeners", {});
|
|
113
|
+
napiTurboModuleObject.call("subscribeKeyBordListeners", {isStatusBarTranslucentValue, isNavigationBarTranslucentValue});
|
|
113
114
|
});
|
|
114
115
|
}
|
|
115
116
|
return 0;
|
|
@@ -234,6 +234,28 @@ ReanimatedModuleProxy::~ReanimatedModuleProxy() {
|
|
|
234
234
|
frameCallbacks_.clear();
|
|
235
235
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
236
236
|
operationsInBatch_.clear();
|
|
237
|
+
// 清空 PropsRegistry 中持有的 ShadowNode 引用,避免析构时级联释放已被框架回收的 ShadowNodeFamily
|
|
238
|
+
if (propsRegistry_) {
|
|
239
|
+
auto lock = propsRegistry_->createLock();
|
|
240
|
+
// 清空内部 map,释放所有 ShadowNode::Shared
|
|
241
|
+
propsRegistry_->clear();
|
|
242
|
+
}
|
|
243
|
+
propsRegistry_.reset();
|
|
244
|
+
|
|
245
|
+
// LayoutAnimationsProxy 持有 ShadowView/MutationNode 引用(内部包含
|
|
246
|
+
// ShadowNode::Shared),需要在 runtime 销毁前清空,避免 runtime 析构时
|
|
247
|
+
// GC 级联触发 ShadowNodeFamily::~ShadowNodeFamily() 崩溃
|
|
248
|
+
if (layoutAnimationsProxy_) {
|
|
249
|
+
auto lock = std::unique_lock<std::recursive_mutex>(
|
|
250
|
+
layoutAnimationsProxy_->mutex);
|
|
251
|
+
layoutAnimationsProxy_->layoutAnimations_.clear();
|
|
252
|
+
layoutAnimationsProxy_->nodeForTag_.clear();
|
|
253
|
+
layoutAnimationsProxy_->deadNodes.clear();
|
|
254
|
+
layoutAnimationsProxy_->leastRemoved.clear();
|
|
255
|
+
layoutAnimationsProxy_->surfaceManager.props_.clear();
|
|
256
|
+
}
|
|
257
|
+
layoutAnimationsProxy_.reset();
|
|
258
|
+
|
|
237
259
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
238
260
|
uiWorkletRuntime_.reset();
|
|
239
261
|
}
|
|
@@ -3,40 +3,104 @@
|
|
|
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 {
|
|
6
|
+
import { Animator, AnimatorResult, window } from '@kit.ArkUI';
|
|
7
|
+
import { KeyboardState } from "./AnimationManager";
|
|
8
8
|
|
|
9
9
|
export class ReanimatedModule extends UITurboModule {
|
|
10
10
|
static NAME = "ReanimatedModule"
|
|
11
11
|
private logger: RNOHLogger
|
|
12
12
|
private keyBordHeight = 0;
|
|
13
|
+
private currentAnimator: AnimatorResult ;
|
|
14
|
+
private currentAnimatedHeight = 0;
|
|
13
15
|
|
|
14
|
-
constructor(ctx:
|
|
16
|
+
constructor(ctx: UITurboModuleContext) {
|
|
15
17
|
super(ctx);
|
|
16
18
|
this.logger = ctx.logger.clone("Reanimated");
|
|
17
19
|
}
|
|
20
|
+
|
|
18
21
|
public setViewProps(tag: Tag, props: Object) {
|
|
19
22
|
this.ctx.descriptorRegistry.setAnimatedRawProps(tag, props);
|
|
20
23
|
}
|
|
21
24
|
|
|
22
|
-
public async subscribeKeyBordListeners() {
|
|
25
|
+
public async subscribeKeyBordListeners(isStatusBarTranslucent: boolean, isNavigationBarTranslucent: boolean) {
|
|
26
|
+
//ignore isStatusBarTranslucent - those are Android only
|
|
23
27
|
const windowInstance = await window.getLastWindow(this.ctx.uiAbilityContext);
|
|
28
|
+
const navIndicatorArea = windowInstance.getWindowAvoidArea(
|
|
29
|
+
window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR
|
|
30
|
+
);
|
|
31
|
+
const navIndicatorHeight = this.ctx.getUIContext().px2vp(
|
|
32
|
+
navIndicatorArea.bottomRect.height
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const isEdgeToEdge = this.isEdgeToEdgeMode(windowInstance);
|
|
36
|
+
const effectiveNavBarTranslucent = isEdgeToEdge && isNavigationBarTranslucent;
|
|
37
|
+
|
|
24
38
|
windowInstance.on('keyboardHeightChange', async (height) => {
|
|
25
|
-
let
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
let rawKeyboardHeight = this.ctx.getUIContext().px2vp(height);
|
|
40
|
+
//If the immersive mode is not enabled, then the area around the bottom navigation bar that needs to be avoided needs to be removed.
|
|
41
|
+
//If the immersive mode is enabled, the returned value will be the height of the current keyboard.
|
|
42
|
+
let keyBordHeight = effectiveNavBarTranslucent
|
|
43
|
+
? rawKeyboardHeight
|
|
44
|
+
: Math.max(0, rawKeyboardHeight - navIndicatorHeight);
|
|
45
|
+
|
|
46
|
+
//Unchanged height, skip handle
|
|
47
|
+
if (Math.abs(keyBordHeight - this.currentAnimatedHeight) < 0.01) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const isOpening = keyBordHeight > this.keyBordHeight;
|
|
52
|
+
|
|
53
|
+
if (this.currentAnimator) {
|
|
54
|
+
this.currentAnimator.onFrame = null;
|
|
55
|
+
this.currentAnimator.onFinish = null;
|
|
56
|
+
this.currentAnimator.cancel();
|
|
57
|
+
this.currentAnimator = null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.currentAnimator = Animator.create({
|
|
61
|
+
duration: isOpening ? 480 : 350,
|
|
62
|
+
delay: 0,
|
|
63
|
+
//simulate the keyboard pop-up and retraction animations in harmony
|
|
64
|
+
easing: isOpening ? "cubic-bezier(0.2, 0.0, 0.1, 1.0)"
|
|
65
|
+
: "cubic-bezier(0.0, 0.0, 0.1, 1.0)",
|
|
66
|
+
fill: "forwards",
|
|
67
|
+
direction: "normal",
|
|
68
|
+
iterations: 1,
|
|
69
|
+
begin: this.currentAnimatedHeight,
|
|
70
|
+
end: keyBordHeight
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
this.currentAnimator.onFrame = (progress: number) => {
|
|
74
|
+
this.currentAnimatedHeight = progress;
|
|
75
|
+
if (Math.abs(progress - keyBordHeight) < 0.01) { //The final instruction is sent by "onFinish".
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
let status = keyBordHeight > this.keyBordHeight ? KeyboardState.OPENING : KeyboardState.CLOSING;
|
|
28
79
|
this.ctx.rnInstance.postMessageToCpp("REANIMATED_KEY_BOARD_CHANGE",
|
|
29
|
-
{ keyboardHeight:
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
80
|
+
{ keyboardHeight: progress, status: status.valueOf() });
|
|
81
|
+
}
|
|
82
|
+
this.currentAnimator.onFinish = () => {
|
|
83
|
+
this.currentAnimatedHeight = keyBordHeight;
|
|
84
|
+
let status = keyBordHeight > this.keyBordHeight ? KeyboardState.OPEN : KeyboardState.CLOSED;
|
|
85
|
+
this.keyBordHeight = keyBordHeight;
|
|
86
|
+
this.ctx.rnInstance.postMessageToCpp("REANIMATED_KEY_BOARD_CHANGE",
|
|
87
|
+
{ keyboardHeight: keyBordHeight, status: status.valueOf() });
|
|
88
|
+
}
|
|
89
|
+
this.currentAnimator.play();
|
|
33
90
|
})
|
|
34
91
|
}
|
|
35
92
|
|
|
36
93
|
public async unsubscribeKeyBordListeners() {
|
|
37
94
|
const windowInstance = await window.getLastWindow(this.ctx.uiAbilityContext);
|
|
38
|
-
windowInstance.off('keyboardHeightChange'
|
|
39
|
-
|
|
95
|
+
windowInstance.off('keyboardHeightChange')
|
|
96
|
+
if (this.currentAnimator) {
|
|
97
|
+
this.currentAnimator.onFrame = null;
|
|
98
|
+
this.currentAnimator.onFinish = null;
|
|
99
|
+
this.currentAnimator.cancel();
|
|
100
|
+
this.currentAnimator = null;
|
|
101
|
+
}
|
|
102
|
+
this.keyBordHeight = 0;
|
|
103
|
+
this.currentAnimatedHeight = 0;
|
|
40
104
|
}
|
|
41
105
|
|
|
42
106
|
public setGestureHandlerState(handlerTag: Tag, newState: number) {
|
|
@@ -45,4 +109,15 @@ export class ReanimatedModule extends UITurboModule {
|
|
|
45
109
|
module.setGestureHandlerState(handlerTag, newState);
|
|
46
110
|
}
|
|
47
111
|
}
|
|
112
|
+
|
|
113
|
+
private isEdgeToEdgeMode(windowInstance: window.Window) {
|
|
114
|
+
let isLayoutFullScreen = false;
|
|
115
|
+
try {
|
|
116
|
+
const windowProperties = windowInstance.getWindowProperties();
|
|
117
|
+
isLayoutFullScreen = windowProperties.isLayoutFullScreen;
|
|
118
|
+
} catch (e: ESObject) {
|
|
119
|
+
isLayoutFullScreen = false;
|
|
120
|
+
}
|
|
121
|
+
return isLayoutFullScreen;
|
|
122
|
+
}
|
|
48
123
|
}
|
package/harmony/reanimated.har
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
"alias": "react-native-reanimated",
|
|
5
5
|
"redirectInternalImports": true
|
|
6
6
|
},
|
|
7
|
-
"version": "3.18.
|
|
7
|
+
"version": "3.18.3-beta.2",
|
|
8
8
|
"description": "",
|
|
9
9
|
"main": "lib/index.js",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
|
+
"pack":"npm pack",
|
|
12
13
|
"pack:prod": "npm pack",
|
|
13
14
|
"prepack": "npm run build",
|
|
14
15
|
"prepublishOnly": "npm run prepack && react-native verify-package-harmony --package-path . --skip-checks oh_package_name_is_derived_from_npm_package_name",
|