react-native-tvos 0.69.6-3 → 0.69.8-0
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/Libraries/Components/TV/TVFocusGuideView.js +74 -61
- package/Libraries/Components/View/View.js +36 -2
- package/Libraries/Components/View/ViewNativeComponent.js +9 -3
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Lists/VirtualizedList.js +25 -10
- package/README.md +2 -1
- package/React/Base/RCTRootView.m +6 -0
- package/React/Base/RCTRootViewInternal.h +1 -0
- package/React/Base/RCTVersion.m +2 -2
- package/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.h +1 -0
- package/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.mm +6 -0
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +88 -29
- package/React/Views/RCTTVView.h +8 -1
- package/React/Views/RCTTVView.m +79 -7
- package/React/Views/RCTViewManager.m +13 -1
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +7 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/core/ReactAndroidHWInputDeviceHelper.java +44 -14
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +25 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +62 -11
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java +45 -4
- package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
- package/ReactCommon/react/renderer/components/view/ViewProps.cpp +80 -16
- package/ReactCommon/react/renderer/components/view/ViewProps.h +8 -0
- package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-debug-javadoc.jar → 0.69.8-0/hermes-engine-0.69.8-0-debug-javadoc.jar} +0 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug-javadoc.jar.md5 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug-javadoc.jar.sha1 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug-javadoc.jar.sha256 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug-javadoc.jar.sha512 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug.aar +0 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug.aar.md5 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug.aar.sha1 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug.aar.sha256 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-debug.aar.sha512 +1 -0
- package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-release-javadoc.jar → 0.69.8-0/hermes-engine-0.69.8-0-release-javadoc.jar} +0 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release-javadoc.jar.md5 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release-javadoc.jar.sha1 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release-javadoc.jar.sha256 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release-javadoc.jar.sha512 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release.aar +0 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release.aar.md5 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release.aar.sha1 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release.aar.sha256 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0-release.aar.sha512 +1 -0
- package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3.module → 0.69.8-0/hermes-engine-0.69.8-0.module} +47 -47
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0.module.md5 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0.module.sha1 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0.module.sha256 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0.module.sha512 +1 -0
- package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3.pom → 0.69.8-0/hermes-engine-0.69.8-0.pom} +1 -1
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0.pom.md5 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0.pom.sha1 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0.pom.sha256 +1 -0
- package/android/com/facebook/react/hermes-engine/0.69.8-0/hermes-engine-0.69.8-0.pom.sha512 +1 -0
- package/android/com/facebook/react/hermes-engine/maven-metadata.xml +4 -4
- package/android/com/facebook/react/hermes-engine/maven-metadata.xml.md5 +1 -1
- package/android/com/facebook/react/hermes-engine/maven-metadata.xml.sha1 +1 -1
- package/android/com/facebook/react/hermes-engine/maven-metadata.xml.sha256 +1 -1
- package/android/com/facebook/react/hermes-engine/maven-metadata.xml.sha512 +1 -1
- package/android/com/facebook/react/react-native/{0.69.6-3/react-native-0.69.6-3-release-javadoc.jar → 0.69.8-0/react-native-0.69.8-0-debug-javadoc.jar} +0 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug-javadoc.jar.md5 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug-javadoc.jar.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug-javadoc.jar.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug-javadoc.jar.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.69.6-3/react-native-0.69.6-3-debug-sources.jar → 0.69.8-0/react-native-0.69.8-0-debug-sources.jar} +0 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug-sources.jar.md5 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug-sources.jar.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug-sources.jar.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug-sources.jar.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.69.6-3/react-native-0.69.6-3-debug.aar → 0.69.8-0/react-native-0.69.8-0-debug.aar} +0 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug.aar.md5 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug.aar.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug.aar.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-debug.aar.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.69.6-3/react-native-0.69.6-3-debug-javadoc.jar → 0.69.8-0/react-native-0.69.8-0-release-javadoc.jar} +0 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release-javadoc.jar.md5 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release-javadoc.jar.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release-javadoc.jar.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release-javadoc.jar.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.69.6-3/react-native-0.69.6-3-release-sources.jar → 0.69.8-0/react-native-0.69.8-0-release-sources.jar} +0 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release-sources.jar.md5 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release-sources.jar.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release-sources.jar.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release-sources.jar.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.69.6-3/react-native-0.69.6-3-release.aar → 0.69.8-0/react-native-0.69.8-0-release.aar} +0 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release.aar.md5 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release.aar.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release.aar.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0-release.aar.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.69.6-3/react-native-0.69.6-3.module → 0.69.8-0/react-native-0.69.8-0.module} +57 -57
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0.module.md5 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0.module.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0.module.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0.module.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.69.6-3/react-native-0.69.6-3.pom → 0.69.8-0/react-native-0.69.8-0.pom} +1 -1
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0.pom.md5 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0.pom.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0.pom.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.69.8-0/react-native-0.69.8-0.pom.sha512 +1 -0
- package/android/com/facebook/react/react-native/maven-metadata.xml +4 -4
- package/android/com/facebook/react/react-native/maven-metadata.xml.md5 +1 -1
- package/android/com/facebook/react/react-native/maven-metadata.xml.sha1 +1 -1
- package/android/com/facebook/react/react-native/maven-metadata.xml.sha256 +1 -1
- package/android/com/facebook/react/react-native/maven-metadata.xml.sha512 +1 -1
- package/package.json +2 -2
- package/sdks/hermesc/linux64-bin/hermesc +0 -0
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/template/package.json +1 -1
- package/tvos-types.d.ts +32 -5
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug-javadoc.jar.md5 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug-javadoc.jar.sha1 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug-javadoc.jar.sha256 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug-javadoc.jar.sha512 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug.aar +0 -0
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug.aar.md5 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug.aar.sha1 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug.aar.sha256 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-debug.aar.sha512 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release-javadoc.jar.md5 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release-javadoc.jar.sha1 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release-javadoc.jar.sha256 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release-javadoc.jar.sha512 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release.aar +0 -0
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release.aar.md5 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release.aar.sha1 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release.aar.sha256 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3-release.aar.sha512 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3.module.md5 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3.module.sha1 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3.module.sha256 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3.module.sha512 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3.pom.md5 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3.pom.sha1 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3.pom.sha256 +0 -1
- package/android/com/facebook/react/hermes-engine/0.69.6-3/hermes-engine-0.69.6-3.pom.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug-javadoc.jar.md5 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug-javadoc.jar.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug-javadoc.jar.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug-javadoc.jar.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug-sources.jar.md5 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug-sources.jar.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug-sources.jar.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug-sources.jar.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug.aar.md5 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug.aar.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug.aar.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-debug.aar.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release-javadoc.jar.md5 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release-javadoc.jar.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release-javadoc.jar.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release-javadoc.jar.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release-sources.jar.md5 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release-sources.jar.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release-sources.jar.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release-sources.jar.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release.aar.md5 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release.aar.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release.aar.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3-release.aar.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3.module.md5 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3.module.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3.module.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3.module.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3.pom.md5 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3.pom.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3.pom.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.69.6-3/react-native-0.69.6-3.pom.sha512 +0 -1
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-debug-sources.jar → 0.69.8-0/hermes-engine-0.69.8-0-debug-sources.jar} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-debug-sources.jar.md5 → 0.69.8-0/hermes-engine-0.69.8-0-debug-sources.jar.md5} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-debug-sources.jar.sha1 → 0.69.8-0/hermes-engine-0.69.8-0-debug-sources.jar.sha1} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-debug-sources.jar.sha256 → 0.69.8-0/hermes-engine-0.69.8-0-debug-sources.jar.sha256} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-debug-sources.jar.sha512 → 0.69.8-0/hermes-engine-0.69.8-0-debug-sources.jar.sha512} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-release-sources.jar → 0.69.8-0/hermes-engine-0.69.8-0-release-sources.jar} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-release-sources.jar.md5 → 0.69.8-0/hermes-engine-0.69.8-0-release-sources.jar.md5} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-release-sources.jar.sha1 → 0.69.8-0/hermes-engine-0.69.8-0-release-sources.jar.sha1} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-release-sources.jar.sha256 → 0.69.8-0/hermes-engine-0.69.8-0-release-sources.jar.sha256} +0 -0
- /package/android/com/facebook/react/hermes-engine/{0.69.6-3/hermes-engine-0.69.6-3-release-sources.jar.sha512 → 0.69.8-0/hermes-engine-0.69.8-0-release-sources.jar.sha512} +0 -0
package/React/Views/RCTTVView.m
CHANGED
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
__weak RCTBridge *_bridge;
|
|
24
24
|
UITapGestureRecognizer *_selectRecognizer;
|
|
25
25
|
BOOL motionEffectsAdded;
|
|
26
|
+
NSArray* focusDestinations;
|
|
27
|
+
id<UIFocusItem> previouslyFocusedItem;
|
|
28
|
+
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
- (instancetype)initWithBridge:(RCTBridge *)bridge {
|
|
@@ -255,6 +258,23 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
255
258
|
motionEffectsAdded = NO;
|
|
256
259
|
}
|
|
257
260
|
|
|
261
|
+
- (BOOL)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context
|
|
262
|
+
{
|
|
263
|
+
// This is the `trapFocus*` logic that prevents the focus updates if
|
|
264
|
+
// focus should be trapped and `nextFocusedItem` is not a child FocusEnv.
|
|
265
|
+
if ((_trapFocusUp && context.focusHeading == UIFocusHeadingUp)
|
|
266
|
+
|| (_trapFocusDown && context.focusHeading == UIFocusHeadingDown)
|
|
267
|
+
|| (_trapFocusLeft && context.focusHeading == UIFocusHeadingLeft)
|
|
268
|
+
|| (_trapFocusRight && context.focusHeading == UIFocusHeadingRight)) {
|
|
269
|
+
|
|
270
|
+
// Checks if `nextFocusedItem` is a child `FocusEnvironment`.
|
|
271
|
+
// If not, it returns false thus it keeps the focus inside.
|
|
272
|
+
return [UIFocusSystem environment:self containsEnvironment:context.nextFocusedItem];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return [super shouldUpdateFocusInContext:context];
|
|
276
|
+
}
|
|
277
|
+
|
|
258
278
|
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
|
|
259
279
|
withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator
|
|
260
280
|
{
|
|
@@ -267,9 +287,8 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
267
287
|
// So, `previouslyFocusedItem` is always the last focused child of `TVFocusGuide`.
|
|
268
288
|
// We should update `preferredFocusEnvironments` in this case to make sure `FocusGuide` remembers
|
|
269
289
|
// the last focused element and redirects the focus to it whenever focus comes back.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
self.focusGuide.preferredFocusEnvironments = @[context.previouslyFocusedItem, self];
|
|
290
|
+
previouslyFocusedItem = context.previouslyFocusedItem;
|
|
291
|
+
[self handleFocusGuide];
|
|
273
292
|
}
|
|
274
293
|
|
|
275
294
|
if (context.nextFocusedView == self && self.isTVSelectable ) {
|
|
@@ -445,10 +464,10 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
445
464
|
|
|
446
465
|
- (void)setAutoFocus:(BOOL)autoFocus
|
|
447
466
|
{
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
467
|
+
if (_autoFocus != autoFocus) {
|
|
468
|
+
_autoFocus = autoFocus;
|
|
469
|
+
[self handleFocusGuide];
|
|
470
|
+
}
|
|
452
471
|
}
|
|
453
472
|
|
|
454
473
|
- (void)addFocusGuide:(NSArray*)destinations {
|
|
@@ -465,4 +484,57 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
465
484
|
self.focusGuide.preferredFocusEnvironments = destinations;
|
|
466
485
|
}
|
|
467
486
|
|
|
487
|
+
- (void)removeFocusGuide {
|
|
488
|
+
if (self.focusGuide != nil) {
|
|
489
|
+
focusDestinations = nil;
|
|
490
|
+
previouslyFocusedItem = nil;
|
|
491
|
+
|
|
492
|
+
[self removeLayoutGuide:self.focusGuide];
|
|
493
|
+
self.focusGuide = nil;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/// Responsible of determining what focusGuide's next state should be based on the active properties of the component.
|
|
498
|
+
- (void)handleFocusGuide
|
|
499
|
+
{
|
|
500
|
+
// `destinations` should always be favored against `autoFocus` feature, if provided.
|
|
501
|
+
if (focusDestinations != nil) {
|
|
502
|
+
[self addFocusGuide:focusDestinations];
|
|
503
|
+
} else if (_autoFocus && previouslyFocusedItem != nil) {
|
|
504
|
+
// We also add `self` as the second option in case `previouslyFocusedItem` becomes unreachable (e.g gets detached).
|
|
505
|
+
// `self` helps redirecting focus to the first focusable element in that case.
|
|
506
|
+
[self addFocusGuide:@[previouslyFocusedItem, self]];
|
|
507
|
+
} else if (_autoFocus) {
|
|
508
|
+
[self addFocusGuide:@[self]];
|
|
509
|
+
} else {
|
|
510
|
+
// Then there's no need to have `focusGuide`, remove it to prevent potential bugs.
|
|
511
|
+
[self removeFocusGuide];
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
- (void)setFocusDestinations:(NSArray*)destinations
|
|
516
|
+
{
|
|
517
|
+
if(destinations.count == 0) {
|
|
518
|
+
focusDestinations = nil;
|
|
519
|
+
} else {
|
|
520
|
+
focusDestinations = destinations;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
[self handleFocusGuide];
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
- (void)requestTVFocus
|
|
527
|
+
{
|
|
528
|
+
RCTRootView *rootview = [self rootView];
|
|
529
|
+
if (rootview == nil) return;
|
|
530
|
+
|
|
531
|
+
if (self.focusGuide != nil) {
|
|
532
|
+
rootview.reactPreferredFocusEnvironments = self.focusGuide.preferredFocusEnvironments;
|
|
533
|
+
} else {
|
|
534
|
+
rootview.reactPreferredFocusEnvironments = @[self];
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
[rootview setNeedsFocusUpdate];
|
|
538
|
+
[rootview updateFocusIfNeeded];
|
|
539
|
+
}
|
|
468
540
|
@end
|
|
@@ -138,6 +138,10 @@ RCT_EXPORT_VIEW_PROPERTY(nextFocusDown, NSNumber)
|
|
|
138
138
|
RCT_EXPORT_VIEW_PROPERTY(nextFocusLeft, NSNumber)
|
|
139
139
|
RCT_EXPORT_VIEW_PROPERTY(nextFocusRight, NSNumber)
|
|
140
140
|
RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL)
|
|
141
|
+
RCT_EXPORT_VIEW_PROPERTY(trapFocusUp, BOOL)
|
|
142
|
+
RCT_EXPORT_VIEW_PROPERTY(trapFocusDown, BOOL)
|
|
143
|
+
RCT_EXPORT_VIEW_PROPERTY(trapFocusLeft, BOOL)
|
|
144
|
+
RCT_EXPORT_VIEW_PROPERTY(trapFocusRight, BOOL)
|
|
141
145
|
#endif
|
|
142
146
|
|
|
143
147
|
// Accessibility related properties
|
|
@@ -452,9 +456,17 @@ RCT_EXPORT_METHOD(setDestinations : (nonnull NSNumber *)viewTag reactTags : (NSA
|
|
|
452
456
|
[destinations addObject:destination];
|
|
453
457
|
}
|
|
454
458
|
}
|
|
455
|
-
[view
|
|
459
|
+
[view setFocusDestinations:destinations];
|
|
456
460
|
}];
|
|
457
461
|
}
|
|
462
|
+
|
|
463
|
+
RCT_EXPORT_METHOD(requestTVFocus : (nonnull NSNumber *)viewTag)
|
|
464
|
+
{
|
|
465
|
+
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
466
|
+
RCTTVView *view = (RCTTVView *)viewRegistry[viewTag];
|
|
467
|
+
[view requestTVFocus];
|
|
468
|
+
}];
|
|
469
|
+
}
|
|
458
470
|
#endif
|
|
459
471
|
|
|
460
472
|
// The events below define the properties that are not used by native directly, but required in the view config for new
|
|
@@ -105,7 +105,13 @@ public class ReactFeatureFlags {
|
|
|
105
105
|
public static boolean enableDelayedViewStateDeletion = false;
|
|
106
106
|
|
|
107
107
|
/**
|
|
108
|
-
* Send key down events as well as key up events
|
|
108
|
+
* Android TV: Send key down events as well as key up events.
|
|
109
|
+
* Enabling this flag will result in two 'select' TVRemoteEventHandler events
|
|
110
|
+
* (one with key action 0 and one with key action 1) for each press of the center
|
|
111
|
+
* DPad button. (Similarly for arrow keys.)
|
|
112
|
+
* Note: If you enable this flag, long presses of the select or center button will
|
|
113
|
+
* result in an initial 'select' with eventKeyAction = 0 (ACTION_DOWN), before
|
|
114
|
+
* the expected 'longSelect' events are fired. (Similarly for arrow keys.)
|
|
109
115
|
*/
|
|
110
116
|
public static boolean enableKeyDownEvents = false;
|
|
111
117
|
|
|
@@ -81,8 +81,14 @@ public class ReactAndroidHWInputDeviceHelper {
|
|
|
81
81
|
*/
|
|
82
82
|
private int mLastFocusedViewId = View.NO_ID;
|
|
83
83
|
|
|
84
|
+
// Presses longer than this number of milliseconds are treated as long presses
|
|
85
|
+
// This seems to be roughly the time the emulator waits after the first key down event
|
|
86
|
+
// before sending a continuous stream of rapid key downs on a long press.
|
|
87
|
+
private long mLongPressedDelta = 300;
|
|
88
|
+
|
|
89
|
+
// These are used for long press detection
|
|
84
90
|
private long mLastKeyDownTime = 0;
|
|
85
|
-
private
|
|
91
|
+
private boolean longPressEventActive = false;
|
|
86
92
|
|
|
87
93
|
public ReactAndroidHWInputDeviceHelper() {}
|
|
88
94
|
|
|
@@ -101,6 +107,12 @@ public class ReactAndroidHWInputDeviceHelper {
|
|
|
101
107
|
eventKeyCode == KeyEvent.KEYCODE_DPAD_LEFT;
|
|
102
108
|
}
|
|
103
109
|
|
|
110
|
+
// True if we are in the long press state and we are more than
|
|
111
|
+
// mLongPressedDelta milliseconds since the last long press event was fired
|
|
112
|
+
private boolean isLongPressEventTime(long time) {
|
|
113
|
+
return mLastKeyDownTime != 0 && time - mLastKeyDownTime > mLongPressedDelta;
|
|
114
|
+
}
|
|
115
|
+
|
|
104
116
|
/** Called from {@link com.facebook.react.ReactRootView}. This is the main place the key events are handled. */
|
|
105
117
|
public void handleKeyEvent(KeyEvent ev, ReactContext context) {
|
|
106
118
|
int eventKeyCode = ev.getKeyCode();
|
|
@@ -108,30 +120,48 @@ public class ReactAndroidHWInputDeviceHelper {
|
|
|
108
120
|
long time = SystemClock.uptimeMillis();
|
|
109
121
|
boolean isSelectOrDPadEvent = isDPadEvent(eventKeyCode) || isSelectEvent(eventKeyCode);
|
|
110
122
|
|
|
111
|
-
// Simple implementation of long press detection
|
|
112
|
-
if ((eventKeyAction == KeyEvent.ACTION_DOWN)
|
|
113
|
-
|
|
114
|
-
|
|
123
|
+
// Simple implementation of long press detection for key down events
|
|
124
|
+
if ((eventKeyAction == KeyEvent.ACTION_DOWN) && isSelectOrDPadEvent) {
|
|
125
|
+
if (mLastKeyDownTime == 0) {
|
|
126
|
+
mLastKeyDownTime = time;
|
|
127
|
+
} else {
|
|
128
|
+
if (isLongPressEventTime(time)) {
|
|
129
|
+
// Activate long press state and don't reset until key up event arrives
|
|
130
|
+
longPressEventActive = true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
115
133
|
}
|
|
116
134
|
|
|
117
|
-
if (shouldDispatchEvent(eventKeyCode, eventKeyAction)) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
135
|
+
if (shouldDispatchEvent(eventKeyCode, eventKeyAction, time)) {
|
|
136
|
+
if(longPressEventActive) {
|
|
137
|
+
// If we are not sending key down events to JS, send the long press event as a key up to make sure it is received
|
|
138
|
+
dispatchEvent(
|
|
139
|
+
KEY_EVENTS_LONG_PRESS_ACTIONS.get(eventKeyCode),
|
|
140
|
+
mLastFocusedViewId,
|
|
141
|
+
ReactFeatureFlags.enableKeyDownEvents ? eventKeyAction : KeyEvent.ACTION_UP,
|
|
142
|
+
context
|
|
143
|
+
);
|
|
144
|
+
// Update the start time for detecting the next long press event
|
|
145
|
+
mLastKeyDownTime = time;
|
|
123
146
|
} else {
|
|
124
147
|
dispatchEvent(KEY_EVENTS_ACTIONS.get(eventKeyCode), mLastFocusedViewId, eventKeyAction, context);
|
|
125
148
|
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// If this is key up event, reset long press detector
|
|
152
|
+
if ((eventKeyAction == KeyEvent.ACTION_UP) && isSelectOrDPadEvent) {
|
|
126
153
|
mLastKeyDownTime = 0;
|
|
154
|
+
longPressEventActive = false;
|
|
127
155
|
}
|
|
156
|
+
|
|
128
157
|
}
|
|
129
158
|
|
|
130
|
-
// Android TV: Only send key up actions, unless key down events are enabled
|
|
131
|
-
private boolean shouldDispatchEvent(int eventKeyCode, int eventKeyAction) {
|
|
159
|
+
// Android TV: Only send key up actions, unless key down events are enabled or we need to send a long press event
|
|
160
|
+
private boolean shouldDispatchEvent(int eventKeyCode, int eventKeyAction, long time) {
|
|
132
161
|
return KEY_EVENTS_ACTIONS.containsKey(eventKeyCode) && (
|
|
133
162
|
(eventKeyAction == KeyEvent.ACTION_UP) ||
|
|
134
|
-
(eventKeyAction == KeyEvent.ACTION_DOWN && ReactFeatureFlags.enableKeyDownEvents)
|
|
163
|
+
(eventKeyAction == KeyEvent.ACTION_DOWN && !longPressEventActive && ReactFeatureFlags.enableKeyDownEvents) ||
|
|
164
|
+
(eventKeyAction == KeyEvent.ACTION_DOWN && longPressEventActive && isLongPressEventTime(time))
|
|
135
165
|
);
|
|
136
166
|
}
|
|
137
167
|
|
|
@@ -586,6 +586,10 @@ public class ReactEditText extends AppCompatEditText
|
|
|
586
586
|
new SpannableStringBuilder(reactTextUpdate.getText());
|
|
587
587
|
|
|
588
588
|
manageSpans(spannableStringBuilder, reactTextUpdate.mContainsMultipleFragments);
|
|
589
|
+
|
|
590
|
+
// Mitigation for https://github.com/facebook/react-native/issues/35936 (S318090)
|
|
591
|
+
stripAbsoluteSizeSpans(spannableStringBuilder);
|
|
592
|
+
|
|
589
593
|
mContainsImages = reactTextUpdate.containsImages();
|
|
590
594
|
|
|
591
595
|
// When we update text, we trigger onChangeText code that will
|
|
@@ -659,6 +663,27 @@ public class ReactEditText extends AppCompatEditText
|
|
|
659
663
|
}
|
|
660
664
|
}
|
|
661
665
|
|
|
666
|
+
private void stripAbsoluteSizeSpans(SpannableStringBuilder sb) {
|
|
667
|
+
// We have already set a font size on the EditText itself. We can safely remove sizing spans
|
|
668
|
+
// which are the same as the set font size, and not otherwise overlapped.
|
|
669
|
+
final int effectiveFontSize = mTextAttributes.getEffectiveFontSize();
|
|
670
|
+
ReactAbsoluteSizeSpan[] spans = sb.getSpans(0, sb.length(), ReactAbsoluteSizeSpan.class);
|
|
671
|
+
|
|
672
|
+
outerLoop:
|
|
673
|
+
for (ReactAbsoluteSizeSpan span : spans) {
|
|
674
|
+
ReactAbsoluteSizeSpan[] overlappingSpans =
|
|
675
|
+
sb.getSpans(sb.getSpanStart(span), sb.getSpanEnd(span), ReactAbsoluteSizeSpan.class);
|
|
676
|
+
|
|
677
|
+
for (ReactAbsoluteSizeSpan overlappingSpan : overlappingSpans) {
|
|
678
|
+
if (span.getSize() != effectiveFontSize) {
|
|
679
|
+
continue outerLoop;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
sb.removeSpan(span);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
662
687
|
private static boolean sameTextForSpan(
|
|
663
688
|
final Editable oldText,
|
|
664
689
|
final SpannableStringBuilder newText,
|
|
@@ -20,6 +20,7 @@ import android.graphics.RectF;
|
|
|
20
20
|
import android.graphics.drawable.Drawable;
|
|
21
21
|
import android.graphics.drawable.LayerDrawable;
|
|
22
22
|
import android.os.Build;
|
|
23
|
+
import android.view.FocusFinder;
|
|
23
24
|
import android.view.MotionEvent;
|
|
24
25
|
import android.view.View;
|
|
25
26
|
import android.view.ViewGroup;
|
|
@@ -86,6 +87,10 @@ public class ReactViewGroup extends ViewGroup
|
|
|
86
87
|
private boolean autoFocus = false;
|
|
87
88
|
private WeakReference<View> lastFocusedElement;
|
|
88
89
|
private boolean mRecoverFocus = false;
|
|
90
|
+
private boolean trapFocusUp = false;
|
|
91
|
+
private boolean trapFocusDown = false;
|
|
92
|
+
private boolean trapFocusLeft = false;
|
|
93
|
+
private boolean trapFocusRight = false;
|
|
89
94
|
|
|
90
95
|
/**
|
|
91
96
|
* This listener will be set for child views when removeClippedSubview property is enabled. When
|
|
@@ -391,6 +396,8 @@ public class ReactViewGroup extends ViewGroup
|
|
|
391
396
|
Animation animation = child.getAnimation();
|
|
392
397
|
boolean isAnimating = animation != null && !animation.hasEnded();
|
|
393
398
|
if (!intersects && child.getParent() != null && !isAnimating) {
|
|
399
|
+
recoverFocus(child);
|
|
400
|
+
|
|
394
401
|
// We can try saving on invalidate call here as the view that we remove is out of visible area
|
|
395
402
|
// therefore invalidation is not necessary.
|
|
396
403
|
super.removeViewsInLayout(idx - clippedSoFar, 1);
|
|
@@ -1092,8 +1099,18 @@ public class ReactViewGroup extends ViewGroup
|
|
|
1092
1099
|
return false;
|
|
1093
1100
|
}
|
|
1094
1101
|
|
|
1102
|
+
private boolean isFocusDestinationsSet() {
|
|
1103
|
+
return focusDestinations.length > 0;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1095
1106
|
private boolean isTVFocusGuide() {
|
|
1096
|
-
|
|
1107
|
+
/**
|
|
1108
|
+
* We don't count a view as `TVFocusGuide` if it has `trapFocus*` props enabled.
|
|
1109
|
+
* The reason is, it's a seperate functionality that has nothing to do with other
|
|
1110
|
+
* TVFocusGuide features that involves heavy focus management. So, the feature
|
|
1111
|
+
* is not directly tied to `TVFocusGuide`.
|
|
1112
|
+
*/
|
|
1113
|
+
return isFocusDestinationsSet() || autoFocus;
|
|
1097
1114
|
}
|
|
1098
1115
|
|
|
1099
1116
|
@Nullable
|
|
@@ -1182,6 +1199,14 @@ public class ReactViewGroup extends ViewGroup
|
|
|
1182
1199
|
return super.requestFocus(direction, previouslyFocusedRect);
|
|
1183
1200
|
}
|
|
1184
1201
|
|
|
1202
|
+
if (isFocusDestinationsSet()) {
|
|
1203
|
+
View destination = findDestinationView();
|
|
1204
|
+
|
|
1205
|
+
if (destination != null && requestFocusViewOrAncestor(destination)) {
|
|
1206
|
+
return true;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1185
1210
|
if (this.autoFocus) {
|
|
1186
1211
|
View lastFocusedElem = lastFocusedElement.get();
|
|
1187
1212
|
|
|
@@ -1207,19 +1232,29 @@ public class ReactViewGroup extends ViewGroup
|
|
|
1207
1232
|
}
|
|
1208
1233
|
}
|
|
1209
1234
|
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
if (destination != null && requestFocusViewOrAncestor(destination)) {
|
|
1213
|
-
return true;
|
|
1214
|
-
}
|
|
1235
|
+
return super.requestFocus(direction, previouslyFocusedRect);
|
|
1236
|
+
}
|
|
1215
1237
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1238
|
+
@Override
|
|
1239
|
+
public View focusSearch(View focused, int direction) {
|
|
1240
|
+
/**
|
|
1241
|
+
* FocusSearch recursively goes all the way up to the Root view
|
|
1242
|
+
* and runs `FocusFinder.findNextFocus()` to determine the next focusable.
|
|
1243
|
+
* It finds the next focusable by accounting *every* focusable elements on the screen.
|
|
1244
|
+
*
|
|
1245
|
+
* That is exactly the thing we want to prevent if the view has a `focusTrap` enabled
|
|
1246
|
+
* matching the `direction`. We interrupt `focusSearch` to make the `FocusFinder` run
|
|
1247
|
+
* the algorithm only accounting the children elements of the focus trap.
|
|
1248
|
+
* This ensures that focus will always stay inside the container until trap gets disabled.
|
|
1249
|
+
*/
|
|
1250
|
+
if ((trapFocusUp && direction == FOCUS_UP)
|
|
1251
|
+
|| (trapFocusDown && direction == FOCUS_DOWN)
|
|
1252
|
+
|| (trapFocusLeft && direction == FOCUS_LEFT)
|
|
1253
|
+
|| (trapFocusRight && direction == FOCUS_RIGHT)) {
|
|
1254
|
+
return FocusFinder.getInstance().findNextFocus(this, focused, direction);
|
|
1220
1255
|
}
|
|
1221
1256
|
|
|
1222
|
-
return
|
|
1257
|
+
return super.focusSearch(focused, direction);
|
|
1223
1258
|
}
|
|
1224
1259
|
|
|
1225
1260
|
public void setFocusDestinations(@NonNull int[] focusDestinations) {
|
|
@@ -1230,4 +1265,20 @@ public class ReactViewGroup extends ViewGroup
|
|
|
1230
1265
|
this.autoFocus = autoFocus;
|
|
1231
1266
|
lastFocusedElement = new WeakReference<View>(null);
|
|
1232
1267
|
}
|
|
1268
|
+
|
|
1269
|
+
public void setTrapFocusUp(boolean enabled) {
|
|
1270
|
+
this.trapFocusUp = enabled;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
public void setTrapFocusDown(boolean enabled) {
|
|
1274
|
+
this.trapFocusDown = enabled;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
public void setTrapFocusLeft(boolean enabled) {
|
|
1278
|
+
this.trapFocusLeft = enabled;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
public void setTrapFocusRight(boolean enabled) {
|
|
1282
|
+
this.trapFocusRight = enabled;
|
|
1283
|
+
}
|
|
1233
1284
|
}
|
|
@@ -10,6 +10,7 @@ package com.facebook.react.views.view;
|
|
|
10
10
|
import android.annotation.TargetApi;
|
|
11
11
|
import android.graphics.Rect;
|
|
12
12
|
import android.os.Build;
|
|
13
|
+
import android.util.Log;
|
|
13
14
|
import android.view.View;
|
|
14
15
|
import androidx.annotation.NonNull;
|
|
15
16
|
import androidx.annotation.Nullable;
|
|
@@ -51,6 +52,7 @@ public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
|
|
|
51
52
|
};
|
|
52
53
|
private static final int CMD_HOTSPOT_UPDATE = 1;
|
|
53
54
|
private static final int CMD_SET_PRESSED = 2;
|
|
55
|
+
private static final int CMD_SET_DESTINATIONS = 3;
|
|
54
56
|
private static final String HOTSPOT_UPDATE_KEY = "hotspotUpdate";
|
|
55
57
|
|
|
56
58
|
@ReactProp(name = "accessible")
|
|
@@ -305,7 +307,7 @@ public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
|
|
|
305
307
|
|
|
306
308
|
@Override
|
|
307
309
|
public Map<String, Integer> getCommandsMap() {
|
|
308
|
-
return MapBuilder.of(HOTSPOT_UPDATE_KEY, CMD_HOTSPOT_UPDATE, "setPressed", CMD_SET_PRESSED);
|
|
310
|
+
return MapBuilder.of(HOTSPOT_UPDATE_KEY, CMD_HOTSPOT_UPDATE, "setPressed", CMD_SET_PRESSED, "setDestinations", CMD_SET_DESTINATIONS);
|
|
309
311
|
}
|
|
310
312
|
|
|
311
313
|
@Override
|
|
@@ -321,6 +323,11 @@ public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
|
|
|
321
323
|
handleSetPressed(root, args);
|
|
322
324
|
break;
|
|
323
325
|
}
|
|
326
|
+
case CMD_SET_DESTINATIONS:
|
|
327
|
+
{
|
|
328
|
+
handleSetDestinations(root, args);
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
324
331
|
}
|
|
325
332
|
}
|
|
326
333
|
|
|
@@ -337,6 +344,16 @@ public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
|
|
|
337
344
|
handleSetPressed(root, args);
|
|
338
345
|
break;
|
|
339
346
|
}
|
|
347
|
+
case "setDestinations":
|
|
348
|
+
{
|
|
349
|
+
handleSetDestinations(root, args);
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
case "requestTVFocus":
|
|
353
|
+
{
|
|
354
|
+
root.requestFocus();
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
340
357
|
}
|
|
341
358
|
}
|
|
342
359
|
|
|
@@ -359,14 +376,18 @@ public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
|
|
|
359
376
|
root.drawableHotspotChanged(x, y);
|
|
360
377
|
}
|
|
361
378
|
|
|
379
|
+
private void handleSetDestinations(ReactViewGroup root, @Nullable ReadableArray args) {
|
|
380
|
+
if (args == null || args.size() != 1) {
|
|
381
|
+
throw new JSApplicationIllegalArgumentException(
|
|
382
|
+
"Illegal number of arguments for 'setDestinations' command");
|
|
383
|
+
}
|
|
362
384
|
|
|
363
|
-
|
|
364
|
-
public void setDestinations(final ReactViewGroup view, final ReadableArray destinations) {
|
|
385
|
+
ReadableArray destinations = args.getArray(0);
|
|
365
386
|
int[] fd = new int[destinations.size()];
|
|
366
387
|
for (int i = 0; i < fd.length; i++) {
|
|
367
388
|
fd[i] = destinations.getInt(i);
|
|
368
389
|
}
|
|
369
|
-
|
|
390
|
+
root.setFocusDestinations(fd);
|
|
370
391
|
}
|
|
371
392
|
|
|
372
393
|
@ReactProp(name = "autoFocus")
|
|
@@ -374,4 +395,24 @@ public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
|
|
|
374
395
|
view.setAutoFocusTV(autoFocus);
|
|
375
396
|
}
|
|
376
397
|
|
|
398
|
+
@ReactProp(name = "trapFocusUp")
|
|
399
|
+
public void trapFocusUp(ReactViewGroup view, boolean enabled) {
|
|
400
|
+
view.setTrapFocusUp(enabled);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
@ReactProp(name = "trapFocusDown")
|
|
404
|
+
public void trapFocusDown(ReactViewGroup view, boolean enabled) {
|
|
405
|
+
view.setTrapFocusDown(enabled);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
@ReactProp(name = "trapFocusLeft")
|
|
409
|
+
public void trapFocusLeft(ReactViewGroup view, boolean enabled) {
|
|
410
|
+
view.setTrapFocusLeft(enabled);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
@ReactProp(name = "trapFocusRight")
|
|
414
|
+
public void trapFocusRight(ReactViewGroup view, boolean enabled) {
|
|
415
|
+
view.setTrapFocusRight(enabled);
|
|
416
|
+
}
|
|
417
|
+
|
|
377
418
|
}
|
|
@@ -17,8 +17,8 @@ namespace facebook::react {
|
|
|
17
17
|
constexpr struct {
|
|
18
18
|
int32_t Major = 0;
|
|
19
19
|
int32_t Minor = 69;
|
|
20
|
-
int32_t Patch =
|
|
21
|
-
std::string_view Prerelease = "
|
|
20
|
+
int32_t Patch = 8;
|
|
21
|
+
std::string_view Prerelease = "0";
|
|
22
22
|
} ReactNativeVersion;
|
|
23
23
|
|
|
24
24
|
} // namespace facebook::react
|
|
@@ -31,33 +31,73 @@ ViewProps::ViewProps(
|
|
|
31
31
|
rawProps,
|
|
32
32
|
"isTVSelectable",
|
|
33
33
|
sourceProps.isTVSelectable,
|
|
34
|
-
(Boolean)false)),
|
|
34
|
+
(Boolean) false)),
|
|
35
35
|
hasTVPreferredFocus(convertRawProp(
|
|
36
36
|
context,
|
|
37
37
|
rawProps,
|
|
38
38
|
"hasTVPreferredFocus",
|
|
39
39
|
sourceProps.hasTVPreferredFocus,
|
|
40
|
-
(Boolean)false)),
|
|
40
|
+
(Boolean) false)),
|
|
41
41
|
tvParallaxProperties(convertRawProp(
|
|
42
42
|
context,
|
|
43
43
|
rawProps,
|
|
44
44
|
"tvParallaxProperties",
|
|
45
45
|
sourceProps.tvParallaxProperties,
|
|
46
46
|
{})),
|
|
47
|
-
nextFocusUp(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
nextFocusUp(convertRawProp(
|
|
48
|
+
context,
|
|
49
|
+
rawProps,
|
|
50
|
+
"nextFocusUp",
|
|
51
|
+
sourceProps.nextFocusUp,
|
|
52
|
+
{})),
|
|
53
|
+
nextFocusDown(convertRawProp(
|
|
54
|
+
context,
|
|
55
|
+
rawProps,
|
|
56
|
+
"nextFocusDown",
|
|
57
|
+
sourceProps.nextFocusDown,
|
|
58
|
+
{})),
|
|
59
|
+
nextFocusLeft(convertRawProp(
|
|
60
|
+
context,
|
|
61
|
+
rawProps,
|
|
62
|
+
"nextFocusLeft",
|
|
63
|
+
sourceProps.nextFocusLeft,
|
|
64
|
+
{})),
|
|
65
|
+
nextFocusRight(convertRawProp(
|
|
66
|
+
context,
|
|
67
|
+
rawProps,
|
|
68
|
+
"nextFocusRight",
|
|
69
|
+
sourceProps.nextFocusRight,
|
|
70
|
+
{})),
|
|
55
71
|
autoFocus(convertRawProp(
|
|
56
72
|
context,
|
|
57
73
|
rawProps,
|
|
58
74
|
"autoFocus",
|
|
59
75
|
sourceProps.autoFocus,
|
|
60
76
|
(Boolean) false)),
|
|
77
|
+
trapFocusUp(convertRawProp(
|
|
78
|
+
context,
|
|
79
|
+
rawProps,
|
|
80
|
+
"trapFocusUp",
|
|
81
|
+
sourceProps.trapFocusUp,
|
|
82
|
+
false)),
|
|
83
|
+
trapFocusDown(convertRawProp(
|
|
84
|
+
context,
|
|
85
|
+
rawProps,
|
|
86
|
+
"trapFocusDown",
|
|
87
|
+
sourceProps.trapFocusDown,
|
|
88
|
+
false)),
|
|
89
|
+
trapFocusLeft(convertRawProp(
|
|
90
|
+
context,
|
|
91
|
+
rawProps,
|
|
92
|
+
"trapFocusLeft",
|
|
93
|
+
sourceProps.trapFocusLeft,
|
|
94
|
+
false)),
|
|
95
|
+
trapFocusRight(convertRawProp(
|
|
96
|
+
context,
|
|
97
|
+
rawProps,
|
|
98
|
+
"trapFocusRight",
|
|
99
|
+
sourceProps.trapFocusRight,
|
|
100
|
+
false)),
|
|
61
101
|
#endif
|
|
62
102
|
opacity(convertRawProp(
|
|
63
103
|
context,
|
|
@@ -217,12 +257,36 @@ ViewProps::ViewProps(
|
|
|
217
257
|
"renderToHardwareTextureAndroid",
|
|
218
258
|
sourceProps.renderToHardwareTextureAndroid,
|
|
219
259
|
{})),
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
260
|
+
autoFocus(convertRawProp(
|
|
261
|
+
context,
|
|
262
|
+
rawProps,
|
|
263
|
+
"autoFocus",
|
|
264
|
+
sourceProps.autoFocus,
|
|
265
|
+
false)),
|
|
266
|
+
trapFocusUp(convertRawProp(
|
|
267
|
+
context,
|
|
268
|
+
rawProps,
|
|
269
|
+
"trapFocusUp",
|
|
270
|
+
sourceProps.trapFocusUp,
|
|
271
|
+
false)),
|
|
272
|
+
trapFocusDown(convertRawProp(
|
|
273
|
+
context,
|
|
274
|
+
rawProps,
|
|
275
|
+
"trapFocusDown",
|
|
276
|
+
sourceProps.trapFocusDown,
|
|
277
|
+
false)),
|
|
278
|
+
trapFocusLeft(convertRawProp(
|
|
279
|
+
context,
|
|
280
|
+
rawProps,
|
|
281
|
+
"trapFocusLeft",
|
|
282
|
+
sourceProps.trapFocusLeft,
|
|
283
|
+
false)),
|
|
284
|
+
trapFocusRight(convertRawProp(
|
|
285
|
+
context,
|
|
286
|
+
rawProps,
|
|
287
|
+
"trapFocusRight",
|
|
288
|
+
sourceProps.trapFocusRight,
|
|
289
|
+
false))
|
|
226
290
|
#endif
|
|
227
291
|
{};
|
|
228
292
|
|