已开启
chore(0.72): 同步分支修改 #68
已开启
action创建于 9月12日
共 2 个文件变更+28-5
@@ -35,7 +35,8 @@
35 "peerDependencies": {35 "peerDependencies": {
36 "react": ">=16.13.1",36 "react": ">=16.13.1",
37 "react-native": ">=0.63.2",37 "react-native": ">=0.63.2",
38- "react-native-windows": ">=0.63.3"38+ "react-native-windows": ">=0.63.3",
G
Ggyange9月28日

@react-native-ohos/native-stack 只在 OHOS 平台存在,但 peerDependencies 里没有对应 peerDependenciesMeta.optional 标记。非 OHOS 平台安装时 npm/yarn 会报 unmet peer dependency 警告。参照上面 react-native-windows 的做法,给它也加一个 optional: true?

likedislike
39+ "@react-native-ohos/native-stack": ">=7.4.0-rc.12"
G
Ggyange12 天前

peerDependencies 里 @react-native-ohos/native-stack 下限是 7.4.0-rc.12,是个 RC 版本。消费方 npm install 可能拉到不稳定的预发布版,是否等稳定版发布后再合入,或者至少把下限收到 >=7.4.0?

likedislike
39 },40 },
40 "peerDependenciesMeta": {41 "peerDependenciesMeta": {
41 "react-native-windows": {42 "react-native-windows": {
@@ -9,9 +9,11 @@
9"use strict";9"use strict";
10 10 
11import { TurboModuleRegistry } from "react-native";11import { TurboModuleRegistry } from "react-native";
12-var OrientationNative = TurboModuleRegistry ? 12+import { setIsFullScreen } from '@react-native-ohos/native-stack';
13-TurboModuleRegistry.get('OreitationLockerNativeModule') :13+ 
14-require('react-native').NativeModules.Orientation;14+var OrientationNative = TurboModuleRegistry ?
15+ TurboModuleRegistry.get('OreitationLockerNativeModule') :
16+ require('react-native').NativeModules.Orientation;
15var deviceEventEmitter = require('react-native').DeviceEventEmitter;17var deviceEventEmitter = require('react-native').DeviceEventEmitter;
16 18 
17var listeners = {};19var listeners = {};
@@ -36,6 +38,20 @@ function getKey(listener) {
36 return listener[META];38 return listener[META];
37}39}
38 40 
41+function waitRedrawEnd() {
GG
Ggyange9月28日

waitRedrawEnd 用 requestAnimationFrame 轮询累计 100ms 来等 native 全屏重绘完成,但 rAF 只保证 JS 帧回调,不等 native 侧真正画完。低端设备或高负载时 100ms 可能不够,高端设备上又白等。native-stack 有没有提供 fullscreen 切换完成的回调或 Promise?有的话用它比硬等靠谱。

likedislike
Ggyange12 天前

waitRedrawEnd 用 requestAnimationFrame 循环轮询 Date.now() 直到过 100ms,但从未检查 redraw 是否真的完成——实质上就是 setTimeout(100),还多了 rAF 的调度开销。如果目的是等 native 全屏生效后再锁方向,有没有 native 侧的回调或事件可以用?如果没有,至少直接用 setTimeout 更直观。

likedislike
42+ return new Promise(resolve => {
43+ const start = Date.now();
44+ const loop = () => {
45+ if (Date.now() - start >= 100) {
G
Ggyange18 天前

100ms 硬编码等帧绘制完成——慢设备可能不够、快设备白等。setIsFullScreen 有没有回调或返回 promise 能知道全屏切换真正完成了?用 rAF 轮询 100ms 不太靠谱,而且 unlock 路径里也没有 setIsFullScreen(false),从横屏解锁后全屏状态会残留。

likedislike
46+ resolve();
47+ } else {
48+ requestAnimationFrame(loop);
49+ }
50+ };
51+ requestAnimationFrame(loop);
52+ });
53+}
54+ 
39export default class Orientation {55export default class Orientation {
40 static _disableFaceUpDown = false;56 static _disableFaceUpDown = false;
41 57
@@ -65,6 +81,8 @@ export default class Orientation {
65 static lockToPortrait = () => {81 static lockToPortrait = () => {
66 locked = true;82 locked = true;
67 OrientationNative.lockToPortrait();83 OrientationNative.lockToPortrait();
84+ // 锁定竖屏 通知native-stack关闭全屏
85+ setIsFullScreen(false);
68 };86 };
69 87 
70 static lockToPortraitUpsideDown = () => {88 static lockToPortraitUpsideDown = () => {
@@ -74,7 +92,11 @@ export default class Orientation {
74 92 
75 static lockToLandscape = () => {93 static lockToLandscape = () => {
76 locked = true;94 locked = true;
77- OrientationNative.lockToLandscape();95+ // 锁定横屏 通知native-stack开启全屏
GG
Ggyange9月28日

lockToLandscapeLeft、lockToLandscapeRight、lockToPortraitUpsideDown 都没有调 setIsFullScreen,只有 lockToLandscape 和 lockToPortrait 改了。如果业务直接调 lockToLandscapeLeft,全屏状态和实际方向会不一致。是不是该把 setIsFullScreen 收到一个内部统一入口,或者每个 lock 方法都补上?

likedislike
Ggyange18 天前

lockToLandscapeLeft 和 lockToLandscapeRight 没有调用 setIsFullScreen(true),如果业务侧走这两个方法锁横屏,全屏不会开启,画面会裁在 non-fullscreen 区域里。三个横屏入口是不是都要加?

likedislike
Ggyange12 天前

只有 lockToLandscape 加了 setIsFullScreen(true) + waitRedrawEnd,lockToLandscapeLeft 和 lockToLandscapeRight 没改。通过这两个入口进横屏时全屏不会开启,是有意为之还是漏了?

likedislike
96+ setIsFullScreen(true);
GG
Ggyange18 天前

快速连续调 lockToLandscape 会创建多个 pending promise,每个到期后都会再调一次 OrientationNative.lockToLandscape()。加个 generation 计数器或取消前一个 pending,避免过期回调覆盖新状态。

likedislike
Ggyange12 天前

lockToLandscape 把 native 调用延迟到 waitRedrawEnd 之后,但 locked 在延迟之前就置 true 了。如果这 100ms+ 的窗口里用户又调了 lockToPortrait,portrait 的 native 调用会立即执行,然后被随后触发的 deferred landscape 覆盖——最终停在横屏,和最后一次调用意图相反。可以考虑用一个 pending 队列或者 cancel 上一次 deferred 的方式,保证只有最后一次 lock 调用真正落到 native。

likedislike
97+ waitRedrawEnd().then(() => {
98+ OrientationNative.lockToLandscape();
99+ });
78 };100 };
79 101 
80 static lockToLandscapeRight = () => {102 static lockToLandscapeRight = () => {