react-native-acoustic-connect 19.0.11 → 19.0.34
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/CHANGELOG.md +111 -0
- package/ConnectConfig.example.json +1 -1
- package/README.md +426 -3
- package/android/build.gradle +119 -3
- package/android/config.gradle +123 -13
- package/android/src/main/assets/ConnectAdvancedConfig.json +1 -1
- package/android/src/main/assets/EOCoreAdvancedConfig.json +1 -1
- package/android/src/main/assets/TealeafAdvancedConfig.json +1 -1
- package/android/src/main/java/com/acousticconnectrn/HybridAcousticConnectRN.kt +457 -37
- package/app.plugin.js +2 -2
- package/ios/AcousticConnectRNConfig.json +2 -2
- package/ios/ConnectRNParsing.swift +229 -0
- package/ios/HybridAcousticConnectRN.swift +290 -30
- package/lib/commonjs/TLTRN.js +116 -3
- package/lib/commonjs/TLTRN.js.map +1 -1
- package/lib/commonjs/components/Connect.js +145 -27
- package/lib/commonjs/components/Connect.js.map +1 -1
- package/lib/commonjs/index.js +3 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/TLTRN.js +116 -3
- package/lib/module/TLTRN.js.map +1 -1
- package/lib/module/components/Connect.js +146 -28
- package/lib/module/components/Connect.js.map +1 -1
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/TLTRN.d.ts +85 -1
- package/lib/typescript/src/TLTRN.d.ts.map +1 -1
- package/lib/typescript/src/components/Connect.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/react-native-acoustic-connect.nitro.d.ts +190 -10
- package/lib/typescript/src/specs/react-native-acoustic-connect.nitro.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridAcousticConnectRNSpec.cpp +5 -9
- package/nitrogen/generated/android/c++/JHybridAcousticConnectRNSpec.hpp +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/acousticconnectrn/HybridAcousticConnectRNSpec.kt +2 -1
- package/nitrogen/generated/ios/AcousticConnectRN-Swift-Cxx-Umbrella.hpp +1 -0
- package/nitrogen/generated/ios/c++/HybridAcousticConnectRNSpecSwift.hpp +2 -1
- package/nitrogen/generated/ios/swift/HybridAcousticConnectRNSpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridAcousticConnectRNSpec_cxx.swift +2 -25
- package/nitrogen/generated/shared/c++/HybridAcousticConnectRNSpec.hpp +2 -1
- package/package.json +6 -8
- package/plugin/build/withConnectAndroidConfig.d.ts +2 -2
- package/plugin/build/withConnectAndroidConfig.js +2 -2
- package/plugin/build/withConnectIosSigning.d.ts +1 -1
- package/plugin/build/withConnectIosSigning.js +1 -1
- package/plugin/src/withConnectAndroidConfig.ts +2 -2
- package/plugin/src/withConnectIosSigning.ts +1 -1
- package/scripts/gradleParser.js +1 -1
- package/src/TLTRN.ts +125 -4
- package/src/components/Connect.tsx +150 -27
- package/src/index.ts +5 -0
- package/src/specs/react-native-acoustic-connect.nitro.ts +192 -10
- package/Examples/SampleUI/.bundle/config +0 -2
- package/Examples/SampleUI/.detoxrc.js +0 -83
- package/Examples/SampleUI/.eslintrc.js +0 -4
- package/Examples/SampleUI/.prettierrc.js +0 -7
- package/Examples/SampleUI/.watchmanconfig +0 -1
- package/Examples/SampleUI/App.js +0 -1
- package/Examples/SampleUI/Gemfile +0 -10
- package/Examples/SampleUI/Gemfile.lock +0 -121
- package/Examples/SampleUI/README.md +0 -79
- package/Examples/SampleUI/__tests__/App.test.tsx +0 -17
- package/Examples/SampleUI/android/app/build.gradle +0 -129
- package/Examples/SampleUI/android/app/debug.keystore +0 -0
- package/Examples/SampleUI/android/app/proguard-rules.pro +0 -10
- package/Examples/SampleUI/android/app/src/debug/AndroidManifest.xml +0 -9
- package/Examples/SampleUI/android/app/src/main/AndroidManifest.xml +0 -31
- package/Examples/SampleUI/android/app/src/main/java/com/sampleui/MainActivity.kt +0 -30
- package/Examples/SampleUI/android/app/src/main/java/com/sampleui/MainApplication.kt +0 -53
- package/Examples/SampleUI/android/app/src/main/res/drawable/rn_edit_text_material.xml +0 -37
- package/Examples/SampleUI/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/Examples/SampleUI/android/app/src/main/res/values/strings.xml +0 -3
- package/Examples/SampleUI/android/app/src/main/res/values/styles.xml +0 -9
- package/Examples/SampleUI/android/build.gradle +0 -21
- package/Examples/SampleUI/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/Examples/SampleUI/android/gradle/wrapper/gradle-wrapper.properties +0 -7
- package/Examples/SampleUI/android/gradle.properties +0 -39
- package/Examples/SampleUI/android/gradlew +0 -252
- package/Examples/SampleUI/android/gradlew.bat +0 -94
- package/Examples/SampleUI/android/settings.gradle +0 -21
- package/Examples/SampleUI/app.json +0 -51
- package/Examples/SampleUI/assets/fonts/Abel-Regular.ttf +0 -0
- package/Examples/SampleUI/assets/fonts/NotoSans-Regular.ttf +0 -0
- package/Examples/SampleUI/assets/images/android-icon.png +0 -0
- package/Examples/SampleUI/assets/images/artist-1.jpg +0 -0
- package/Examples/SampleUI/assets/images/artist-2.jpg +0 -0
- package/Examples/SampleUI/assets/images/avatar.png +0 -0
- package/Examples/SampleUI/assets/images/beach.jpg +0 -0
- package/Examples/SampleUI/assets/images/bridge.jpg +0 -0
- package/Examples/SampleUI/assets/images/chameleon.jpg +0 -0
- package/Examples/SampleUI/assets/images/city.jpg +0 -0
- package/Examples/SampleUI/assets/images/email-icon.png +0 -0
- package/Examples/SampleUI/assets/images/favorite.png +0 -0
- package/Examples/SampleUI/assets/images/forest.jpg +0 -0
- package/Examples/SampleUI/assets/images/paper-icon.png +0 -0
- package/Examples/SampleUI/assets/images/players-2.jpg +0 -0
- package/Examples/SampleUI/assets/images/players.jpg +0 -0
- package/Examples/SampleUI/assets/images/restaurant-1.jpg +0 -0
- package/Examples/SampleUI/assets/images/restaurant-2.jpg +0 -0
- package/Examples/SampleUI/assets/images/song-1.jpg +0 -0
- package/Examples/SampleUI/assets/images/song-2.jpg +0 -0
- package/Examples/SampleUI/assets/images/splash.png +0 -0
- package/Examples/SampleUI/assets/images/strawberries.jpg +0 -0
- package/Examples/SampleUI/assets/images/wrecked-ship.jpg +0 -0
- package/Examples/SampleUI/assets/styles/fonts.css +0 -47
- package/Examples/SampleUI/babel.config.js +0 -22
- package/Examples/SampleUI/index.js +0 -9
- package/Examples/SampleUI/ios/.xcode.env +0 -11
- package/Examples/SampleUI/ios/Podfile +0 -71
- package/Examples/SampleUI/ios/Podfile.lock +0 -2276
- package/Examples/SampleUI/ios/SampleUI/AppDelegate.h +0 -7
- package/Examples/SampleUI/ios/SampleUI/AppDelegate.mm +0 -31
- package/Examples/SampleUI/ios/SampleUI/Images.xcassets/AppIcon.appiconset/Contents.json +0 -53
- package/Examples/SampleUI/ios/SampleUI/Images.xcassets/Contents.json +0 -6
- package/Examples/SampleUI/ios/SampleUI/Info.plist +0 -52
- package/Examples/SampleUI/ios/SampleUI/LaunchScreen.storyboard +0 -47
- package/Examples/SampleUI/ios/SampleUI/PrivacyInfo.xcprivacy +0 -48
- package/Examples/SampleUI/ios/SampleUI/main.m +0 -10
- package/Examples/SampleUI/ios/SampleUI.xcodeproj/project.pbxproj +0 -785
- package/Examples/SampleUI/ios/SampleUI.xcodeproj/xcshareddata/xcschemes/SampleUI.xcscheme +0 -105
- package/Examples/SampleUI/ios/SampleUI.xcworkspace/contents.xcworkspacedata +0 -10
- package/Examples/SampleUI/ios/SampleUITests/Info.plist +0 -24
- package/Examples/SampleUI/ios/SampleUITests/SampleUITests.m +0 -66
- package/Examples/SampleUI/jest.config.js +0 -3
- package/Examples/SampleUI/metro.config.js +0 -54
- package/Examples/SampleUI/package.json +0 -65
- package/Examples/SampleUI/scripts/integration-test-android.sh +0 -292
- package/Examples/SampleUI/src/DrawerItems.tsx +0 -322
- package/Examples/SampleUI/src/ExampleList.tsx +0 -175
- package/Examples/SampleUI/src/Examples/ActivityIndicatorExample.tsx +0 -73
- package/Examples/SampleUI/src/Examples/AnimatedFABExample/AnimatedFABExample.tsx +0 -220
- package/Examples/SampleUI/src/Examples/AnimatedFABExample/CustomFAB.tsx +0 -70
- package/Examples/SampleUI/src/Examples/AnimatedFABExample/CustomFABControls.tsx +0 -146
- package/Examples/SampleUI/src/Examples/AnimatedFABExample/index.ts +0 -1
- package/Examples/SampleUI/src/Examples/AppbarExample.tsx +0 -263
- package/Examples/SampleUI/src/Examples/AvatarExample.tsx +0 -76
- package/Examples/SampleUI/src/Examples/BadgeExample.tsx +0 -97
- package/Examples/SampleUI/src/Examples/BannerExample.tsx +0 -152
- package/Examples/SampleUI/src/Examples/BottomNavigationBarExample.tsx +0 -94
- package/Examples/SampleUI/src/Examples/BottomNavigationExample.tsx +0 -205
- package/Examples/SampleUI/src/Examples/ButtonExample.tsx +0 -405
- package/Examples/SampleUI/src/Examples/CardExample.tsx +0 -245
- package/Examples/SampleUI/src/Examples/CheckboxExample.tsx +0 -87
- package/Examples/SampleUI/src/Examples/CheckboxItemExample.tsx +0 -72
- package/Examples/SampleUI/src/Examples/ChipExample.tsx +0 -432
- package/Examples/SampleUI/src/Examples/DataTableExample.tsx +0 -128
- package/Examples/SampleUI/src/Examples/DialogExample.tsx +0 -217
- package/Examples/SampleUI/src/Examples/Dialogs/DialogTextComponent.tsx +0 -31
- package/Examples/SampleUI/src/Examples/Dialogs/DialogTrackingTest.tsx +0 -307
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithCustomColors.tsx +0 -57
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithDismissableBackButton.tsx +0 -38
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithIcon.tsx +0 -42
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithLoadingIndicator.tsx +0 -48
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithLongText.tsx +0 -81
- package/Examples/SampleUI/src/Examples/Dialogs/DialogWithRadioBtns.tsx +0 -111
- package/Examples/SampleUI/src/Examples/Dialogs/UndismissableDialog.tsx +0 -30
- package/Examples/SampleUI/src/Examples/Dialogs/index.tsx +0 -44
- package/Examples/SampleUI/src/Examples/DividerExample.tsx +0 -30
- package/Examples/SampleUI/src/Examples/FABExample.tsx +0 -226
- package/Examples/SampleUI/src/Examples/IconButtonExample.tsx +0 -230
- package/Examples/SampleUI/src/Examples/IconExample.tsx +0 -50
- package/Examples/SampleUI/src/Examples/ListAccordionExample.tsx +0 -65
- package/Examples/SampleUI/src/Examples/ListAccordionGroupExample.tsx +0 -80
- package/Examples/SampleUI/src/Examples/ListItemExample.tsx +0 -310
- package/Examples/SampleUI/src/Examples/ListSectionExample.tsx +0 -159
- package/Examples/SampleUI/src/Examples/MaterialBottomTabNavigatorExample.tsx +0 -87
- package/Examples/SampleUI/src/Examples/MenuExample.tsx +0 -211
- package/Examples/SampleUI/src/Examples/ProgressBarExample.tsx +0 -142
- package/Examples/SampleUI/src/Examples/RadioButtonExample.tsx +0 -104
- package/Examples/SampleUI/src/Examples/RadioButtonGroupExample.tsx +0 -67
- package/Examples/SampleUI/src/Examples/RadioButtonItemExample.tsx +0 -77
- package/Examples/SampleUI/src/Examples/SearchbarExample.tsx +0 -249
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonCustomColorCheck.tsx +0 -93
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonDefault.tsx +0 -49
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonDisabled.tsx +0 -47
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonMultiselect.tsx +0 -50
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonMultiselectIcons.tsx +0 -49
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonMultiselectRealCase.tsx +0 -114
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonOnlyIcons.tsx +0 -40
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonOnlyIconsWithCheck.tsx +0 -43
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonRealCase.tsx +0 -97
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonWithDensity.tsx +0 -47
- package/Examples/SampleUI/src/Examples/SegmentedButtons/SegmentedButtonWithSelectedCheck.tsx +0 -52
- package/Examples/SampleUI/src/Examples/SegmentedButtons/index.ts +0 -9
- package/Examples/SampleUI/src/Examples/SegmentedButtonsExample.tsx +0 -57
- package/Examples/SampleUI/src/Examples/SnackbarExample.tsx +0 -141
- package/Examples/SampleUI/src/Examples/SurfaceExample.tsx +0 -130
- package/Examples/SampleUI/src/Examples/SwitchExample.tsx +0 -105
- package/Examples/SampleUI/src/Examples/TeamDetails.tsx +0 -291
- package/Examples/SampleUI/src/Examples/TeamsList.tsx +0 -57
- package/Examples/SampleUI/src/Examples/TextExample.tsx +0 -132
- package/Examples/SampleUI/src/Examples/TextInputExample.tsx +0 -914
- package/Examples/SampleUI/src/Examples/ThemeExample.tsx +0 -41
- package/Examples/SampleUI/src/Examples/ThemingWithReactNavigation.tsx +0 -75
- package/Examples/SampleUI/src/Examples/ToggleButtonExample.tsx +0 -128
- package/Examples/SampleUI/src/Examples/TooltipExample.tsx +0 -191
- package/Examples/SampleUI/src/Examples/TouchableRippleExample.tsx +0 -37
- package/Examples/SampleUI/src/RootNavigator.tsx +0 -95
- package/Examples/SampleUI/src/ScreenWrapper.tsx +0 -67
- package/Examples/SampleUI/src/components/ActivityIndicator.tsx +0 -254
- package/Examples/SampleUI/src/components/Appbar/Appbar.tsx +0 -364
- package/Examples/SampleUI/src/components/Appbar/AppbarAction.tsx +0 -132
- package/Examples/SampleUI/src/components/Appbar/AppbarBackAction.tsx +0 -77
- package/Examples/SampleUI/src/components/Appbar/AppbarBackIcon.tsx +0 -52
- package/Examples/SampleUI/src/components/Appbar/AppbarContent.tsx +0 -249
- package/Examples/SampleUI/src/components/Appbar/AppbarHeader.tsx +0 -174
- package/Examples/SampleUI/src/components/Appbar/index.ts +0 -22
- package/Examples/SampleUI/src/components/Appbar/utils.ts +0 -188
- package/Examples/SampleUI/src/components/Avatar/Avatar.tsx +0 -8
- package/Examples/SampleUI/src/components/Avatar/AvatarIcon.tsx +0 -87
- package/Examples/SampleUI/src/components/Avatar/AvatarImage.tsx +0 -128
- package/Examples/SampleUI/src/components/Avatar/AvatarText.tsx +0 -127
- package/Examples/SampleUI/src/components/Badge.tsx +0 -138
- package/Examples/SampleUI/src/components/Banner.tsx +0 -302
- package/Examples/SampleUI/src/components/BottomNavigation/BottomNavigation.tsx +0 -643
- package/Examples/SampleUI/src/components/BottomNavigation/BottomNavigationBar.tsx +0 -1039
- package/Examples/SampleUI/src/components/BottomNavigation/BottomNavigationRouteScreen.tsx +0 -31
- package/Examples/SampleUI/src/components/BottomNavigation/utils.ts +0 -70
- package/Examples/SampleUI/src/components/Button/Button.tsx +0 -503
- package/Examples/SampleUI/src/components/Button/utils.tsx +0 -272
- package/Examples/SampleUI/src/components/Card/Card.tsx +0 -373
- package/Examples/SampleUI/src/components/Card/CardActions.tsx +0 -74
- package/Examples/SampleUI/src/components/Card/CardContent.tsx +0 -99
- package/Examples/SampleUI/src/components/Card/CardCover.tsx +0 -96
- package/Examples/SampleUI/src/components/Card/CardTitle.tsx +0 -236
- package/Examples/SampleUI/src/components/Card/utils.tsx +0 -110
- package/Examples/SampleUI/src/components/Checkbox/Checkbox.tsx +0 -78
- package/Examples/SampleUI/src/components/Checkbox/CheckboxAndroid.tsx +0 -180
- package/Examples/SampleUI/src/components/Checkbox/CheckboxIOS.tsx +0 -104
- package/Examples/SampleUI/src/components/Checkbox/CheckboxItem.tsx +0 -236
- package/Examples/SampleUI/src/components/Checkbox/index.ts +0 -19
- package/Examples/SampleUI/src/components/Checkbox/utils.ts +0 -183
- package/Examples/SampleUI/src/components/Chip/Chip.tsx +0 -513
- package/Examples/SampleUI/src/components/Chip/helpers.tsx +0 -322
- package/Examples/SampleUI/src/components/CrossFadeIcon.tsx +0 -140
- package/Examples/SampleUI/src/components/DataTable/DataTable.tsx +0 -138
- package/Examples/SampleUI/src/components/DataTable/DataTableCell.tsx +0 -132
- package/Examples/SampleUI/src/components/DataTable/DataTableHeader.tsx +0 -82
- package/Examples/SampleUI/src/components/DataTable/DataTablePagination.tsx +0 -407
- package/Examples/SampleUI/src/components/DataTable/DataTableRow.tsx +0 -107
- package/Examples/SampleUI/src/components/DataTable/DataTableTitle.tsx +0 -208
- package/Examples/SampleUI/src/components/Dialog/Dialog.tsx +0 -191
- package/Examples/SampleUI/src/components/Dialog/DialogActions.tsx +0 -94
- package/Examples/SampleUI/src/components/Dialog/DialogContent.tsx +0 -54
- package/Examples/SampleUI/src/components/Dialog/DialogIcon.tsx +0 -100
- package/Examples/SampleUI/src/components/Dialog/DialogScrollArea.tsx +0 -88
- package/Examples/SampleUI/src/components/Dialog/DialogTitle.tsx +0 -94
- package/Examples/SampleUI/src/components/Divider.tsx +0 -102
- package/Examples/SampleUI/src/components/Drawer/Drawer.tsx +0 -8
- package/Examples/SampleUI/src/components/Drawer/DrawerCollapsedItem.tsx +0 -282
- package/Examples/SampleUI/src/components/Drawer/DrawerItem.tsx +0 -209
- package/Examples/SampleUI/src/components/Drawer/DrawerSection.tsx +0 -138
- package/Examples/SampleUI/src/components/FAB/AnimatedFAB.tsx +0 -619
- package/Examples/SampleUI/src/components/FAB/FAB.tsx +0 -371
- package/Examples/SampleUI/src/components/FAB/FABGroup.tsx +0 -532
- package/Examples/SampleUI/src/components/FAB/index.ts +0 -13
- package/Examples/SampleUI/src/components/FAB/utils.ts +0 -474
- package/Examples/SampleUI/src/components/HelperText/HelperText.tsx +0 -168
- package/Examples/SampleUI/src/components/HelperText/utils.ts +0 -30
- package/Examples/SampleUI/src/components/Icon.tsx +0 -170
- package/Examples/SampleUI/src/components/IconButton/IconButton.tsx +0 -234
- package/Examples/SampleUI/src/components/IconButton/utils.ts +0 -190
- package/Examples/SampleUI/src/components/List/List.tsx +0 -20
- package/Examples/SampleUI/src/components/List/ListAccordion.tsx +0 -391
- package/Examples/SampleUI/src/components/List/ListAccordionGroup.tsx +0 -88
- package/Examples/SampleUI/src/components/List/ListIcon.tsx +0 -79
- package/Examples/SampleUI/src/components/List/ListImage.tsx +0 -89
- package/Examples/SampleUI/src/components/List/ListItem.tsx +0 -313
- package/Examples/SampleUI/src/components/List/ListSection.tsx +0 -87
- package/Examples/SampleUI/src/components/List/ListSubheader.tsx +0 -79
- package/Examples/SampleUI/src/components/List/utils.ts +0 -113
- package/Examples/SampleUI/src/components/MaterialCommunityIcon.tsx +0 -121
- package/Examples/SampleUI/src/components/Menu/Menu.tsx +0 -711
- package/Examples/SampleUI/src/components/Menu/MenuItem.tsx +0 -257
- package/Examples/SampleUI/src/components/Menu/utils.ts +0 -110
- package/Examples/SampleUI/src/components/Modal.tsx +0 -245
- package/Examples/SampleUI/src/components/Portal/Portal.tsx +0 -69
- package/Examples/SampleUI/src/components/Portal/PortalConsumer.tsx +0 -44
- package/Examples/SampleUI/src/components/Portal/PortalHost.tsx +0 -143
- package/Examples/SampleUI/src/components/Portal/PortalManager.tsx +0 -54
- package/Examples/SampleUI/src/components/ProgressBar.tsx +0 -292
- package/Examples/SampleUI/src/components/RadioButton/RadioButton.tsx +0 -86
- package/Examples/SampleUI/src/components/RadioButton/RadioButtonAndroid.tsx +0 -202
- package/Examples/SampleUI/src/components/RadioButton/RadioButtonGroup.tsx +0 -67
- package/Examples/SampleUI/src/components/RadioButton/RadioButtonIOS.tsx +0 -130
- package/Examples/SampleUI/src/components/RadioButton/RadioButtonItem.tsx +0 -268
- package/Examples/SampleUI/src/components/RadioButton/index.ts +0 -22
- package/Examples/SampleUI/src/components/RadioButton/utils.ts +0 -37
- package/Examples/SampleUI/src/components/Searchbar.tsx +0 -459
- package/Examples/SampleUI/src/components/SegmentedButtons/SegmentedButtonItem.tsx +0 -271
- package/Examples/SampleUI/src/components/SegmentedButtons/SegmentedButtons.tsx +0 -197
- package/Examples/SampleUI/src/components/SegmentedButtons/utils.ts +0 -179
- package/Examples/SampleUI/src/components/Snackbar.tsx +0 -430
- package/Examples/SampleUI/src/components/Surface.tsx +0 -376
- package/Examples/SampleUI/src/components/Switch/Switch.tsx +0 -108
- package/Examples/SampleUI/src/components/Switch/utils.ts +0 -113
- package/Examples/SampleUI/src/components/TextInput/Addons/Outline.tsx +0 -64
- package/Examples/SampleUI/src/components/TextInput/Addons/Underline.tsx +0 -78
- package/Examples/SampleUI/src/components/TextInput/Adornment/TextInputAdornment.tsx +0 -208
- package/Examples/SampleUI/src/components/TextInput/Adornment/TextInputAffix.tsx +0 -212
- package/Examples/SampleUI/src/components/TextInput/Adornment/TextInputIcon.tsx +0 -195
- package/Examples/SampleUI/src/components/TextInput/Adornment/enums.tsx +0 -12
- package/Examples/SampleUI/src/components/TextInput/Adornment/types.tsx +0 -11
- package/Examples/SampleUI/src/components/TextInput/Adornment/utils.ts +0 -48
- package/Examples/SampleUI/src/components/TextInput/Label/InputLabel.tsx +0 -217
- package/Examples/SampleUI/src/components/TextInput/Label/LabelBackground.tsx +0 -100
- package/Examples/SampleUI/src/components/TextInput/TextInput.tsx +0 -572
- package/Examples/SampleUI/src/components/TextInput/TextInputFlat.tsx +0 -475
- package/Examples/SampleUI/src/components/TextInput/TextInputOutlined.tsx +0 -450
- package/Examples/SampleUI/src/components/TextInput/constants.tsx +0 -48
- package/Examples/SampleUI/src/components/TextInput/helpers.tsx +0 -612
- package/Examples/SampleUI/src/components/TextInput/types.tsx +0 -155
- package/Examples/SampleUI/src/components/ToggleButton/ToggleButton.tsx +0 -187
- package/Examples/SampleUI/src/components/ToggleButton/ToggleButtonGroup.tsx +0 -72
- package/Examples/SampleUI/src/components/ToggleButton/ToggleButtonRow.tsx +0 -107
- package/Examples/SampleUI/src/components/ToggleButton/index.ts +0 -16
- package/Examples/SampleUI/src/components/ToggleButton/utils.ts +0 -26
- package/Examples/SampleUI/src/components/Tooltip/Tooltip.tsx +0 -249
- package/Examples/SampleUI/src/components/Tooltip/utils.ts +0 -129
- package/Examples/SampleUI/src/components/TouchableRipple/Pressable.tsx +0 -41
- package/Examples/SampleUI/src/components/TouchableRipple/TouchableRipple.native.tsx +0 -145
- package/Examples/SampleUI/src/components/TouchableRipple/TouchableRipple.tsx +0 -317
- package/Examples/SampleUI/src/components/TouchableRipple/utils.ts +0 -66
- package/Examples/SampleUI/src/components/Typography/AnimatedText.tsx +0 -107
- package/Examples/SampleUI/src/components/Typography/Text.tsx +0 -184
- package/Examples/SampleUI/src/components/Typography/types.tsx +0 -5
- package/Examples/SampleUI/src/components/Typography/v2/Caption.tsx +0 -50
- package/Examples/SampleUI/src/components/Typography/v2/Headline.tsx +0 -52
- package/Examples/SampleUI/src/components/Typography/v2/Paragraph.tsx +0 -49
- package/Examples/SampleUI/src/components/Typography/v2/StyledText.tsx +0 -56
- package/Examples/SampleUI/src/components/Typography/v2/Subheading.tsx +0 -50
- package/Examples/SampleUI/src/components/Typography/v2/Text.tsx +0 -62
- package/Examples/SampleUI/src/components/Typography/v2/Title.tsx +0 -49
- package/Examples/SampleUI/src/components/Typography/v2/index.ts +0 -5
- package/Examples/SampleUI/src/core/PaperProvider.tsx +0 -122
- package/Examples/SampleUI/src/core/SafeAreaProviderCompat.tsx +0 -65
- package/Examples/SampleUI/src/core/settings.tsx +0 -23
- package/Examples/SampleUI/src/core/theming.tsx +0 -170
- package/Examples/SampleUI/src/index.native.tsx +0 -285
- package/Examples/SampleUI/src/index.tsx +0 -226
- package/Examples/SampleUI/src/react-navigation/index.tsx +0 -19
- package/Examples/SampleUI/src/react-navigation/navigators/createMaterialBottomTabNavigator.tsx +0 -72
- package/Examples/SampleUI/src/react-navigation/types.tsx +0 -126
- package/Examples/SampleUI/src/react-navigation/views/MaterialBottomTabView.tsx +0 -140
- package/Examples/SampleUI/src/styles/__tests__/fonts.test.js +0 -290
- package/Examples/SampleUI/src/styles/fonts.tsx +0 -143
- package/Examples/SampleUI/src/styles/overlay.tsx +0 -70
- package/Examples/SampleUI/src/styles/shadow.tsx +0 -109
- package/Examples/SampleUI/src/styles/themes/index.ts +0 -4
- package/Examples/SampleUI/src/styles/themes/v2/DarkTheme.tsx +0 -30
- package/Examples/SampleUI/src/styles/themes/v2/LightTheme.tsx +0 -30
- package/Examples/SampleUI/src/styles/themes/v2/colors.tsx +0 -277
- package/Examples/SampleUI/src/styles/themes/v3/DarkTheme.tsx +0 -66
- package/Examples/SampleUI/src/styles/themes/v3/LightTheme.tsx +0 -69
- package/Examples/SampleUI/src/styles/themes/v3/tokens.tsx +0 -230
- package/Examples/SampleUI/src/utils/BackHandler/BackHandler.native.tsx +0 -3
- package/Examples/SampleUI/src/utils/BackHandler/BackHandler.tsx +0 -11
- package/Examples/SampleUI/src/utils/addEventListener.tsx +0 -56
- package/Examples/SampleUI/src/utils/forwardRef.tsx +0 -23
- package/Examples/SampleUI/src/utils/getContrastingColor.tsx +0 -15
- package/Examples/SampleUI/src/utils/hasTouchHandler.tsx +0 -23
- package/Examples/SampleUI/src/utils/roundLayoutSize.ts +0 -2
- package/Examples/SampleUI/src/utils/splitStyles.ts +0 -60
- package/Examples/SampleUI/src/utils/useAnimatedValue.tsx +0 -9
- package/Examples/SampleUI/src/utils/useAnimatedValueArray.tsx +0 -13
- package/Examples/SampleUI/src/utils/useIsKeyboardShown.tsx +0 -55
- package/Examples/SampleUI/src/utils/useLayout.tsx +0 -29
- package/Examples/SampleUI/src/utils/useLazyRef.tsx +0 -11
- package/Examples/SampleUI/tsconfig.json +0 -3
- package/Examples/SampleUI/utils/index.ts +0 -1426
- package/cli/__tests__/doctor.test.mjs +0 -88
package/src/TLTRN.ts
CHANGED
|
@@ -54,7 +54,7 @@ class TLTRN {
|
|
|
54
54
|
static displayDebug = false;
|
|
55
55
|
|
|
56
56
|
static myTimer = {
|
|
57
|
-
handle: null as
|
|
57
|
+
handle: null as ReturnType<typeof setInterval> | null,
|
|
58
58
|
started: 0,
|
|
59
59
|
time: 1000,
|
|
60
60
|
/**
|
|
@@ -110,11 +110,44 @@ class TLTRN {
|
|
|
110
110
|
return result;
|
|
111
111
|
};
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Sentinel for the native `delay` argument meaning "use the
|
|
115
|
+
* `CaptureLayoutDelay` configured for this screen". Both bridges resolve it
|
|
116
|
+
* from the layout config; anything >= 0 is an explicit delay in
|
|
117
|
+
* milliseconds.
|
|
118
|
+
*/
|
|
119
|
+
static USE_CONFIGURED_CAPTURE_DELAY = -1;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Captures the layout of the current screen.
|
|
123
|
+
*
|
|
124
|
+
* @param name Screen name to associate with the capture.
|
|
125
|
+
* @param delayMs Milliseconds to wait before capturing. Omit it to use the
|
|
126
|
+
* `CaptureLayoutDelay` from `ConnectConfig.json` — that is the setting to
|
|
127
|
+
* reach for when a screen transition animation is still running and the
|
|
128
|
+
* capture would otherwise catch a half-rendered screen. Pass `0` to
|
|
129
|
+
* capture immediately.
|
|
130
|
+
*
|
|
131
|
+
* Passing no delay used to send a hardcoded `0`, which made
|
|
132
|
+
* `CaptureLayoutDelay` inert for React Native apps and fired the capture at
|
|
133
|
+
* the *start* of the transition rather than after it.
|
|
134
|
+
*
|
|
135
|
+
* @returns With no `delayMs` — the normal case — only that the capture was
|
|
136
|
+
* **scheduled**, not that it produced a layout message. The native
|
|
137
|
+
* deferred overload dispatches and returns immediately, so anything that
|
|
138
|
+
* goes wrong once it runs (no view controller resolved, layout capture
|
|
139
|
+
* gated off by config) cannot be reflected here; those surface in logcat
|
|
140
|
+
* / os_log instead. Pass `0` and the value describes the capture itself,
|
|
141
|
+
* at the cost of capturing mid-transition.
|
|
142
|
+
*/
|
|
143
|
+
static logScreenLayout = (name: string | undefined, delayMs?: number) => {
|
|
114
144
|
TLTRN.currentScreen = name || '';
|
|
115
145
|
let result = false
|
|
116
146
|
try {
|
|
117
|
-
result = AcousticConnectRN.logScreenLayout(
|
|
147
|
+
result = AcousticConnectRN.logScreenLayout(
|
|
148
|
+
TLTRN.currentScreen,
|
|
149
|
+
delayMs === undefined ? TLTRN.USE_CONFIGURED_CAPTURE_DELAY : delayMs
|
|
150
|
+
);
|
|
118
151
|
} catch (error: Error | any) {
|
|
119
152
|
console.log('LogScreenLayout error: ', error.message);
|
|
120
153
|
}
|
|
@@ -168,8 +201,86 @@ class TLTRN {
|
|
|
168
201
|
return result;
|
|
169
202
|
};
|
|
170
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Keys already warned about, so a call site inside a render or a list loop
|
|
206
|
+
* warns once rather than on every pass.
|
|
207
|
+
*/
|
|
208
|
+
static warnedNestedValueSites = new Set<string>();
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Cap on {@link warnedNestedValueSites}.
|
|
212
|
+
*
|
|
213
|
+
* The site key includes the nested keys' names, so a payload built from an
|
|
214
|
+
* API response — per-record ids, timestamps — makes every call a distinct
|
|
215
|
+
* site, and the set would then grow for the life of the session. By the
|
|
216
|
+
* hundredth distinct shape the warning has made its point, so it stops
|
|
217
|
+
* instead of accumulating: bounded memory matters more than warning about
|
|
218
|
+
* shape 101.
|
|
219
|
+
*/
|
|
220
|
+
static WARNED_NESTED_VALUE_SITES_MAX = 100;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Warns when a flat-values payload carries a nested object or array.
|
|
224
|
+
*
|
|
225
|
+
* `logCustomEvent`/`logDialogCustomEvent` are typed for flat scalars, but
|
|
226
|
+
* TypeScript types are erased at runtime: a payload built from an API
|
|
227
|
+
* response, widened through `any`, or passed from untyped JS reaches the
|
|
228
|
+
* bridge with its nesting intact. Both platforms then reshape it silently —
|
|
229
|
+
* Android's SDK chain is typed `HashMap<String, String>` end to end, so a
|
|
230
|
+
* nested value is stringified into whatever its `toString()` yields — and
|
|
231
|
+
* the call still returns `true`. `logSignal` is the API that carries nested
|
|
232
|
+
* JSON on both platforms.
|
|
233
|
+
*
|
|
234
|
+
* Warning only: the payload is passed through untouched, so this changes no
|
|
235
|
+
* behaviour and cannot break a caller who is relying on today's reshaping.
|
|
236
|
+
*
|
|
237
|
+
* @param api Name of the calling API, for the message.
|
|
238
|
+
* @param values The payload about to cross the bridge.
|
|
239
|
+
*/
|
|
240
|
+
static warnOnNestedValues = (api: string, values: Record<string, unknown>) => {
|
|
241
|
+
if (values == null || typeof values !== 'object') {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const nested = Object.keys(values).filter((key) => {
|
|
245
|
+
const value = (values as Record<string, unknown>)[key];
|
|
246
|
+
return typeof value === 'object' && value !== null;
|
|
247
|
+
});
|
|
248
|
+
if (nested.length === 0) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const site = `${api}:${nested.sort().join(',')}`;
|
|
252
|
+
if (TLTRN.warnedNestedValueSites.has(site)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (TLTRN.warnedNestedValueSites.size >= TLTRN.WARNED_NESTED_VALUE_SITES_MAX) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
TLTRN.warnedNestedValueSites.add(site);
|
|
259
|
+
console.warn(
|
|
260
|
+
`TLTRN.${api}: nested value(s) [${nested.sort().join(', ')}] will be flattened — ` +
|
|
261
|
+
`${api} carries flat scalars only, and the native SDKs reshape anything else ` +
|
|
262
|
+
`without reporting it. Use logSignal for nested JSON; it is carried intact on ` +
|
|
263
|
+
`both platforms.`
|
|
264
|
+
);
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Logs a custom event.
|
|
269
|
+
*
|
|
270
|
+
* @param eventName Event name, as it appears in the posted JSON.
|
|
271
|
+
* @param values Flat key/value pairs. Nested objects and arrays are NOT
|
|
272
|
+
* supported here and are reshaped by the native SDKs — use `logSignal`
|
|
273
|
+
* for nested JSON.
|
|
274
|
+
* @param level Monitoring level for this event.
|
|
275
|
+
* @returns Whether the native SDK **accepted the event for delivery** —
|
|
276
|
+
* not whether the collector received it. The event is queued locally and
|
|
277
|
+
* posted later, so no return value from this call can attest to delivery;
|
|
278
|
+
* a `true` here means only that the SDK took the event. A `false` is also
|
|
279
|
+
* logged natively (logcat / os_log) so the rejection is visible.
|
|
280
|
+
*/
|
|
171
281
|
static logCustomEvent = async (eventName: string, values: Record<string, string | number | boolean>, level: number) => {
|
|
172
282
|
let result = false
|
|
283
|
+
TLTRN.warnOnNestedValues('logCustomEvent', values);
|
|
173
284
|
try {
|
|
174
285
|
result = AcousticConnectRN.logCustomEvent(eventName, values, level);
|
|
175
286
|
} catch (error: Error | any) {
|
|
@@ -209,8 +320,15 @@ class TLTRN {
|
|
|
209
320
|
return result;
|
|
210
321
|
};
|
|
211
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Logs a custom event tied to a dialog.
|
|
325
|
+
*
|
|
326
|
+
* Same flat-values contract and same return-value meaning as
|
|
327
|
+
* {@link logCustomEvent} — it routes to the same native API.
|
|
328
|
+
*/
|
|
212
329
|
static logDialogCustomEvent = async (dialogId: string, eventName: string, values: Record<string, string | number | boolean>) => {
|
|
213
330
|
let result = false
|
|
331
|
+
TLTRN.warnOnNestedValues('logDialogCustomEvent', values);
|
|
214
332
|
try {
|
|
215
333
|
result = AcousticConnectRN.logDialogCustomEvent(dialogId, eventName, values);
|
|
216
334
|
} catch (error: Error | any) {
|
|
@@ -356,7 +474,10 @@ class TLTRN {
|
|
|
356
474
|
static logTeal = async () => {
|
|
357
475
|
try {
|
|
358
476
|
TLTRN.isLoggingData = 1;
|
|
359
|
-
var res = await AcousticConnectRN.logScreenLayout(
|
|
477
|
+
var res = await AcousticConnectRN.logScreenLayout(
|
|
478
|
+
TLTRN.currentScreen,
|
|
479
|
+
TLTRN.USE_CONFIGURED_CAPTURE_DELAY
|
|
480
|
+
);
|
|
360
481
|
var dict = { ReactLayoutTime: TLTRN.totalRenderTime };
|
|
361
482
|
var result = await AcousticConnectRN.logCustomEvent("ReactPlugin", dict, 1);
|
|
362
483
|
if (TLTRN.displayDebug) {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* prohibited.
|
|
9
9
|
********************************************************************************************/
|
|
10
10
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
11
|
-
import { View, StyleSheet
|
|
11
|
+
import { View, StyleSheet } from "react-native";
|
|
12
12
|
import type { LayoutChangeEvent } from "react-native"; // Use type-only import for LayoutChangeEvent
|
|
13
13
|
import TLTRN from '../TLTRN';
|
|
14
14
|
|
|
@@ -76,14 +76,13 @@ const Connect: React.FC<ConnectProps> = ({
|
|
|
76
76
|
// ref is usable, then flip `navReady` to subscribe. The direct-child case
|
|
77
77
|
// resolves on the first synchronous check (no polling, no warning). If the
|
|
78
78
|
// ref never attaches within the grace window we warn once, as before.
|
|
79
|
-
// See CA-144314.
|
|
80
79
|
useEffect(() => {
|
|
81
80
|
// Reset readiness whenever the resolved ref changes. Without this, a
|
|
82
81
|
// `navigationRef` prop swap leaves `navReady` stale-true, so the
|
|
83
82
|
// subscription effect below re-runs and attaches `addListener` to the
|
|
84
83
|
// old container (whose `.current` is still non-null mid-transition)
|
|
85
84
|
// before the new ref is validated. Resetting forces re-validation
|
|
86
|
-
// through `isUsable()` before tracking re-enables.
|
|
85
|
+
// through `isUsable()` before tracking re-enables.
|
|
87
86
|
setNavReady(false);
|
|
88
87
|
|
|
89
88
|
const isUsable = () =>
|
|
@@ -132,14 +131,28 @@ const Connect: React.FC<ConnectProps> = ({
|
|
|
132
131
|
|
|
133
132
|
// Listen for the 'state' event to track navigation state changes
|
|
134
133
|
const unsubscribeState = navigation.current.addListener("state", () => {
|
|
135
|
-
|
|
134
|
+
// extractName resolves the focused route through the nested
|
|
135
|
+
// navigators itself, so there is no outer-level fallback to chain
|
|
136
|
+
// here — one used to be appended, which reported the tab name for
|
|
137
|
+
// every push inside that tab.
|
|
138
|
+
currentRoute.current = extractName(navigation);
|
|
136
139
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
// Both platforms take the same path. iOS used to be excluded from
|
|
141
|
+
// the layout call, which left the wrapper with no layout trigger
|
|
142
|
+
// at all there: the one remaining bridge caller was TLTRN's
|
|
143
|
+
// render-settle timer, so a plain navigation captured nothing.
|
|
144
|
+
if (!currentRoute.current) {
|
|
145
|
+
return;
|
|
142
146
|
}
|
|
147
|
+
TLTRN.logScreenViewPageName(currentRoute.current);
|
|
148
|
+
// Deliberately no delay argument. TLTRN then sends its
|
|
149
|
+
// "use the configured CaptureLayoutDelay" sentinel, so the capture
|
|
150
|
+
// is deferred past the transition. Passing 0 would select the
|
|
151
|
+
// native synchronous overload instead, which captures on the
|
|
152
|
+
// calling thread at the *start* of the transition — React
|
|
153
|
+
// Navigation fires 'state' before the animation runs — and makes
|
|
154
|
+
// CaptureLayoutDelay inert.
|
|
155
|
+
TLTRN.logScreenLayout(currentRoute.current);
|
|
143
156
|
});
|
|
144
157
|
|
|
145
158
|
// Cleanup listeners when the component unmounts or dependencies change
|
|
@@ -149,12 +162,9 @@ const Connect: React.FC<ConnectProps> = ({
|
|
|
149
162
|
}, [navReady, navigation]);
|
|
150
163
|
|
|
151
164
|
const onStartShouldSetResponderCapture = useCallback((event: any) => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (currentRoute.current) {
|
|
156
|
-
TLTRN.logScreenViewPageName(currentRoute.current);
|
|
157
|
-
}
|
|
165
|
+
currentRoute.current = extractName(navigation);
|
|
166
|
+
if (currentRoute.current) {
|
|
167
|
+
TLTRN.logScreenViewPageName(currentRoute.current);
|
|
158
168
|
}
|
|
159
169
|
TLTRN.logClickEvent(event);
|
|
160
170
|
return false; // Must remain false so events bubble to the host app's handlers
|
|
@@ -166,13 +176,18 @@ const Connect: React.FC<ConnectProps> = ({
|
|
|
166
176
|
}
|
|
167
177
|
initial.current = true;
|
|
168
178
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
179
|
+
// Resolved through extractName like the other two triggers. This site
|
|
180
|
+
// used to read `getCurrentRoute()?.name` directly, so a `params.name`
|
|
181
|
+
// override was honoured on navigation but silently ignored for the
|
|
182
|
+
// first-paint screen — the same screen reported under two names.
|
|
183
|
+
currentRoute.current = extractName(navigation);
|
|
184
|
+
// Same unification as the 'state' listener above: the split sent
|
|
185
|
+
// only a screenview on iOS and only a layout on Android, so
|
|
186
|
+
// neither platform got both from the first-paint trigger. No delay
|
|
187
|
+
// argument, for the reason given there.
|
|
188
|
+
if (currentRoute.current) {
|
|
189
|
+
TLTRN.logScreenViewPageName(currentRoute.current);
|
|
190
|
+
TLTRN.logScreenLayout(currentRoute.current);
|
|
176
191
|
}
|
|
177
192
|
return true;
|
|
178
193
|
}, [navigation]);
|
|
@@ -190,13 +205,121 @@ const Connect: React.FC<ConnectProps> = ({
|
|
|
190
205
|
);
|
|
191
206
|
};
|
|
192
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Walks a React Navigation state down to the deepest **focused** route.
|
|
210
|
+
*
|
|
211
|
+
* Nested navigators are the default architecture of production RN apps: a tab
|
|
212
|
+
* navigator whose tabs each hold a stack. The container's root state then
|
|
213
|
+
* describes only the outer level, and the route that the user is actually
|
|
214
|
+
* looking at lives in `routes[index].state`, recursively. Reading the outer
|
|
215
|
+
* level alone reports the *tab* name for every push inside that tab, so screen
|
|
216
|
+
* changes below the first level are invisible to analytics and replay.
|
|
217
|
+
*
|
|
218
|
+
* `index` can legitimately be absent on a partial/rehydrated state, in which
|
|
219
|
+
* case React Navigation treats the last route as focused — matched here.
|
|
220
|
+
*
|
|
221
|
+
* A depth cap guards against a malformed state whose nesting cycles; 32 is far
|
|
222
|
+
* past any real navigator tree.
|
|
223
|
+
*/
|
|
224
|
+
function findFocusedRoute(state: any): any {
|
|
225
|
+
let current = state;
|
|
226
|
+
let depth = 0;
|
|
227
|
+
while (current?.routes?.length && depth++ < 32) {
|
|
228
|
+
const index = current.index ?? current.routes.length - 1;
|
|
229
|
+
const route = current.routes[index];
|
|
230
|
+
if (!route?.state?.routes?.length) {
|
|
231
|
+
return route;
|
|
232
|
+
}
|
|
233
|
+
current = route.state;
|
|
234
|
+
}
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Containers already reported by {@link warnExtractNameFailed}.
|
|
240
|
+
*
|
|
241
|
+
* Keyed by the container itself, so a ref that throws on every navigation
|
|
242
|
+
* produces one line rather than one per transition, while a genuinely
|
|
243
|
+
* different container still gets its own. A `WeakSet` holds no strong
|
|
244
|
+
* reference, so remembering a container cannot keep it alive.
|
|
245
|
+
*/
|
|
246
|
+
const extractNameErrorReported = new WeakSet<object>();
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Reports, once per container, that resolving the current route threw.
|
|
250
|
+
*
|
|
251
|
+
* A throw here is expected and harmless during teardown, which is why
|
|
252
|
+
* ``extractName`` swallows it. A ref that keeps throwing is a different
|
|
253
|
+
* matter: every screen view goes unnamed, and without a line here that looks
|
|
254
|
+
* exactly like a ref that never attached. One warning separates the two
|
|
255
|
+
* without flooding a listener that fires per navigation.
|
|
256
|
+
*/
|
|
257
|
+
function warnExtractNameFailed(container: unknown, error: unknown) {
|
|
258
|
+
if (typeof container === "object" && container !== null) {
|
|
259
|
+
if (extractNameErrorReported.has(container)) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
extractNameErrorReported.add(container);
|
|
263
|
+
}
|
|
264
|
+
console.warn(
|
|
265
|
+
"Connect: could not resolve the current route — the navigation container ref threw. " +
|
|
266
|
+
"Screen views stay unnamed while this persists (harmless if the container is unmounting). " +
|
|
267
|
+
"Cause:",
|
|
268
|
+
error
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* The screen name to report for the navigation container's current position.
|
|
274
|
+
*
|
|
275
|
+
* Resolution order:
|
|
276
|
+
*
|
|
277
|
+
* 1. The focused route resolved from `getRootState()` by ``findFocusedRoute``.
|
|
278
|
+
* Taking the state and walking it here — rather than trusting a single
|
|
279
|
+
* accessor — keeps the wrapper correct regardless of whether the host app's
|
|
280
|
+
* navigation library resolves nesting inside `getCurrentRoute()`, and works
|
|
281
|
+
* for a custom container ref that exposes state but not that helper.
|
|
282
|
+
* 2. `getCurrentRoute()`, for refs that expose no `getRootState`.
|
|
283
|
+
*
|
|
284
|
+
* Either way `params.name` wins over the route's own `name` when the host app
|
|
285
|
+
* supplies it — the documented override for giving a route a human-readable
|
|
286
|
+
* analytics name. Only a non-empty string counts, so `params: { name: '' }`
|
|
287
|
+
* falls through to the route name instead of blanking the screenview.
|
|
288
|
+
*
|
|
289
|
+
* Returns `""` when nothing resolves, which both callers treat as "skip".
|
|
290
|
+
*/
|
|
193
291
|
function extractName(navigation: any): string {
|
|
194
|
-
const
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
292
|
+
const container = navigation?.current;
|
|
293
|
+
if (!container) {
|
|
294
|
+
return "";
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
let route: any;
|
|
298
|
+
try {
|
|
299
|
+
route = findFocusedRoute(container.getRootState?.());
|
|
300
|
+
} catch (error) {
|
|
301
|
+
// A container mid-teardown can throw out of getRootState(). Screen
|
|
302
|
+
// naming is not worth taking the host app's navigation down for.
|
|
303
|
+
warnExtractNameFailed(container, error);
|
|
304
|
+
route = undefined;
|
|
305
|
+
}
|
|
306
|
+
if (!route) {
|
|
307
|
+
try {
|
|
308
|
+
route = container.getCurrentRoute?.();
|
|
309
|
+
} catch (error) {
|
|
310
|
+
warnExtractNameFailed(container, error);
|
|
311
|
+
route = undefined;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (!route) {
|
|
315
|
+
return "";
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const overridden = route.params?.name;
|
|
319
|
+
if (typeof overridden === "string" && overridden.length > 0) {
|
|
320
|
+
return overridden;
|
|
198
321
|
}
|
|
199
|
-
return "";
|
|
322
|
+
return typeof route.name === "string" ? route.name : "";
|
|
200
323
|
}
|
|
201
324
|
|
|
202
325
|
export default Connect;
|
package/src/index.ts
CHANGED
|
@@ -41,4 +41,9 @@ try {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export { Connect, TLTRN, KeyboardListener, DialogListener, useDialogTracking, DialogDebugger, withAcousticAutoDialog }
|
|
44
|
+
|
|
45
|
+
// Re-exported so callers can name a `logSignal` payload without importing
|
|
46
|
+
// from `react-native-nitro-modules` — the spec aliases nitro's AnyMap only
|
|
47
|
+
// because that is the one type nitrogen accepts for arbitrary JSON.
|
|
48
|
+
export type { SignalValues } from './specs/react-native-acoustic-connect.nitro'
|
|
44
49
|
export default AcousticConnectRN
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// Created on 5/9/25.
|
|
11
11
|
//
|
|
12
12
|
|
|
13
|
-
import { type HybridObject } from 'react-native-nitro-modules'
|
|
13
|
+
import { type AnyMap, type HybridObject } from 'react-native-nitro-modules'
|
|
14
14
|
|
|
15
15
|
// Define a named type for the anonymous object
|
|
16
16
|
export type KeyValueObject = {
|
|
@@ -18,6 +18,32 @@ export type KeyValueObject = {
|
|
|
18
18
|
[key: string]: unknown;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Payload accepted by {@link AcousticConnectRN.logSignal} — any JSON-shaped
|
|
23
|
+
* object. Nested objects and arrays are allowed, so this is a superset of a
|
|
24
|
+
* flat `Record<string, string | number | boolean>`.
|
|
25
|
+
*
|
|
26
|
+
* You do not need this type to call `logSignal`: an object literal is enough.
|
|
27
|
+
* It exists for the times you want to name the payload — a helper parameter, a
|
|
28
|
+
* shared constant — and is re-exported from the package root so you never have
|
|
29
|
+
* to reach into `react-native-nitro-modules` for it:
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* import AcousticConnectRN, { type SignalValues } from 'react-native-acoustic-connect'
|
|
33
|
+
*
|
|
34
|
+
* const payload: SignalValues = { signalContent: { signalType: 'pageview' } }
|
|
35
|
+
* AcousticConnectRN.logSignal(payload, 1)
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* Aliases nitro's `AnyMap`, which is the only way to express arbitrary JSON in
|
|
40
|
+
* a Nitro spec — a hand-rolled recursive type is rejected by nitrogen, which
|
|
41
|
+
* tries to generate a struct for it. Nitrogen resolves the alias, so the
|
|
42
|
+
* generated native bindings are identical either way; the indirection exists
|
|
43
|
+
* purely to keep a third-party type name off our public API.
|
|
44
|
+
*/
|
|
45
|
+
export type SignalValues = AnyMap
|
|
46
|
+
|
|
21
47
|
export type ConnectMonitoringLevelType = 'Ignore' | 'CellularAndWiFi' | 'WiFi'
|
|
22
48
|
|
|
23
49
|
/**
|
|
@@ -123,21 +149,138 @@ export interface AcousticConnectRN extends HybridObject<{ ios: 'swift', android:
|
|
|
123
149
|
getBooleanConfigItemForKey(theDefault: boolean, key: string, moduleName: string): boolean
|
|
124
150
|
getStringItemForKey(theDefault: string, key: string, moduleName: string): string | null | undefined
|
|
125
151
|
getNumberItemForKey(theDefault: number, key: string, moduleName: string): number
|
|
152
|
+
/**
|
|
153
|
+
* Logs a named custom event with a flat set of key/value pairs.
|
|
154
|
+
*
|
|
155
|
+
* `values` is deliberately **flat** (scalars only), unlike
|
|
156
|
+
* {@link logSignal}. The Android SDK's custom-event path is typed
|
|
157
|
+
* `HashMap<String, String>` end to end (`Connect.logCustomEvent` →
|
|
158
|
+
* `Tealeaf.logCustomEvent`), so there is no native route for nested
|
|
159
|
+
* JSON. Widening this signature would compile but silently drop the
|
|
160
|
+
* nesting on Android while preserving it on iOS — a cross-platform
|
|
161
|
+
* divergence worse than the restriction. Use {@link logSignal} when the
|
|
162
|
+
* payload needs structure.
|
|
163
|
+
*
|
|
164
|
+
* @param eventName Event name; appears in the posted JSON.
|
|
165
|
+
* @param values Flat key/value pairs to attach to the event.
|
|
166
|
+
* @param level Monitoring level for this event.
|
|
167
|
+
* @returns `true` if the SDK **accepted the event for delivery** — not
|
|
168
|
+
* that the collector received it. Events are queued on device and posted
|
|
169
|
+
* in batches later, so nothing this call can return attests to delivery
|
|
170
|
+
* or to server-side acceptance. A `false` means the SDK rejected the
|
|
171
|
+
* event outright and nothing was queued; the bridge also logs that to
|
|
172
|
+
* logcat / os_log so it is visible without inspecting the return value.
|
|
173
|
+
*/
|
|
126
174
|
logCustomEvent(eventName: string, values: Record<string, string | number | boolean>, level: number): boolean
|
|
127
|
-
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Logs a signal payload.
|
|
178
|
+
*
|
|
179
|
+
* `values` accepts **arbitrary JSON** — nested objects and arrays, not
|
|
180
|
+
* just scalars — because both native SDKs embed the payload verbatim:
|
|
181
|
+
* iOS `CTSignalMessage` gates only on `NSJSONSerialization
|
|
182
|
+
* isValidJSONObject:`, and Android `Connect.logSignal` takes an untyped
|
|
183
|
+
* `HashMap<String, Any?>`. The bridge converts the map to each
|
|
184
|
+
* platform's JSON representation without flattening or reshaping it.
|
|
185
|
+
*
|
|
186
|
+
* Scalar-only callers are unaffected: {@link SignalValues} is a superset
|
|
187
|
+
* of `Record<string, string | number | boolean>`.
|
|
188
|
+
*
|
|
189
|
+
* @param values Signal payload. Objects, arrays, strings, numbers,
|
|
190
|
+
* booleans and `null` are all carried through.
|
|
191
|
+
* @param level Monitoring level for this signal.
|
|
192
|
+
* @returns `true` if the SDK **accepted the signal for delivery** — not
|
|
193
|
+
* that the collector received it, and not that it passed server-side
|
|
194
|
+
* schema validation. Signals are queued on device and posted later, so
|
|
195
|
+
* nothing this call can return attests to delivery. A `false` means the
|
|
196
|
+
* SDK rejected it and nothing was queued; the bridge logs that to
|
|
197
|
+
* logcat / os_log.
|
|
198
|
+
*
|
|
199
|
+
* @remarks
|
|
200
|
+
* **Android version boundary — top-level numbers.** The Android SDK's
|
|
201
|
+
* `JsonUtil.getHashValues` gained a `Number` branch in Connect Android
|
|
202
|
+
* **11.0.24-beta**, so from that version a top-level numeric value is
|
|
203
|
+
* carried. Earlier versions serialised only `String`, `Boolean`,
|
|
204
|
+
* `JSONObject`, `JSONArray` and `byte[]` at the top level of the signal
|
|
205
|
+
* map and dropped a top-level number. Numbers nested *inside* an object
|
|
206
|
+
* or array were never affected, because the bridge builds those
|
|
207
|
+
* `JSONObject`/`JSONArray` values itself, and iOS has always carried
|
|
208
|
+
* top-level numbers normally. Both versions sit inside the
|
|
209
|
+
* `[11.0.11, 12.0.0)` range this package accepts, so nest the number if
|
|
210
|
+
* your integration pins a Connect Android version below 11.0.24-beta.
|
|
211
|
+
*
|
|
212
|
+
* @example Nested payload
|
|
213
|
+
* ```ts
|
|
214
|
+
* import AcousticConnectRN from 'react-native-acoustic-connect'
|
|
215
|
+
*
|
|
216
|
+
* AcousticConnectRN.logSignal(
|
|
217
|
+
* {
|
|
218
|
+
* signalContent: {
|
|
219
|
+
* signalType: 'pageview',
|
|
220
|
+
* url: 'https://app.example.com/dashboard',
|
|
221
|
+
* pageCategory: 'dashboard',
|
|
222
|
+
* },
|
|
223
|
+
* audience: [
|
|
224
|
+
* { name: 'Account Name', value: 'Acme Corp' },
|
|
225
|
+
* { name: 'Account ID', value: '4815162342' },
|
|
226
|
+
* ],
|
|
227
|
+
* },
|
|
228
|
+
* 1
|
|
229
|
+
* )
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
logSignal(values: SignalValues, level: number): boolean
|
|
128
233
|
logExceptionEvent(message: string, stackInfo: string, unhandled: boolean): boolean
|
|
129
234
|
logLocation(): boolean
|
|
130
235
|
logLocationWithLatitudeLongitude(latitude: number, longitude: number, level: number): boolean
|
|
131
236
|
logClickEvent(target: number, controlId: string): boolean
|
|
132
237
|
logTextChangeEvent(target: number, controlId: string, text: string | null | undefined): boolean
|
|
238
|
+
/**
|
|
239
|
+
* Sets the logical screen name subsequent events are attributed to.
|
|
240
|
+
*
|
|
241
|
+
* Sets the name and nothing else — no screenview, no layout capture — on
|
|
242
|
+
* both platforms. `<Connect>` calls this on every touch so the click that
|
|
243
|
+
* follows lands on the right screen, so it has to stay cheap.
|
|
244
|
+
*
|
|
245
|
+
* Android used to route it through `Connect.resumeConnect`, which also
|
|
246
|
+
* emitted a screenview and captured a full layout, putting tens to hundreds
|
|
247
|
+
* of KB on the wire per tap where iOS sent none. Use `logScreenLayout` when
|
|
248
|
+
* a layout capture is what you want.
|
|
249
|
+
*/
|
|
133
250
|
setCurrentScreenName(logicalPageName: string): boolean
|
|
134
251
|
logScreenViewContextLoad(logicalPageName: string | null | undefined, referrer:string | null | undefined): boolean
|
|
135
252
|
logScreenViewContextUnload(logicalPageName: string | null | undefined, referrer:string | null | undefined): boolean
|
|
253
|
+
/**
|
|
254
|
+
* Captures the layout of the current screen.
|
|
255
|
+
*
|
|
256
|
+
* @param name Screen name to associate with the capture.
|
|
257
|
+
* @param delay Milliseconds to wait before capturing — the same unit as
|
|
258
|
+
* `CaptureLayoutDelay` in the layout config, on both platforms. A
|
|
259
|
+
* negative value means "use the `CaptureLayoutDelay` configured for this
|
|
260
|
+
* screen"; `0` captures immediately.
|
|
261
|
+
*
|
|
262
|
+
* Prefer `TLTRN.logScreenLayout`, which defaults to the configured delay.
|
|
263
|
+
*
|
|
264
|
+
* @returns For a `delay` of `0`, whether the capture itself succeeded. For
|
|
265
|
+
* any positive or configured delay, only that the capture was
|
|
266
|
+
* **scheduled** — the native deferred overload dispatches and returns
|
|
267
|
+
* immediately, so a `true` says nothing about what the capture found
|
|
268
|
+
* when it eventually ran. Failures after that point (no view controller
|
|
269
|
+
* resolved, config gating the capture off) surface in logcat / os_log,
|
|
270
|
+
* not here.
|
|
271
|
+
*/
|
|
136
272
|
logScreenLayout(name: string, delay: number): boolean
|
|
137
273
|
// New dialog event handling methods
|
|
138
274
|
logDialogShowEvent(dialogId: string, dialogTitle: string, dialogType: string): boolean
|
|
139
275
|
logDialogDismissEvent(dialogId: string, dismissReason: string): boolean
|
|
140
276
|
logDialogButtonClickEvent(dialogId: string, buttonText: string, buttonIndex: number): boolean
|
|
277
|
+
/**
|
|
278
|
+
* Logs a custom event against a tracked dialog.
|
|
279
|
+
*
|
|
280
|
+
* `values` is flat for the same reason as {@link logCustomEvent} — this
|
|
281
|
+
* routes to the native custom-event API, whose Android path carries string
|
|
282
|
+
* values only.
|
|
283
|
+
*/
|
|
141
284
|
logDialogCustomEvent(dialogId: string, eventName: string, values: Record<string, string | number | boolean>): boolean
|
|
142
285
|
|
|
143
286
|
/**
|
|
@@ -161,23 +304,62 @@ export interface AcousticConnectRN extends HybridObject<{ ios: 'swift', android:
|
|
|
161
304
|
* `'loggedIn'` when omitted (identity logging typically marks a sign-in),
|
|
162
305
|
* overriding the native SDKs' own `'pageView'` default.
|
|
163
306
|
* @param additionalParameters Optional extra key/value pairs merged into the
|
|
164
|
-
* signal payload. Only when omitted (`undefined`) does the bridge supply
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* API expects it).
|
|
307
|
+
* signal payload. Only when omitted (`undefined`) does the bridge supply a
|
|
308
|
+
* default, and that default follows the resolved `signalType` — see
|
|
309
|
+
* **Required method attribute** below. An explicitly-provided map is used
|
|
310
|
+
* as-is, so passing an empty `{}` sends no extra parameters (the default is
|
|
311
|
+
* not merged in). A `'url'` entry is honoured uniformly on both platforms:
|
|
312
|
+
* on Android it is routed to the SDK's explicit `url` parameter, on iOS it
|
|
313
|
+
* rides inside the parameter map (where the native API expects it).
|
|
171
314
|
* @returns A promise resolving to `true` if the identity signal was
|
|
172
315
|
* dispatched, `false` otherwise (including the blank-identifier case).
|
|
173
316
|
* Never rejects.
|
|
174
317
|
*
|
|
175
|
-
*
|
|
318
|
+
* ### Required method attribute
|
|
319
|
+
*
|
|
320
|
+
* Identity signals must carry a *method* attribute, and the key Connect
|
|
321
|
+
* requires depends on the signal type:
|
|
322
|
+
*
|
|
323
|
+
* | `signalType` | Required attribute |
|
|
324
|
+
* | -------------------- | -------------------- |
|
|
325
|
+
* | `'loggedIn'` | `loginMethod` |
|
|
326
|
+
* | `'accountRegistered'`| `registrationMethod` |
|
|
327
|
+
*
|
|
328
|
+
* Send the wrong key and the signal fails schema validation and is
|
|
329
|
+
* discarded server-side — while this promise still resolves `true`, because
|
|
330
|
+
* the native SDKs report only that the signal was queued. If you pass
|
|
331
|
+
* `additionalParameters` explicitly, you own supplying the right key.
|
|
332
|
+
*
|
|
333
|
+
* @example Sign-in — `loginMethod` is required
|
|
176
334
|
* ```ts
|
|
177
335
|
* import AcousticConnectRN from 'react-native-acoustic-connect'
|
|
178
336
|
*
|
|
337
|
+
* await AcousticConnectRN.logIdentity('Email', 'user@example.com', 'loggedIn', {
|
|
338
|
+
* loginMethod: 'sso',
|
|
339
|
+
* })
|
|
340
|
+
*
|
|
341
|
+
* // Omitting both arguments is equivalent to the above with
|
|
342
|
+
* // `{ loginMethod: 'email' }` — the bridge defaults to a `loggedIn` signal.
|
|
179
343
|
* await AcousticConnectRN.logIdentity('Email', 'user@example.com')
|
|
180
344
|
* ```
|
|
345
|
+
*
|
|
346
|
+
* @example Registration — `registrationMethod` is required
|
|
347
|
+
* ```ts
|
|
348
|
+
* await AcousticConnectRN.logIdentity(
|
|
349
|
+
* 'Email',
|
|
350
|
+
* 'user@example.com',
|
|
351
|
+
* 'accountRegistered',
|
|
352
|
+
* { registrationMethod: 'email' }
|
|
353
|
+
* )
|
|
354
|
+
* ```
|
|
355
|
+
*
|
|
356
|
+
* @returns `true` if the SDK **accepted the identity signal for
|
|
357
|
+
* delivery**. It does not mean the signal reached the collector, and it
|
|
358
|
+
* does not mean the collector kept it — a schema-invalid signal (the
|
|
359
|
+
* wrong method key above) is discarded server-side after resolving
|
|
360
|
+
* `true` here. Never rejects. A `false` means the SDK rejected the call
|
|
361
|
+
* locally, e.g. a blank identifier; the bridge logs that to logcat /
|
|
362
|
+
* os_log.
|
|
181
363
|
*/
|
|
182
364
|
logIdentity(
|
|
183
365
|
identifierName: string,
|