diff --git a/packages/plugin-session-replay-react-native/amplitude-plugin-session-replay-react-native.podspec b/packages/plugin-session-replay-react-native/amplitude-plugin-session-replay-react-native.podspec index 03329014d..4c0b82696 100644 --- a/packages/plugin-session-replay-react-native/amplitude-plugin-session-replay-react-native.podspec +++ b/packages/plugin-session-replay-react-native/amplitude-plugin-session-replay-react-native.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm,swift}" - s.dependency 'AmplitudeSessionReplay', '>=0.0.15' + s.dependency 'AmplitudeSessionReplay', '>=0.1.0' # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. diff --git a/packages/plugin-session-replay-react-native/android/build.gradle b/packages/plugin-session-replay-react-native/android/build.gradle index 2bca9df8a..f3ce5d8b2 100644 --- a/packages/plugin-session-replay-react-native/android/build.gradle +++ b/packages/plugin-session-replay-react-native/android/build.gradle @@ -90,7 +90,7 @@ repositories { def kotlin_version = getExtOrDefault("kotlinVersion") dependencies { - implementation("com.amplitude:session-replay-android:[0.15.5, 1.0.0]") + implementation("com.amplitude:session-replay-android:[0.16.4, 1.0.0]") // For < 0.71, this will be from the local maven repo // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin diff --git a/packages/plugin-session-replay-react-native/example/.eslintrc.js b/packages/plugin-session-replay-react-native/example/.eslintrc.js new file mode 100644 index 000000000..187894b6a --- /dev/null +++ b/packages/plugin-session-replay-react-native/example/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: '@react-native', +}; diff --git a/packages/plugin-session-replay-react-native/example/.gitignore b/packages/plugin-session-replay-react-native/example/.gitignore new file mode 100644 index 000000000..d5ae45669 --- /dev/null +++ b/packages/plugin-session-replay-react-native/example/.gitignore @@ -0,0 +1,74 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +**/.xcode.env.local + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml +*.hprof +.cxx/ +*.keystore +!debug.keystore + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/ + +**/fastlane/report.xml +**/fastlane/Preview.html +**/fastlane/screenshots +**/fastlane/test_output + +# Bundle artifact +*.jsbundle + +# Ruby / CocoaPods +**/Pods/ +/vendor/bundle/ + +# Temporary files created by Metro to check the health of the file watcher +.metro-health-check* + +# testing +/coverage + +# Yarn +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions diff --git a/packages/plugin-session-replay-react-native/example/.prettierrc.js b/packages/plugin-session-replay-react-native/example/.prettierrc.js new file mode 100644 index 000000000..2b540746a --- /dev/null +++ b/packages/plugin-session-replay-react-native/example/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + arrowParens: 'avoid', + bracketSameLine: true, + bracketSpacing: false, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/packages/plugin-session-replay-react-native/example/src/App.tsx b/packages/plugin-session-replay-react-native/example/App.tsx similarity index 91% rename from packages/plugin-session-replay-react-native/example/src/App.tsx rename to packages/plugin-session-replay-react-native/example/App.tsx index 8a7b52040..172f9b4cc 100644 --- a/packages/plugin-session-replay-react-native/example/src/App.tsx +++ b/packages/plugin-session-replay-react-native/example/App.tsx @@ -22,6 +22,7 @@ import { useColorScheme, View, } from 'react-native'; +import { WebView } from 'react-native-webview'; import { Colors, @@ -96,6 +97,10 @@ type ViewGalleryScreenNavigationProps = NativeStackScreenProps< RootStackParamList, 'ViewGallery' >; +type WebViewScreenNavigationProps = NativeStackScreenProps< + RootStackParamList, + 'WebView' +>; function HomeScreen({ navigation }: HomeScreenNavigationProps) { const isDarkMode = useColorScheme() === 'dark'; @@ -126,6 +131,12 @@ function HomeScreen({ navigation }: HomeScreenNavigationProps) { onPress={() => navigation.navigate('ViewGallery')} /> +
+
Edit App.tsx to change this screen and then come back to see your edits. @@ -192,6 +203,14 @@ const ViewGalleryScreen = ({ ); }; +const WebViewScreen = () => { + return ( + + + + ); +} + const SwitchExample = () => { const [isEnabled, setIsEnabled] = useState(false); const toggleSwitch = () => setIsEnabled((previousState) => !previousState); @@ -232,6 +251,7 @@ const TextInputExample = () => { type RootStackParamList = { Home: undefined; ViewGallery: undefined; + WebView: undefined; }; const Stack = createNativeStackNavigator(); @@ -265,6 +285,11 @@ function App(): React.JSX.Element { options={{ title: 'View Gallery' }} component={ViewGalleryScreen} /> + ); diff --git a/packages/plugin-session-replay-react-native/example/Gemfile b/packages/plugin-session-replay-react-native/example/Gemfile index 6a7d5c7a4..85d7f6828 100644 --- a/packages/plugin-session-replay-react-native/example/Gemfile +++ b/packages/plugin-session-replay-react-native/example/Gemfile @@ -3,5 +3,7 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version ruby ">= 2.6.10" -gem 'cocoapods', '~> 1.13' -gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' +# Exclude problematic versions of cocoapods and activesupport that causes build failures. +gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' +gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' +gem 'xcodeproj', '< 1.26.0' diff --git a/packages/plugin-session-replay-react-native/example/Gemfile.lock b/packages/plugin-session-replay-react-native/example/Gemfile.lock new file mode 100644 index 000000000..cecf454e9 --- /dev/null +++ b/packages/plugin-session-replay-react-native/example/Gemfile.lock @@ -0,0 +1,117 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.7) + base64 + nkf + rexml + activesupport (7.2.2.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + base64 (0.2.0) + benchmark (0.4.0) + bigdecimal (3.1.9) + claide (1.1.0) + cocoapods (1.15.2) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.15.2) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.23.0, < 2.0) + cocoapods-core (1.15.2) + activesupport (>= 5.0, < 8) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (2.1) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored2 (3.1.2) + concurrent-ruby (1.3.4) + connection_pool (2.4.1) + drb (2.2.1) + escape (0.0.4) + ethon (0.16.0) + ffi (>= 1.15.0) + ffi (1.17.1) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + httpclient (2.8.3) + i18n (1.14.6) + concurrent-ruby (~> 1.0) + json (2.9.1) + logger (1.6.4) + minitest (5.25.4) + molinillo (0.8.0) + nanaimo (0.3.0) + nap (1.1.0) + netrc (0.11.0) + nkf (0.2.0) + public_suffix (4.0.7) + rexml (3.4.0) + ruby-macho (2.5.1) + securerandom (0.4.1) + typhoeus (1.4.1) + ethon (>= 0.9.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + xcodeproj (1.25.1) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + rexml (>= 3.3.6, < 4.0) + +PLATFORMS + ruby + +DEPENDENCIES + activesupport (>= 6.1.7.5, != 7.1.0) + cocoapods (>= 1.13, != 1.15.1, != 1.15.0) + xcodeproj (< 1.26.0) + +RUBY VERSION + ruby 3.1.0p0 + +BUNDLED WITH + 2.5.17 diff --git a/packages/plugin-session-replay-react-native/example/README.md b/packages/plugin-session-replay-react-native/example/README.md index 6cc54fab7..e45d0ae12 100644 --- a/packages/plugin-session-replay-react-native/example/README.md +++ b/packages/plugin-session-replay-react-native/example/README.md @@ -1,23 +1,17 @@ This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). - # Getting Started - >**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. ## Step 1: Start the Metro Server - First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. - To start Metro, run the following command from the _root_ of your React Native project: - ```bash -# using npm -npm start - -# OR using Yarn +Using Yarn yarn start ``` +Note: The test app points to the RN plugin folder directly instead of getting it from npm repository. This functionality does not work with npm, so please only use yarn + ## Step 2: Start your Application Once the dev server is ready, you'll see the following options @@ -46,4 +40,4 @@ Now that you have successfully run the app, let's modify it. ## Congratulations! :tada: -You've successfully run and modified your React Native App. :partying_face: +You've successfully run and modified your React Native App. :partying_face: \ No newline at end of file diff --git a/packages/plugin-session-replay-react-native/example/__tests__/App.test.tsx b/packages/plugin-session-replay-react-native/example/__tests__/App.test.tsx new file mode 100644 index 000000000..9eac6fbc8 --- /dev/null +++ b/packages/plugin-session-replay-react-native/example/__tests__/App.test.tsx @@ -0,0 +1,17 @@ +/** + * @format + */ + +import 'react-native'; +import React from 'react'; +import App from '../App'; + +// Note: import explicitly to use the types shipped with jest. +import {it} from '@jest/globals'; + +// Note: test renderer must be required after react-native. +import renderer from 'react-test-renderer'; + +it('renders correctly', () => { + renderer.create(); +}); diff --git a/packages/plugin-session-replay-react-native/example/android/app/build.gradle b/packages/plugin-session-replay-react-native/example/android/app/build.gradle index 340e979aa..4c811729a 100644 --- a/packages/plugin-session-replay-react-native/example/android/app/build.gradle +++ b/packages/plugin-session-replay-react-native/example/android/app/build.gradle @@ -8,14 +8,14 @@ apply plugin: "com.facebook.react" */ react { /* Folders */ - // The root of your project, i.e. where "package.json" lives. Default is '..' - // root = file("../") - // The folder where the react-native NPM package is. Default is ../node_modules/react-native - // reactNativeDir = file("../node_modules/react-native") - // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen - // codegenDir = file("../node_modules/@react-native/codegen") - // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js - // cliFile = file("../node_modules/react-native/cli.js") + // The root of your project, i.e. where "package.json" lives. Default is '../..' + // root = file("../../") + // The folder where the react-native NPM package is. Default is ../../node_modules/react-native + // reactNativeDir = file("../../node_modules/react-native") + // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen + // codegenDir = file("../../node_modules/@react-native/codegen") + // The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js + // cliFile = file("../../node_modules/react-native/cli.js") /* Variants */ // The list of variants to that are debuggable. For those we're going to @@ -49,6 +49,9 @@ react { // // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" // hermesFlags = ["-O", "-output-source-map"] + + /* Autolinking */ + autolinkLibrariesWithApp() } /** @@ -74,9 +77,9 @@ android { buildToolsVersion rootProject.ext.buildToolsVersion compileSdk rootProject.ext.compileSdkVersion - namespace "amplitude.pluginsessionreplayreactnative.example" + namespace "com.example" defaultConfig { - applicationId "amplitude.pluginsessionreplayreactnative.example" + applicationId "com.example" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 @@ -107,7 +110,6 @@ android { dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") - implementation("com.facebook.react:flipper-integration") if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") @@ -115,5 +117,3 @@ dependencies { implementation jscFlavor } } - -apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) diff --git a/packages/plugin-session-replay-react-native/example/android/app/src/main/AndroidManifest.xml b/packages/plugin-session-replay-react-native/example/android/app/src/main/AndroidManifest.xml index 089054724..e1892528b 100644 --- a/packages/plugin-session-replay-react-native/example/android/app/src/main/AndroidManifest.xml +++ b/packages/plugin-session-replay-react-native/example/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ - + android:theme="@style/AppTheme" + android:supportsRtl="true"> { - // Packages that cannot be autolinked yet can be added manually here, for example: - // packages.add(new MyReactNativePackage()); - return PackageList(this).packages - } + override fun getPackages(): List = + PackageList(this).packages.apply { + // Packages that cannot be autolinked yet can be added manually here, for example: + // add(MyReactNativePackage()) + } override fun getJSMainModuleName(): String = "index" @@ -31,15 +31,14 @@ class MainApplication : Application(), ReactApplication { } override val reactHost: ReactHost - get() = getDefaultReactHost(this.applicationContext, reactNativeHost) + get() = getDefaultReactHost(applicationContext, reactNativeHost) override fun onCreate() { super.onCreate() - SoLoader.init(this, false) + SoLoader.init(this, OpenSourceMergedSoMapping) if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { // If you opted-in for the New Architecture, we load the native entry point for this app. load() } - ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager) } } diff --git a/packages/plugin-session-replay-react-native/example/android/app/src/main/res/drawable/rn_edit_text_material.xml b/packages/plugin-session-replay-react-native/example/android/app/src/main/res/drawable/rn_edit_text_material.xml index 73b37e4d9..5c25e728e 100644 --- a/packages/plugin-session-replay-react-native/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +++ b/packages/plugin-session-replay-react-native/example/android/app/src/main/res/drawable/rn_edit_text_material.xml @@ -17,7 +17,8 @@ android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material" android:insetRight="@dimen/abc_edit_text_inset_horizontal_material" android:insetTop="@dimen/abc_edit_text_inset_top_material" - android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"> + android:insetBottom="@dimen/abc_edit_text_inset_bottom_material" + >