@ohos-cpf/3rdloop 0.0.7 → 0.0.9

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.
Files changed (230) hide show
  1. package/README.md +44 -25
  2. package/lib/cli.js +54 -29
  3. package/lib/config-cmd.js +1 -1
  4. package/lib/config.js +32 -0
  5. package/lib/doctor.js +266 -48
  6. package/lib/mcp.js +498 -0
  7. package/lib/opencode.js +75 -29
  8. package/lib/orch.js +32 -10
  9. package/lib/runner.js +8 -5
  10. package/lib/serve.js +162 -149
  11. package/lib/step.js +15 -4
  12. package/lib/web.js +107 -265
  13. package/lib/workflow.js +18 -8
  14. package/package.json +6 -2
  15. package/vendor/Archive/data/.index/meta.json +7 -0
  16. package/vendor/Archive/data/.index/search.db +0 -0
  17. package/vendor/Archive/data/docs/experiences/arkts-check-tool-pitfalls-baseline-comparison.md +13 -0
  18. package/vendor/Archive/data/docs/experiences/arkts-deep-path-import-recognition.md +31 -0
  19. package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-entry-file-case-mismatch.md +25 -0
  20. package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-import-trailing-slash.md +20 -0
  21. package/vendor/Archive/data/docs/experiences/arkts-library-source-files-may-be-ts.md +18 -0
  22. package/vendor/Archive/data/docs/experiences/arkts-typedarray-buffer-interface-cast-compile-fixes.md +36 -0
  23. package/vendor/Archive/data/docs/experiences/arkts-xts-compile-error-clustering-fix.md +24 -0
  24. package/vendor/Archive/data/docs/experiences/arkts-xts-doc-expected-value-runtime-probe.md +35 -0
  25. package/vendor/Archive/data/docs/experiences/arkts-xts-fixture-rawfile-testability-injection.md +33 -0
  26. package/vendor/Archive/data/docs/experiences/code-linter-chinese-comment-false-positive.md +16 -0
  27. package/vendor/Archive/data/docs/experiences/esobject-new-expression-variable-tracking.md +33 -0
  28. package/vendor/Archive/data/docs/experiences/filesystem-case-sensitivity-module-resolution.md +31 -0
  29. package/vendor/Archive/data/docs/experiences/gitcode-clone-redirect-warning-normal.md +13 -0
  30. package/vendor/Archive/data/docs/experiences/kn_msgvq1w585ec8319.md +77 -0
  31. package/vendor/Archive/data/docs/experiences/kn_msovnm6rd46de72c.md +98 -0
  32. package/vendor/Archive/data/docs/experiences/kn_mspt8vntfe708576.md +87 -0
  33. package/vendor/Archive/data/docs/experiences/kn_mspu1ei77adbbb48.md +133 -0
  34. package/vendor/Archive/data/docs/experiences/kn_mspubgak8d30bfce.md +128 -0
  35. package/vendor/Archive/data/docs/experiences/kn_mspug2de3cb1f7c3.md +115 -0
  36. package/vendor/Archive/data/docs/experiences/kn_skill_opt_001.md +38 -0
  37. package/vendor/Archive/data/docs/experiences/loop-artifacts-verification-evidence-triangle.md +19 -0
  38. package/vendor/Archive/data/docs/experiences/macos-bash-replace-build-ps1.md +19 -0
  39. package/vendor/Archive/data/docs/experiences/macos-bsd-diff-q-illegal-option.md +15 -0
  40. package/vendor/Archive/data/docs/experiences/migrate-cjs-compatible-api-version-map-limit.md +17 -0
  41. package/vendor/Archive/data/docs/experiences/mp3agic-arkts-library-behavior-quirks.md +21 -0
  42. package/vendor/Archive/data/docs/experiences/ohos-face-detection-scan-api-mapping.md +15 -0
  43. package/vendor/Archive/data/docs/experiences/pr-metadata-and-diff-integrity-verification.md +12 -0
  44. package/vendor/Archive/data/docs/experiences/rn-coverage-index-signature-pseudo-member-false-negative.md +32 -0
  45. package/vendor/Archive/data/docs/experiences/rn-memory-check-severity-calibration.md +21 -0
  46. package/vendor/Archive/data/docs/experiences/rn-platform-specific-api-exclusion-evidence.md +24 -0
  47. package/vendor/Archive/data/docs/experiences/rn-upstream-version-diff-pitfalls.md +17 -0
  48. package/vendor/Archive/data/docs/experiences/rn-version-gap-risk-rating-rules.md +13 -0
  49. package/vendor/Archive/data/docs/experiences/rn-view-lib-native-contract-diff-fabric-spec.md +16 -0
  50. package/vendor/Archive/data/docs/experiences/rnoh-adapter-package-version-field-semantics.md +18 -0
  51. package/vendor/Archive/data/docs/experiences/rnoh-arkts-sqlite-rows-array-format.md +18 -0
  52. package/vendor/Archive/data/docs/experiences/rnoh-dependency-residue-scan-strategy.md +18 -0
  53. package/vendor/Archive/data/docs/experiences/rnoh-example-local-lib-dep-use-tgz.md +53 -0
  54. package/vendor/Archive/data/docs/experiences/rnoh-example-prereserve-rntesterlist.md +17 -0
  55. package/vendor/Archive/data/docs/experiences/rnoh-example-template-compatiblesdkversion-upgrade.md +29 -0
  56. package/vendor/Archive/data/docs/experiences/rnoh-example-turbomodule-shell-adaptation-checklist.md +41 -0
  57. package/vendor/Archive/data/docs/experiences/rnoh-mcp-build-project-tool-risk.md +18 -0
  58. package/vendor/Archive/data/docs/experiences/rnoh-npm-devdependencies-version-precheck.md +29 -0
  59. package/vendor/Archive/data/docs/experiences/rnoh-repo-baseline-version-verification.md +13 -0
  60. package/vendor/Archive/data/docs/experiences/rnoh-repo-upstream-directory-mapping.md +18 -0
  61. package/vendor/Archive/data/docs/experiences/rnoh-stateless-library-zero-leak-verification.md +31 -0
  62. package/vendor/Archive/data/docs/experiences/rnoh-template-npmrc-credential-removal.md +15 -0
  63. package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-codegen-wiring-verification.md +19 -0
  64. package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-cpp-methodmap-compatibility-check.md +20 -0
  65. package/vendor/Archive/data/docs/experiences/scenario-doc-vs-source-signature-diff-four-patterns.md +24 -0
  66. package/vendor/Archive/data/docs/experiences/static-analysis-grep-cross-validation.md +29 -0
  67. package/vendor/Archive/demo.js +489 -0
  68. package/vendor/Archive/index.js +43 -0
  69. package/vendor/Archive/package.json +16 -0
  70. package/vendor/Archive/src/constants.js +83 -0
  71. package/vendor/Archive/src/data/stopwords.txt +110 -0
  72. package/vendor/Archive/src/data/synonyms.json +25 -0
  73. package/vendor/Archive/src/data/terms.txt +59 -0
  74. package/vendor/Archive/src/db/sqlite-backend.js +312 -0
  75. package/vendor/Archive/src/db/sqlite-schema.js +64 -0
  76. package/vendor/Archive/src/engine.js +501 -0
  77. package/vendor/Archive/src/index/index-manager.js +203 -0
  78. package/vendor/Archive/src/index/index-state.js +94 -0
  79. package/vendor/Archive/src/index/search-text-builder.js +106 -0
  80. package/vendor/Archive/src/index.js +22 -0
  81. package/vendor/Archive/src/parser/api-identifiers.js +121 -0
  82. package/vendor/Archive/src/parser/api-suffixes.js +48 -0
  83. package/vendor/Archive/src/parser/heading-normalize.js +40 -0
  84. package/vendor/Archive/src/parser/markdown-splitter.js +215 -0
  85. package/vendor/Archive/src/search/catalog-routing.js +87 -0
  86. package/vendor/Archive/src/search/fts-search.js +289 -0
  87. package/vendor/Archive/src/search/query-normalizer.js +159 -0
  88. package/vendor/Archive/src/search/query-rewriter.js +72 -0
  89. package/vendor/Archive/src/search/search-engine.js +72 -0
  90. package/vendor/Archive/src/search/snippet.js +64 -0
  91. package/vendor/Archive/src/store/dir-store.js +103 -0
  92. package/vendor/Archive/src/store/doc-store.js +36 -0
  93. package/vendor/Archive/src/tokenizer/lexicon.js +151 -0
  94. package/vendor/Archive/src/tokenizer/tokenizer.js +167 -0
  95. package/vendor/Archive/src/types.js +86 -0
  96. package/vendor/Archive/src/utils/hash.js +16 -0
  97. package/vendor/Archive/src/utils/lock.js +73 -0
  98. package/vendor/Archive/src/utils/path-safety.js +96 -0
  99. package/vendor/Archive/src/utils/paths.js +39 -0
  100. package/vendor/BadCase/rn/INDEX.md +127 -0
  101. package/vendor/BadCase/rn/cases/KI-001-webview/350/247/206/351/242/221/346/227/240/346/263/225/346/250/252/345/261/217.md +52 -0
  102. package/vendor/BadCase/rn/cases/KI-002-fastImage/347/203/255/346/233/264/346/226/260/345/233/276/347/211/207/345/244/261/350/264/245.md +37 -0
  103. package/vendor/BadCase/rn/cases/KI-003-wechat/347/274/251/347/225/245/345/233/276/346/234/254/345/234/260/345/233/276/347/211/207.md +62 -0
  104. package/vendor/BadCase/rn/cases/KI-004-wechat/345/233/236/350/260/203/346/227/266/345/272/217.md +47 -0
  105. package/vendor/BadCase/rn/cases/KI-005-geolocation/345/257/274/345/205/245/350/267/257/345/276/204/345/220/216/347/274/200.md +31 -0
  106. package/vendor/BadCase/rn/cases/KI-006-SmartRefreshLayout/346/231/272/350/203/275/346/214/207/351/222/210/345/264/251/346/272/203.md +55 -0
  107. package/vendor/BadCase/rn/cases/KI-007-orientation-locker/344/274/240/346/204/237/345/231/250/345/210/235/345/247/213/345/214/226.md +58 -0
  108. package/vendor/BadCase/rn/cases/KI-008-orientation-locker/344/274/240/346/204/237/345/231/250/345/274/225/347/224/250/350/256/241/346/225/260.md +47 -0
  109. package/vendor/BadCase/rn/cases/KI-009-pager-view/345/265/214/345/245/227/346/273/221/345/212/250.md +38 -0
  110. package/vendor/BadCase/rn/cases/KI-010-screens/346/211/213/345/212/277/345/206/262/347/252/201.md +48 -0
  111. package/vendor/BadCase/rn/cases/KI-011-spring-scrollview/346/211/213/345/212/277/351/207/215/345/244/215/347/273/221/345/256/232.md +49 -0
  112. package/vendor/BadCase/rn/cases/KI-012-qr-camera/346/250/252/345/261/217/351/200/202/351/205/215.md +59 -0
  113. package/vendor/BadCase/rn/cases/KI-013-webview/346/267/261/350/211/262/346/250/241/345/274/217/350/203/214/346/231/257/350/211/262.md +37 -0
  114. package/vendor/BadCase/rn/cases/KI-014-amap-geolocation/345/233/236/350/260/203/347/274/272/345/244/261.md +42 -0
  115. package/vendor/BadCase/rn/cases/KI-015-reanimated/350/277/220/350/241/214/346/227/266/346/236/220/346/236/204/345/264/251/346/272/203.md +54 -0
  116. package/vendor/BadCase/rn/cases/KI-016-fs/346/226/207/344/273/266/350/257/273/345/217/226/347/274/226/347/240/201.md +58 -0
  117. package/vendor/BadCase/rn/cases/KI-017-blob-util/345/217/202/346/225/260/347/274/226/347/240/201/351/224/231/350/257/257.md +39 -0
  118. package/vendor/BadCase/rn/cases/KI-018-modal/345/274/271/347/252/227/351/227/252/347/203/201.md +53 -0
  119. package/vendor/BadCase/rn/cases/KI-019-code-push/351/207/215/345/220/257/351/200/273/350/276/221/345/244/261/346/225/210.md +79 -0
  120. package/vendor/BadCase/rn/cases/KI-020-netinfo/346/225/217/346/204/237/344/277/241/346/201/257/346/263/204/351/234/262.md +60 -0
  121. package/vendor/BadCase/rn/cases/KI-021-video/346/234/254/345/234/260/350/247/206/351/242/221/346/222/255/346/224/276/345/274/202/345/270/270.md +79 -0
  122. package/vendor/BadCase/rn/cases/KI-022-audio-recorder-player/346/236/232/344/270/276/347/274/272/345/244/261.md +38 -0
  123. package/vendor/BadCase/rn/cases/KI-023-svg/346/270/220/345/217/230/347/273/247/346/211/277/345/244/261/346/225/210.md +62 -0
  124. package/vendor/BadCase/rn/generalization-log.md +55 -0
  125. package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.json +328 -0
  126. package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.md +382 -0
  127. package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.json +1351 -0
  128. package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.md +1176 -0
  129. package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.json +538 -0
  130. package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.md +1488 -0
  131. package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.json +211 -0
  132. package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.md +35 -0
  133. package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.json +2048 -0
  134. package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.md +3866 -0
  135. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.json +198 -0
  136. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.md +40 -0
  137. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.json +751 -0
  138. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.md +883 -0
  139. package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.json +1544 -0
  140. package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.md +2598 -0
  141. package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.json +246 -0
  142. package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.md +554 -0
  143. package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.json +211 -0
  144. package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.md +54 -0
  145. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.json +1626 -0
  146. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.md +2213 -0
  147. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.json +208 -0
  148. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.md +77 -0
  149. package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.json +377 -0
  150. package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.md +174 -0
  151. package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.json +232 -0
  152. package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.md +194 -0
  153. package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.json +198 -0
  154. package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.md +67 -0
  155. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.json +198 -0
  156. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.md +38 -0
  157. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.json +208 -0
  158. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.md +34 -0
  159. package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.json +222 -0
  160. package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.md +56 -0
  161. package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.json +463 -0
  162. package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.md +383 -0
  163. package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.json +464 -0
  164. package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.md +565 -0
  165. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.json +198 -0
  166. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.md +47 -0
  167. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.json +232 -0
  168. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.md +422 -0
  169. package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.json +295 -0
  170. package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.md +1038 -0
  171. package/vendor/BadCase/rn/rules/R-01-/345/205/250/345/261/217/347/252/227/345/217/243/347/212/266/346/200/201/347/256/241/347/220/206/345/256/214/346/225/264/346/200/247.md +20 -0
  172. package/vendor/BadCase/rn/rules/R-02-/350/265/204/346/272/220URI/345/275/242/346/200/201/345/210/206/346/224/257/350/246/206/347/233/226.md +21 -0
  173. package/vendor/BadCase/rn/rules/R-03-/351/231/204/345/261/236/346/223/215/344/275/234/345/244/261/350/264/245/351/230/273/346/226/255/344/270/273/346/265/201/347/250/213.md +20 -0
  174. package/vendor/BadCase/rn/rules/R-04-/345/274/202/346/255/245/345/233/236/350/260/203/346/263/250/345/206/214/346/227/266/345/272/217.md +20 -0
  175. package/vendor/BadCase/rn/rules/R-05-/346/250/241/345/235/227/345/257/274/345/205/245/350/267/257/345/276/204/350/247/204/350/214/203.md +19 -0
  176. package/vendor/BadCase/rn/rules/R-06-/344/274/240/346/204/237/345/231/250/347/241/254/344/273/266/346/235/203/351/231/220/346/214/211/351/234/200/350/216/267/345/217/226.md +21 -0
  177. package/vendor/BadCase/rn/rules/R-07-/346/231/272/350/203/275/346/214/207/351/222/210/347/224/237/345/221/275/345/221/250/346/234/237/347/256/241/347/220/206.md +20 -0
  178. package/vendor/BadCase/rn/rules/R-08-/346/211/213/345/212/277/344/272/213/344/273/266/346/263/250/345/206/214/344/270/216/345/206/262/347/252/201/345/244/204/347/220/206.md +22 -0
  179. package/vendor/BadCase/rn/rules/R-09-/346/250/252/347/253/226/345/261/217/345/244/232/345/275/242/346/200/201/345/270/203/345/261/200/351/200/202/351/205/215.md +20 -0
  180. package/vendor/BadCase/rn/rules/R-10-/346/267/261/350/211/262/346/250/241/345/274/217/344/270/273/351/242/230/351/242/234/350/211/262/351/200/202/351/205/215.md +19 -0
  181. package/vendor/BadCase/rn/rules/R-11-/346/216/245/345/217/243/345/233/236/350/260/203/345/256/236/347/216/260/345/256/214/346/225/264/346/200/247.md +20 -0
  182. package/vendor/BadCase/rn/rules/R-12-/345/216/237/347/224/237/350/277/220/350/241/214/346/227/266/350/265/204/346/272/220/346/236/220/346/236/204/346/227/266/345/272/217.md +20 -0
  183. package/vendor/BadCase/rn/rules/R-13-/346/226/207/344/273/266/346/225/260/346/215/256/347/274/226/347/240/201/344/270/216/346/240/274/345/274/217/345/205/274/345/256/271.md +21 -0
  184. package/vendor/BadCase/rn/rules/R-14-/345/212/250/347/224/273/345/210/235/345/247/213/345/214/226/346/227/266/345/272/217/344/270/216/347/212/266/346/200/201/345/220/214/346/255/245.md +20 -0
  185. package/vendor/BadCase/rn/rules/R-15-/347/212/266/346/200/201/346/214/201/344/271/205/345/214/226/344/270/216/351/207/215/345/220/257/351/200/273/350/276/221/344/270/200/350/207/264/346/200/247.md +20 -0
  186. package/vendor/BadCase/rn/rules/R-16-/346/225/217/346/204/237/344/277/241/346/201/257/346/227/245/345/277/227/346/263/204/351/234/262.md +19 -0
  187. package/vendor/BadCase/rn/rules/R-17-/345/252/222/344/275/223/350/265/204/346/272/220/347/224/237/345/221/275/345/221/250/346/234/237/344/270/216/351/224/231/350/257/257/345/244/204/347/220/206.md +21 -0
  188. package/vendor/BadCase/rn/rules/R-18-/350/203/275/345/212/233/346/236/232/344/270/276/351/205/215/347/275/256/345/256/214/346/225/264/346/200/247.md +19 -0
  189. package/vendor/BadCase/rn/rules/R-19-/345/233/276/345/275/242/346/270/262/346/237/223/345/261/236/346/200/247/347/273/247/346/211/277/344/270/216/351/207/215/347/275/256.md +19 -0
  190. package/vendor/MCP/README.md +490 -0
  191. package/vendor/MCP/config.json +29 -0
  192. package/vendor/MCP/package.json +23 -0
  193. package/vendor/MCP/scripts/analyze-demo-coverage.cjs +1203 -0
  194. package/vendor/MCP/scripts/analyze-xts-coverage.cjs +1245 -0
  195. package/vendor/MCP/scripts/deveco_docs.js +247 -0
  196. package/vendor/MCP/scripts/extract-interfaces.cjs +1487 -0
  197. package/vendor/MCP/scripts/flutter-analyze-demo-coverage.cjs +666 -0
  198. package/vendor/MCP/scripts/flutter-analyze-xts-coverage.cjs +684 -0
  199. package/vendor/MCP/scripts/flutter-extract-interfaces.cjs +1251 -0
  200. package/vendor/MCP/scripts/flutter-render-spec-doc.cjs +351 -0
  201. package/vendor/MCP/scripts/render-spec-doc.cjs +347 -0
  202. package/vendor/MCP/scripts/rn-analyze-demo-coverage.cjs +645 -0
  203. package/vendor/MCP/scripts/rn-analyze-test-coverage.cjs +614 -0
  204. package/vendor/MCP/scripts/rn-extract-interfaces.cjs +1462 -0
  205. package/vendor/MCP/scripts/rn-render-spec-doc.cjs +327 -0
  206. package/vendor/MCP/scripts/rn-scan-exports.cjs +1336 -0
  207. package/vendor/MCP/src/client/MCPClientPool.js +220 -0
  208. package/vendor/MCP/src/config/ConfigLoader.js +189 -0
  209. package/vendor/MCP/src/executor/ScriptExecutor.js +110 -0
  210. package/vendor/MCP/src/gateway/Gateway.js +451 -0
  211. package/vendor/MCP/src/index.js +87 -0
  212. package/vendor/MCP/src/library/KBToolProvider.js +229 -0
  213. package/vendor/MCP/src/library/logger.js +60 -0
  214. package/vendor/MCP/src/registry/ScriptRegistry.js +238 -0
  215. package/vendor/MCP/src/registry/ToolRegistry.js +111 -0
  216. package/vendor/MCP/src/types.js +115 -0
  217. package/vendor/Server/CLI/cli.js +3 -3
  218. package/vendor/Server/Routes/server.js +3 -3
  219. package/vendor/Server/Skills/arkts-library-test-coverage-check/references/MCP_TOOL_USAGE.md +4 -2
  220. package/vendor/Server/Skills/arkts-library-xts-coverage/SKILL.md +3 -3
  221. package/vendor/Server/Skills/knowledge-import/SKILL.md +1 -1
  222. package/vendor/Server/Skills/knowledge-import/references/MCP_TOOL_USAGE.md +12 -4
  223. package/vendor/Server/Skills/ohos-lib-pr-push/SKILL.md +5 -4
  224. package/vendor/Server/Skills/rn-library-issue-generalizer/SKILL.md +2 -2
  225. package/vendor/Server/Skills/rn-library-known-issue-check/SKILL.md +2 -2
  226. package/vendor/Server/Skills/rnoh-lib-demo-coverage/SKILL.md +1 -2
  227. package/vendor/Server/Skills/rnoh-lib-test-align/references/port-test-demo-guide.md +1 -1
  228. package/vendor/Server/Skills/rnoh-lib-xts-coverage/SKILL.md +1 -2
  229. package/vendor/Server/package.json +5 -1
  230. package/vendor/VERSION +3 -3
@@ -0,0 +1,554 @@
1
+ # PR #20: fix:解决升级到rnoh新框架导致的打开modal闪屏问题及更新readme文档
2
+
3
+ - **状态**: merged
4
+ - **作者**: cuijiaojiao1
5
+ - **创建时间**: 2026-07-09T16:50:08+08:00
6
+ - **分支**: 77Visible → br_rnoh0.72
7
+ - **变更文件数**: 3
8
+
9
+ ## PR 描述
10
+
11
+ fix:解决升级到rnoh新框架导致的打开modal闪屏问题 [#14](https://gitcode.com/CPF-RN/rntpc_react-native-modal/issues/14)
12
+
13
+ ## 变更文件
14
+
15
+ | 文件 | 变更 | +行 | -行 |
16
+ |------|------|-----|-----|
17
+ | `README.md` | ? | +16 | -13 |
18
+ | `README_en.md` | ? | +15 | -12 |
19
+ | `src/modal.tsx` | ? | +192 | -85 |
20
+
21
+ ## Diff
22
+
23
+ ### `README.md`
24
+
25
+ ```diff
26
+ @@ -8,10 +8,11 @@
27
+
28
+ 该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:`@react-native-ohos/react-native-modal` 版本所属关系如下:
29
+
30
+ -| 三方库名称 | 三方库版本 | 发布信息 | 支持 RN 版本 | Autolink | 编译 API 版本 | 社区基线版本 | npm 地址 |
31
+ -| --------------------------------------- | ---------- | ------------------------------------------------------------------------------------------ | --------------- | -------- | ------------- | ------------ | ------------------------------------------------------------------------------------ |
32
+ -| @react-native-ohos/react-native-modal | ~ 14.0.1 | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.77.\*/0.82.\* | 否 | API12+ | 14.0.0-rc.1 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-modal) |
33
+ -| @react-native-oh-tpl/react-native-modal | ~ 13.0.1 | [Gitcode Releases](https://github.com/react-native-oh-library/react-native-modal/releases) | 0.72.\* | 否 | API12+ | 13.0.1 | [Npm Address](https://www.npmjs.com/package/@react-native-oh-tpl/react-native-modal) |
34
+ +| 三方库名称 | 三方库版本 | 发布信息 | 支持 RN 版本 | Autolink | 编译 API 版本 | 社区基线版本 | npm 地址 |
35
+ +| --------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------- | --------------- | -------- | ------------- | ------------ | ------------------------------------------------------------------------------------ |
36
+ +| @react-native-ohos/react-native-modal | ~ 14.0.1 | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.77.\*/0.82.\* | 否 | API12+ | 14.0.0-rc.1 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-modal) |
37
+ +| @react-native-ohos/react-native-modal | ~ 13.0.2 | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.72.\* | 否 | API12+ | 13.0.1 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-modal) |
38
+ +| @react-native-oh-tpl/react-native-modal | ~ 13.0.1@deprecated | [Github Releases](https://github.com/react-native-oh-library/react-native-modal/releases) | 0.72.\* | 否 | API12+ | 13.0.1 | [Npm Address](https://www.npmjs.com/package/@react-native-oh-tpl/react-native-modal) |
39
+
40
+ ## 1. 安装与使用
41
+
42
+ @@ -132,21 +133,23 @@ export default DefaultModal;
43
+
44
+ ## 2. Link
45
+
46
+ -| | 是否支持 autolink | RN 框架版本 |
47
+ -| ------- | ----------------- | ----------- |
48
+ -| ~14.0.1 | No | 0.77/0.82 |
49
+ -| ~13.0.1 | No | 0.72 |
50
+ +| | 是否支持 autolink | RN 框架版本 |
51
+ +| ------------------ | ----------------- | ----------- |
52
+ +| ~14.0.1 | 否 | 0.77/0.82 |
53
+ +| ~13.0.2 | 否 | 0.72 |
54
+ +| ~13.0.1@deprecated | 否 | 0.72 |
55
+
56
+ ## 3. 约束与限制
57
+
58
+ -### 3.1. 兼容性
59
+ +### 3.1 兼容性
60
+
61
+ 请到三方库相应的 Releases 发布地址查看 Release 配套的版本信息:
62
+
63
+ -| 三方库版本 | 发布信息 | 支持 RN 版本 |
64
+ -| ---------- | -------------------------------------------------------------------------------------------------------------------------- | ------------ |
65
+ -| 14.0.1 | [@react-native-ohos/react-native-modal Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.77/0.82 |
66
+ -| 13.0.1 | [@react-native-oh-tpl/react-native-modal Releases](https://github.com/react-native-oh-library/react-native-modal/releases) | 0.72 |
67
+ +| 三方库版本 | 发布信息 | 支持 RN 版本 |
68
+ +| ----------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------ |
69
+ +| 14.0.1 | [@react-native-ohos/react-native-modal Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.77/0.82 |
70
+ +| 13.0.2 | [@react-native-ohos/react-native-modal Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.72 |
71
+ +| 13.0.1@deprecated | [@react-native-oh-tpl/react-native-modal Releases](https://github.com/react-native-oh-library/react-native-modal/releases) | 0.72 |
72
+
73
+ ## 4. 属性
74
+
75
+
76
+ ```
77
+
78
+ ### `README_en.md`
79
+
80
+ ```diff
81
+ @@ -8,10 +8,11 @@ This project is based on [react-native-modal](https://github.com/react-native-mo
82
+
83
+ This third-party library has been migrated to Gitcode and is now available for direct download from npm, the new package name is: `@react-native-ohos/react-native-modal`, The version correspondence details are as follows:
84
+
85
+ -| Name | Version | Release Information | Supported RN Version | Supported Autolink | Compile API Version | Community Baseline Version | npm Address |
86
+ -| --------------------------------------- | -------- | ------------------------------------------------------------------------------------------ | -------------------- | ------------------ | ------------------- | -------------------------- | ------------------------------------------------------------------------------------ |
87
+ -| @react-native-ohos/react-native-modal | ~ 14.0.1 | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.77.\*/0.82.\* | No | API12+ | 14.0.0-rc.1 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-modal) |
88
+ -| @react-native-oh-tpl/react-native-modal | ~ 13.0.1 | [Gitcode Releases](https://github.com/react-native-oh-library/react-native-modal/releases) | 0.72.\* | No | API12+ | 13.0.1 | [Npm Address](https://www.npmjs.com/package/@react-native-oh-tpl/react-native-modal) |
89
+ +| Name | Version | Release Information | Supported RN Version | Supported Autolink | Compile API Version | Community Baseline Version | npm Address |
90
+ +| --------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------- | -------------------- | ------------------ | ------------------- | -------------------------- | ------------------------------------------------------------------------------------ |
91
+ +| @react-native-ohos/react-native-modal | ~ 14.0.1 | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.77.\*/0.82.\* | No | API12+ | 14.0.0-rc.1 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-modal) |
92
+ +| @react-native-ohos/react-native-modal | ~ 13.0.2 | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.72.\* | No | API12+ | 13.0.1 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-modal) |
93
+ +| @react-native-oh-tpl/react-native-modal | ~ 13.0.1@deprecated | [Github Releases](https://github.com/react-native-oh-library/react-native-modal/releases) | 0.72.\* | No | API12+ | 13.0.1 | [Npm Address](https://www.npmjs.com/package/@react-native-oh-tpl/react-native-modal) |
94
+
95
+ ## 1. Installation and Usage
96
+
97
+ @@ -132,10 +133,11 @@ export default DefaultModal;
98
+
99
+ ## 2. Link
100
+
101
+ -| | Supported Autolink | Supported RN Version |
102
+ -| ------- | ------------------ | -------------------- |
103
+ -| ~14.0.1 | No | 0.77/0.82 |
104
+ -| ~13.0.1 | No | 0.72 |
105
+ +| | Supported Autolink | Supported RN Version |
106
+ +| ------------------ | ------------------ | -------------------- |
107
+ +| ~14.0.1 | No | 0.77/0.82 |
108
+ +| ~13.0.2 | No | 0.72 |
109
+ +| ~13.0.1@deprecated | No | 0.72 |
110
+
111
+ ## 3. Constraints
112
+
113
+ @@ -143,10 +145,11 @@ export default DefaultModal;
114
+
115
+ Check the release version information in the release address of the third-party library:
116
+
117
+ -| Version | Release Information | Supported RN Version |
118
+ -| ------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------- |
119
+ -| 14.0.1 | [@react-native-ohos/react-native-modal Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.77/0.82 |
120
+ -| 13.0.1 | [@react-native-oh-tpl/react-native-modal Releases](https://github.com/react-native-oh-library/react-native-modal/releases) | 0.72 |
121
+ +| Version | Release Information | Supported RN Version |
122
+ +| ----------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------- |
123
+ +| 14.0.1 | [@react-native-ohos/react-native-modal Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.77/0.82 |
124
+ +| 13.0.2 | [@react-native-ohos/react-native-modal Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-modal/releases) | 0.72 |
125
+ +| 13.0.1@deprecated | [@react-native-oh-tpl/react-native-modal Releases](https://github.com/react-native-oh-library/react-native-modal/releases) | 0.72 |
126
+
127
+ ## 4. Properties
128
+
129
+
130
+ ```
131
+
132
+ ### `src/modal.tsx`
133
+
134
+ ```diff
135
+ @@ -52,6 +52,7 @@ type State = {
136
+ deviceHeight: number;
137
+ isSwipeable: boolean;
138
+ pan: OrNull<Animated.ValueXY>;
139
+ + animationReady: boolean;
140
+ };
141
+
142
+ const defaultProps = {
143
+ @@ -192,6 +193,7 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
144
+ deviceHeight: Dimensions.get('window').height,
145
+ isSwipeable: !!this.props.swipeDirection,
146
+ pan: null,
147
+ + animationReady: false,
148
+ };
149
+
150
+ isTransitioning = false;
151
+ @@ -200,12 +202,15 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
152
+
153
+ animationIn: string;
154
+ animationOut: string;
155
+ + backdropAnimated: Animated.Value;
156
+ backdropRef: any;
157
+ contentRef: any;
158
+ panResponder: OrNull<PanResponderInstance> = null;
159
+ didUpdateDimensionsEmitter: OrNull<EmitterSubscription> = null;
160
+
161
+ interactionHandle: OrNull<number> = null;
162
+ + _pendingRAF: number[] = [];
163
+ + _pendingTimeout: number[] = [];
164
+
165
+ constructor(props: ModalProps) {
166
+ super(props);
167
+ @@ -215,7 +220,7 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
168
+
169
+ this.animationIn = animationIn;
170
+ this.animationOut = animationOut;
171
+ -
172
+ + this.backdropAnimated = new Animated.Value(0);
173
+ if (this.state.isSwipeable) {
174
+ this.state = {
175
+ ...this.state,
176
+ @@ -227,14 +232,18 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
177
+ this.state = {
178
+ ...this.state,
179
+ isVisible: true,
180
+ - showContent: true,
181
+ + showContent: false,
182
+ + animationReady: false,
183
+ };
184
+ }
185
+ }
186
+
187
+ - static getDerivedStateFromProps(nextProps: Readonly<ModalProps>, state: State) {
188
+ + static getDerivedStateFromProps(
189
+ + nextProps: Readonly<ModalProps>,
190
+ + state: State,
191
+ + ) {
192
+ if (!state.isVisible && nextProps.isVisible) {
193
+ - return { isVisible: true, showContent: true };
194
+ + return { isVisible: true, showContent: false, animationReady: false};
195
+ }
196
+ return null;
197
+ }
198
+ @@ -267,8 +276,17 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
199
+ InteractionManager.clearInteractionHandle(this.interactionHandle);
200
+ this.interactionHandle = null;
201
+ }
202
+ + // Cancel any pending requestAnimationFrame callbacks
203
+ + this._pendingRAF.forEach(id => cancelAnimationFrame(id));
204
+ + this._pendingRAF = [];
205
+ + // Cancel any pending setTimeout callbacks
206
+ + this._pendingTimeout.forEach(id => clearTimeout(id));
207
+ + this._pendingTimeout = [];
208
+ + // Stop any running backdrop animation
209
+ + if (this.backdropAnimated && this.backdropAnimated.stopAnimation) {
210
+ + this.backdropAnimated.stopAnimation();
211
+ + }
212
+ }
213
+ -
214
+ componentDidUpdate(prevProps: ModalProps) {
215
+ // If the animations have been changed then rebuild them to make sure we're
216
+ // using the most up-to-date ones
217
+ @@ -282,15 +300,13 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
218
+ this.animationIn = animationIn;
219
+ this.animationOut = animationOut;
220
+ }
221
+ - // If backdrop opacity has been changed then make sure to update it
222
+ - if (
223
+ - this.props.backdropOpacity !== prevProps.backdropOpacity &&
224
+ - this.backdropRef
225
+ - ) {
226
+ - this.backdropRef.transitionTo(
227
+ - { opacity: this.props.backdropOpacity },
228
+ - this.props.backdropTransitionInTiming,
229
+ - );
230
+ + // If backdrop opacity has been changed then animate the Animated.Value
231
+ + if (this.props.backdropOpacity !== prevProps.backdropOpacity) {
232
+ + Animated.timing(this.backdropAnimated, {
233
+ + toValue: this.props.backdropOpacity,
234
+ + duration: this.props.backdropTransitionInTiming,
235
+ + useNativeDriver: this.props.useNativeDriverForBackdrop === true,
236
+ + }).start();
237
+ }
238
+ // On modal open request, we slide the view up and fade in the backdrop
239
+ if (this.props.isVisible && !prevProps.isVisible) {
240
+ @@ -387,11 +403,13 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
241
+ // Dim the background while swiping the modal
242
+ const newOpacityFactor =
243
+ 1 - this.calcDistancePercentage(gestureState);
244
+ -
245
+ - this.backdropRef &&
246
+ - this.backdropRef.transitionTo({
247
+ - opacity: this.props.backdropOpacity * newOpacityFactor,
248
+ - });
249
+ + // Update backdrop opacity immediately during swipe.
250
+ + // setValue() is synchronous and works regardless of useNativeDriver
251
+ + // setting — it directly sets the Animated.Value without scheduling
252
+ + // an animation, so there is no conflict with native-driven animations.
253
+ + this.backdropAnimated.setValue(
254
+ + this.props.backdropOpacity * newOpacityFactor,
255
+ + );
256
+
257
+ animEvt!(evt, gestureState);
258
+
259
+ @@ -447,12 +465,12 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
260
+ if (this.props.onSwipeCancel) {
261
+ this.props.onSwipeCancel(gestureState);
262
+ }
263
+ -
264
+ - if (this.backdropRef) {
265
+ - this.backdropRef.transitionTo({
266
+ - opacity: this.props.backdropOpacity,
267
+ - });
268
+ - }
269
+ + // Reset backdrop opacity with a smooth animation
270
+ + Animated.timing(this.backdropAnimated, {
271
+ + toValue: this.props.backdropOpacity,
272
+ + duration: this.props.backdropTransitionInTiming,
273
+ + useNativeDriver: this.props.useNativeDriverForBackdrop === true,
274
+ + }).start();
275
+
276
+ Animated.spring(this.state.pan!, {
277
+ toValue: { x: 0, y: 0 },
278
+ @@ -593,13 +611,19 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
279
+ return;
280
+ }
281
+ this.isTransitioning = true;
282
+ - if (this.backdropRef) {
283
+ - this.backdropRef.transitionTo(
284
+ - { opacity: this.props.backdropOpacity },
285
+ - this.props.backdropTransitionInTiming,
286
+ - );
287
+ + // Mark content as not ready for display until the animation is
288
+ + // properly set up. This prevents the one-frame flash where
289
+ + // setAnimation creates an animationStyle interpolated from a stale
290
+ + // animationValue (e.g. 1.0 from a previous animation), causing the
291
+ + // content to appear at its final position for one frame before
292
+ + // startAnimation resets animationValue to 0.
293
+ + this.setState({animationReady: false});
294
+ + if (this.backdropAnimated && this.backdropAnimated.stopAnimation) {
295
+ + this.backdropAnimated.stopAnimation();
296
+ + }
297
+ + if (this.backdropAnimated && this.backdropAnimated.setValue) {
298
+ + this.backdropAnimated.setValue(0);
299
+ }
300
+ -
301
+ // This is for resetting the pan position,otherwise the modal gets stuck
302
+ // at the last released position when you try to open it.
303
+ // TODO: Could certainly be improved - no idea for the moment.
304
+ @@ -612,20 +636,64 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
305
+ if (this.interactionHandle == null) {
306
+ this.interactionHandle = InteractionManager.createInteractionHandle();
307
+ }
308
+ - this.contentRef
309
+ - .animate(this.animationIn, this.props.animationInTiming)
310
+ - .then(() => {
311
+ - this.isTransitioning = false;
312
+ - if (this.interactionHandle) {
313
+ - InteractionManager.clearInteractionHandle(this.interactionHandle);
314
+ - this.interactionHandle = null;
315
+ - }
316
+ - if (!this.props.isVisible) {
317
+ - this.close();
318
+ - } else {
319
+ - this.props.onModalShow();
320
+ - }
321
+ + // Stop any running animation first, then reset animationValue to 0
322
+ + // before setAnimation. This prevents a visual glitch where setAnimation
323
+ + // uses the current animationValue (e.g. 1.0 from a previous animation)
324
+ + // to compute animationStyle, causing a one-frame flash at the wrong position.
325
+ + // After stopAnimation, animationStyle is cleared so content is at its
326
+ + // default position. Setting animationValue to 0 won't cause a visual jump
327
+ + // since there's no active animationStyle to interpolate.
328
+ + this.contentRef.stopAnimation();
329
+ + if (this.contentRef.state && this.contentRef.state.animationValue) {
330
+ + this.contentRef.state.animationValue.setValue(0);
331
+ + }
332
+ + const rafId1 = requestAnimationFrame(() => {
333
+ + // Guard: if the component was unmounted or closed before the
334
+ + // deferred frame fired, skip animation startup entirely.
335
+ + if (!this.contentRef || !this.isTransitioning) {
336
+ + return;
337
+ + }
338
+ + this.contentRef.setAnimation(this.animationIn, () => {
339
+ + // setAnimation has now set animationStyle via setState.→native
340
+ + // first open when the Modal window is being created.
341
+ + this.contentRef.startAnimation(
342
+ + this.props.animationInTiming,
343
+ + 0,
344
+ + 0,
345
+ + () => {
346
+ + this.isTransitioning = false;
347
+ + if (this.interactionHandle) {
348
+ + InteractionManager.clearInteractionHandle(
349
+ + this.interactionHandle,
350
+ + );
351
+ + this.interactionHandle = null;
352
+ + }
353
+ + if (!this.props.isVisible) {
354
+ + this.close();
355
+ + } else {
356
+ + this.props.onModalShow();
357
+ + }
358
+ + },
359
+ + );
360
+ + // Start backdrop fade-in in the same JS tick as content animation.
361
+ + // Animated.timing().start() is synchronous in scheduling — it
362
+ + // enqueues the animation immediately, ensuring backdrop and content
363
+ + // begin on the same frame.
364
+ + Animated.timing(this.backdropAnimated, {
365
+ + toValue: this.props.backdropOpacity,
366
+ + duration: this.props.backdropTransitionInTiming,
367
+ + useNativeDriver: this.props.useNativeDriverForBackdrop === true,
368
+ + }).start();
369
+ + const rafId2 = requestAnimationFrame(() => {
370
+ + if (!this.isTransitioning && !this.state.isVisible) {
371
+ + return;
372
+ + }
373
+ + this.setState({showContent: true, animationReady: true});
374
+ + });
375
+ + this._pendingRAF.push(rafId2);
376
+ });
377
+ + });
378
+ + this._pendingRAF.push(rafId1);
379
+ }
380
+ };
381
+
382
+ @@ -634,12 +702,6 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
383
+ return;
384
+ }
385
+ this.isTransitioning = true;
386
+ - if (this.backdropRef) {
387
+ - this.backdropRef.transitionTo(
388
+ - { opacity: 0 },
389
+ - this.props.backdropTransitionOutTiming,
390
+ - );
391
+ - }
392
+
393
+ let animationOut = this.animationOut;
394
+
395
+ @@ -661,34 +723,80 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
396
+ if (this.interactionHandle == null) {
397
+ this.interactionHandle = InteractionManager.createInteractionHandle();
398
+ }
399
+ - this.contentRef
400
+ - .animate(animationOut, this.props.animationOutTiming)
401
+ - .then(() => {
402
+ - this.isTransitioning = false;
403
+ - if (this.interactionHandle) {
404
+ - InteractionManager.clearInteractionHandle(this.interactionHandle);
405
+ - this.interactionHandle = null;
406
+ + // Stop any running animation first, then reset animationValue to 0
407
+ + // before setAnimation. This prevents a visual glitch where setAnimation
408
+ + // uses the current animationValue (e.g. 1.0 from the entrance animation)
409
+ + // to compute the exit animationStyle, causing a one-frame flash.
410
+ + // After stopAnimation, animationStyle is cleared so content is at its
411
+ + // default position. Setting animationValue to 0 won't cause a visual jump
412
+ + // since there's no active animationStyle to interpolate.
413
+ + this.contentRef.stopAnimation();
414
+ + if (this.contentRef.state && this.contentRef.state.animationValue) {
415
+ + this.contentRef.state.animationValue.setValue(0);
416
+ + }
417
+ + this.contentRef.setAnimation(animationOut, () => {
418
+ + // setAnimation has set the exit animationStyle with
419
+ + // animationValue=0, which corresponds to the "from" position
420
+ + // of the exit animation (e.g. translateY:0 for slideOutDown,
421
+ + // meaning the content is at its normal visible position).
422
+ + // This is correct — the content should start at its current
423
+ + // position and animate out. No need to hide content during
424
+ + // close since the animationStyle is already correct.
425
+ + if (this.backdropRef) {
426
+ + if (this.backdropAnimated && this.backdropAnimated.stopAnimation) {
427
+ + this.backdropAnimated.stopAnimation();
428
+ }
429
+ - if (this.props.isVisible) {
430
+ - this.open();
431
+ - } else {
432
+ - this.setState(
433
+ - {
434
+ - showContent: false,
435
+ - },
436
+ - () => {
437
+ + // Start backdrop fade-out in the same JS tick as content animation.
438
+ + // Animated.timing().start() schedules immediately, keeping backdrop
439
+ + // and content exit animations in sync without relying on animatable's
440
+ + // internal state (transitionTo goes through setState which is async).
441
+ + Animated.timing(this.backdropAnimated, {
442
+ + toValue: 0,
443
+ + duration: this.props.backdropTransitionOutTiming,
444
+ + useNativeDriver: this.props.useNativeDriverForBackdrop === true,
445
+ + }).start();
446
+ + }
447
+ + this.contentRef.startAnimation(
448
+ + this.props.animationOutTiming,
449
+ + 0,
450
+ + 0,
451
+ + () => {
452
+ + const finalizeClose = () => {
453
+ + this.isTransitioning = false;
454
+ + if (this.interactionHandle) {
455
+ + InteractionManager.clearInteractionHandle(
456
+ + this.interactionHandle,
457
+ + );
458
+ + this.interactionHandle = null;
459
+ + }
460
+ + if (this.props.isVisible) {
461
+ + this.open();
462
+ + } else {
463
+ this.setState(
464
+ {
465
+ + showContent: false,
466
+ isVisible: false,
467
+ + animationReady: false,
468
+ },
469
+ () => {
470
+ this.props.onModalHide();
471
+ },
472
+ );
473
+ - },
474
+ - );
475
+ - }
476
+ - });
477
+ + }
478
+ + };
479
+ + // The startAnimation callback fires when the JS-side
480
+ + // Animated.timing completes. On Harmony/OpenHarmony,
481
+ + // the native rendering pipeline may still be processing
482
+ + // the final frame. Use a small delay to ensure the last
483
+ + // frame of the exit animation has been painted before
484
+ + // removing the modal from the view hierarchy, preventing
485
+ + // a flash where the modal content briefly reappears at
486
+ + // its default (un-animated) position.
487
+ + const timeoutId = setTimeout(finalizeClose, 32);
488
+ + this._pendingTimeout.push(timeoutId);
489
+ + },
490
+ + );
491
+ + });
492
+ }
493
+ };
494
+ makeBackdrop = () => {
495
+ @@ -717,23 +825,22 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
496
+ width: this.getDeviceWidth(),
497
+ height: this.getDeviceHeight(),
498
+ backgroundColor:
499
+ - this.state.showContent && !hasCustomBackdrop
500
+ + (this.props.isVisible || this.state.isVisible) && !hasCustomBackdrop
501
+ ? backdropColor
502
+ : 'transparent',
503
+ },
504
+ ];
505
+
506
+ const backdropWrapper = (
507
+ - <animatable.View
508
+ - ref={ref => (this.backdropRef = ref)}
509
+ - useNativeDriver={
510
+ - useNativeDriverForBackdrop !== undefined
511
+ - ? useNativeDriverForBackdrop
512
+ - : useNativeDriver
513
+ - }
514
+ - style={[styles.backdrop, backdropComputedStyle]}>
515
+ + <Animated.View
516
+ + ref={(ref: any) => (this.backdropRef = ref)}
517
+ + style={[
518
+ + styles.backdrop,
519
+ + backdropComputedStyle,
520
+ + {opacity: this.backdropAnimated},
521
+ + ]}>
522
+ {hasCustomBackdrop && customBackdrop}
523
+ - </animatable.View>
524
+ + </Animated.View>
525
+ );
526
+
527
+ if (hasCustomBackdrop) {
528
+ @@ -796,18 +903,18 @@ export class ReactNativeModal extends React.Component<ModalProps, State> {
529
+
530
+ // The user might decide not to show the modal while it is animating
531
+ // to enhance performance.
532
+ - const _children =
533
+ - this.props.hideModalContentWhileAnimating &&
534
+ - this.props.useNativeDriver &&
535
+ - !this.state.showContent ? (
536
+ - <animatable.View />
537
+ + const shouldHideContent =
538
+ + !this.state.showContent ||
539
+ + (this.isTransitioning && !this.state.animationReady);
540
+ + const _children = shouldHideContent ? (
541
+ + <animatable.View style={{opacity: 0}} />
542
+ ) : (
543
+ children
544
+ );
545
+ const containerView = (
546
+ <animatable.View
547
+ {...panHandlers}
548
+ - ref={ref => (this.contentRef = ref)}
549
+ + ref={(ref: any) => (this.contentRef = ref)}
550
+ style={[panPosition, computedStyle]}
551
+ pointerEvents="box-none"
552
+ useNativeDriver={useNativeDriver}
553
+
554
+ ```