├── .bundle └── config ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── .vscode └── launch.json ├── .watchmanconfig ├── App.tsx ├── Gemfile ├── README.md ├── __tests__ └── App.test.tsx ├── android ├── app │ ├── build.gradle │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── oneonevideocall │ │ │ ├── MainActivity.kt │ │ │ └── MainApplication.kt │ │ └── res │ │ ├── drawable │ │ └── rn_edit_text_material.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios ├── .xcode.env ├── OneOneVideoCall.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── OneOneVideoCall.xcscheme ├── OneOneVideoCall │ ├── AppDelegate.h │ ├── AppDelegate.mm │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ ├── LaunchScreen.storyboard │ ├── PrivacyInfo.xcprivacy │ └── main.m ├── OneOneVideoCallTests │ ├── Info.plist │ └── OneOneVideoCallTests.m └── Podfile ├── jest.config.js ├── metro.config.js ├── package-lock.json ├── package.json ├── src ├── EnxConferenceScreen.tsx ├── EnxJoinScreen.tsx ├── Logo.tsx └── image_asset │ ├── disconnect.png │ ├── logofront.png │ ├── menuList.png │ ├── mute.png │ ├── raise_hand.png │ ├── recording.png │ ├── speaker.png │ ├── speakermute@2x.png │ ├── startvideo.png │ ├── stopvideo.png │ ├── switchcamera.png │ └── unmute.png ├── tsconfig.json └── types └── images.d.ts /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | **/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # fastlane 44 | # 45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 46 | # screenshots whenever they are needed. 47 | # For more information about the recommended setup visit: 48 | # https://docs.fastlane.tools/best-practices/source-control/ 49 | 50 | **/fastlane/report.xml 51 | **/fastlane/Preview.html 52 | **/fastlane/screenshots 53 | **/fastlane/test_output 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # Ruby / CocoaPods 59 | **/Pods/ 60 | /vendor/bundle/ 61 | 62 | # Temporary files created by Metro to check the health of the file watcher 63 | .metro-health-check* 64 | 65 | # testing 66 | /coverage 67 | 68 | # Yarn 69 | .yarn/* 70 | !.yarn/patches 71 | !.yarn/plugins 72 | !.yarn/releases 73 | !.yarn/sdks 74 | !.yarn/versions 75 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch Chrome", 9 | "request": "launch", 10 | "type": "chrome", 11 | "url": "http://localhost:8080", 12 | "webRoot": "${workspaceFolder}" 13 | }, 14 | { 15 | "command": "npm start", 16 | "name": "Run npm start", 17 | "request": "launch", 18 | "type": "node-terminal" 19 | }, 20 | 21 | { 22 | "type": "pwa-node", 23 | "request": "launch", 24 | "name": "Launch Program", 25 | "skipFiles": [ 26 | "/**" 27 | ], 28 | "program": "${workspaceFolder}/src/EnxJoinScreen.tsx", 29 | "outFiles": [ 30 | "${workspaceFolder}/**/*.js" 31 | ] 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /App.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { NavigationContainer } from '@react-navigation/native'; 3 | import { createNativeStackNavigator } from '@react-navigation/native-stack'; 4 | import EnxJoinScreen from './src/EnxJoinScreen'; 5 | import EnxConferenceScreen from './src/EnxConferenceScreen'; 6 | 7 | const Stack = createNativeStackNavigator(); 8 | 9 | const App: React.FC = () => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | ); 18 | }; 19 | 20 | export default App; -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | # Cocoapods 1.15 introduced a bug which break the build. We will remove the upper 7 | # bound in the template on Cocoapods with next React Native release. 8 | gem 'cocoapods', '>= 1.13', '< 1.15' 9 | gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Create a Seamless 1-to-1Video Calling App with Open Source React Native: Step-by-Step Guide 2 | The sample react-native App demonstrates the use of EnableX platform Server APIs and react-native Toolkit to build 1-to-1 RTC (Real-Time Communication) Application. It allows developers to ramp up on app development by hosting on their own devices. 3 | 4 | This App creates a virtual Room on the fly hosted on the Enablex platform using REST calls and uses the Room credentials (i.e. Room Id) to connect to the virtual Room as a Moderator or Participant using a mobile client. The same Room credentials can be shared with others to join the same virtual Room to carry out an RTC (Real-Time Communication) session. 5 | 6 | EnableX Developer Center: https://developer.enablex.io/ 7 | 8 | ## 1. How to get started 9 | 10 | ### 1.1 Prerequisites 11 | 12 | #### 1.1.1 App Id and App Key 13 | 14 | * Register with EnableX [https://www.enablex.io/free-trial/] 15 | * Create your Application 16 | * Get your App ID and App Key delivered to your email 17 | 18 | #### 1.1.2 Sample React-Native Client 19 | 20 | * [Clone or download this Repository](https://github.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application.git) 21 | 22 | #### 1.1.3 Test Application Server 23 | 24 | You need to setup an Application Server to provision Web Service API for your react-native Application to enable Video Sessions. 25 | 26 | To help you try our react-native Application quickly, without having to set up an Application Server, this Application is shipped pre-configured to work in a "try" mode with EnableX hosted Application Server i.e. https://demo.enablex.io. 27 | 28 | Our Application Server restricts a single Session Duration to 10 minutes and allows 1 moderator and not more than 1 participant in a Session. 29 | 30 | Once you tried EnableX react-native Sample Application, you may need to set up your own Application Server and verify your Application to work with your Application Server. Refer to point 2 for more details on this. 31 | 32 | #### 1.1.4 Configure react-native Client 33 | 34 | 35 | * Open the App 36 | * Go to EnxJoinScreen.JS and change the following: 37 | ``` 38 | /* To try the app with Enablex hosted service you need to set the kTry = true 39 | When you setup your own Application Service, set kTry = false */*/ 40 | /*Your webservice host URL, Keet the defined host when kTry = true */ 41 | **const kBaseURL = "https://demo.enablex.io/";** 42 | /* To try the app with Enablex hosted service you need to set the kTry = true */ 43 | **const kTry = true;** 44 | /*Use enablec portal to create your app and get these following credentials*/ 45 | 46 | **const kAppId = "App-id";** 47 | **const kAppkey = "App-key";** 48 | ``` 49 | Note: The distributable comes with a demo username and password for the Service. 50 | 51 | ### 1.2 Test 52 | 53 | #### 1.2.1 Open the App 54 | 55 | * Open the App on your Device. You get a form to enter Credentials i.e. Name & Room Id. 56 | * You need to create a Room by clicking the "Create Room" button. 57 | * Once the Room ID is created, you can use it and share it with others to connect to the Virtual Room to carry out an RTC Session either as a Moderator or a Participant (Choose applicable Role in the Form). 58 | 59 | Note: Only one user with a Moderator Role is allowed to connect to a Virtual Room while trying with EnableX Hosted Service. Your Own Application Server can allow up to 5 Moderators. 60 | 61 | Note:- In the case of an emulator/simulator your local stream will not be created. It will be created only on a real device. 62 | 63 | ## 2. Set up Your Own Application Server 64 | 65 | You may need to set up your own Application Server after you try the Sample Application with EnableX hosted Server. We have different variants of the Application Server Sample Code. Pick the one in your preferred language and follow the instructions given in the respective README.md file. 66 | 67 | * NodeJS: [https://github.com/EnableX/Video-Conferencing-Open-Source-Web-Application-Sample.git] 68 | * PHP: [https://github.com/EnableX/Group-Video-Call-Conferencing-Sample-Application-in-PHP] 69 | 70 | Note the following: 71 | 72 | * You need to use App ID and App Key to run this Service. 73 | * Your React-native Client EndPoint needs to connect to this Service to create a Virtual Room and Create a Token to join the session. 74 | * Application Server is created using EnableX Server API while Rest API Service helps in provisioning, session access, and post-session reporting. 75 | 76 | To know more about Server API, go to: 77 | https://developer.enablex.io/docs/guides/video-guide/sample-codes/video-calling-app/#demo-application-server 78 | -------------------------------------------------------------------------------- /__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: import explicitly to use the types shipped with jest. 10 | import {it} from '@jest/globals'; 11 | 12 | // Note: test renderer must be required after react-native. 13 | import renderer from 'react-test-renderer'; 14 | 15 | it('renders correctly', () => { 16 | renderer.create(); 17 | }); 18 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "org.jetbrains.kotlin.android" 3 | apply plugin: "com.facebook.react" 4 | 5 | /** 6 | * This is the configuration block to customize your React Native Android app. 7 | * By default you don't need to apply any configuration, just uncomment the lines you need. 8 | */ 9 | react { 10 | /* Folders */ 11 | // The root of your project, i.e. where "package.json" lives. Default is '..' 12 | // root = file("../") 13 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 14 | // reactNativeDir = file("../node_modules/react-native") 15 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 16 | // codegenDir = file("../node_modules/@react-native/codegen") 17 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 18 | // cliFile = file("../node_modules/react-native/cli.js") 19 | 20 | /* Variants */ 21 | // The list of variants to that are debuggable. For those we're going to 22 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 23 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 24 | // debuggableVariants = ["liteDebug", "prodDebug"] 25 | 26 | /* Bundling */ 27 | // A list containing the node command and its flags. Default is just 'node'. 28 | // nodeExecutableAndArgs = ["node"] 29 | // 30 | // The command to run when bundling. By default is 'bundle' 31 | // bundleCommand = "ram-bundle" 32 | // 33 | // The path to the CLI configuration file. Default is empty. 34 | // bundleConfig = file(../rn-cli.config.js) 35 | // 36 | // The name of the generated asset file containing your JS bundle 37 | // bundleAssetName = "MyApplication.android.bundle" 38 | // 39 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 40 | // entryFile = file("../js/MyApplication.android.js") 41 | // 42 | // A list of extra flags to pass to the 'bundle' commands. 43 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 44 | // extraPackagerArgs = [] 45 | 46 | /* Hermes Commands */ 47 | // The hermes compiler command to run. By default it is 'hermesc' 48 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 49 | // 50 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 51 | // hermesFlags = ["-O", "-output-source-map"] 52 | } 53 | 54 | /** 55 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 56 | */ 57 | def enableProguardInReleaseBuilds = false 58 | 59 | /** 60 | * The preferred build flavor of JavaScriptCore (JSC) 61 | * 62 | * For example, to use the international variant, you can use: 63 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 64 | * 65 | * The international variant includes ICU i18n library and necessary data 66 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 67 | * give correct results when using with locales other than en-US. Note that 68 | * this variant is about 6MiB larger per architecture than default. 69 | */ 70 | def jscFlavor = 'org.webkit:android-jsc:+' 71 | 72 | android { 73 | ndkVersion rootProject.ext.ndkVersion 74 | buildToolsVersion rootProject.ext.buildToolsVersion 75 | compileSdk rootProject.ext.compileSdkVersion 76 | 77 | namespace "com.oneonevideocall" 78 | defaultConfig { 79 | applicationId "com.oneonevideocall" 80 | minSdkVersion rootProject.ext.minSdkVersion 81 | targetSdkVersion rootProject.ext.targetSdkVersion 82 | versionCode 1 83 | versionName "1.0" 84 | } 85 | signingConfigs { 86 | debug { 87 | storeFile file('debug.keystore') 88 | storePassword 'android' 89 | keyAlias 'androiddebugkey' 90 | keyPassword 'android' 91 | } 92 | } 93 | buildTypes { 94 | debug { 95 | signingConfig signingConfigs.debug 96 | } 97 | release { 98 | // Caution! In production, you need to generate your own keystore file. 99 | // see https://reactnative.dev/docs/signed-apk-android. 100 | signingConfig signingConfigs.debug 101 | minifyEnabled enableProguardInReleaseBuilds 102 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 103 | } 104 | } 105 | } 106 | 107 | dependencies { 108 | // The version of react-native is set by the React Native Gradle Plugin 109 | implementation("com.facebook.react:react-android") 110 | 111 | if (hermesEnabled.toBoolean()) { 112 | implementation("com.facebook.react:hermes-android") 113 | } else { 114 | implementation jscFlavor 115 | } 116 | } 117 | 118 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 119 | -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/debug.keystore -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 38 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/oneonevideocall/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.oneonevideocall 2 | 3 | import com.facebook.react.ReactActivity 4 | import com.facebook.react.ReactActivityDelegate 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate 7 | 8 | class MainActivity : ReactActivity() { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | override fun getMainComponentName(): String = "OneOneVideoCall" 15 | 16 | /** 17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] 18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] 19 | */ 20 | override fun createReactActivityDelegate(): ReactActivityDelegate = 21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) 22 | } 23 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/oneonevideocall/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.oneonevideocall 2 | 3 | import android.app.Application 4 | import com.facebook.react.PackageList 5 | import com.facebook.react.ReactApplication 6 | import com.facebook.react.ReactHost 7 | import com.facebook.react.ReactNativeHost 8 | import com.facebook.react.ReactPackage 9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost 11 | import com.facebook.react.defaults.DefaultReactNativeHost 12 | import com.facebook.soloader.SoLoader 13 | 14 | class MainApplication : Application(), ReactApplication { 15 | 16 | override val reactNativeHost: ReactNativeHost = 17 | object : DefaultReactNativeHost(this) { 18 | override fun getPackages(): List = 19 | PackageList(this).packages.apply { 20 | // Packages that cannot be autolinked yet can be added manually here, for example: 21 | // add(MyReactNativePackage()) 22 | } 23 | 24 | override fun getJSMainModuleName(): String = "index" 25 | 26 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 27 | 28 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 29 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 30 | } 31 | 32 | override val reactHost: ReactHost 33 | get() = getDefaultReactHost(applicationContext, reactNativeHost) 34 | 35 | override fun onCreate() { 36 | super.onCreate() 37 | SoLoader.init(this, false) 38 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 39 | // If you opted-in for the New Architecture, we load the native entry point for this app. 40 | load() 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | OneOneVideoCall 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 24 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "26.1.10909125" 8 | kotlinVersion = "1.9.22" 9 | } 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle") 16 | classpath("com.facebook.react:react-native-gradle-plugin") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") 18 | } 19 | } 20 | 21 | apply plugin: "com.facebook.react.rootproject" 22 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Use this property to specify which architecture you want to build. 28 | # You can also override it from the CLI using 29 | # ./gradlew -PreactNativeArchitectures=x86_64 30 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 31 | 32 | # Use this property to enable support to the new architecture. 33 | # This will allow you to use TurboModules and the Fabric render in 34 | # your application. You should enable this flag either if you want 35 | # to write custom TurboModules/Fabric components OR use libraries that 36 | # are providing them. 37 | newArchEnabled=false 38 | 39 | # Use this property to enable or disable the Hermes JS engine. 40 | # If set to false, you will be using JSC instead. 41 | hermesEnabled=true 42 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit 88 | 89 | # Use the maximum available, or set MAX_FD != -1 to use that value. 90 | MAX_FD=maximum 91 | 92 | warn () { 93 | echo "$*" 94 | } >&2 95 | 96 | die () { 97 | echo 98 | echo "$*" 99 | echo 100 | exit 1 101 | } >&2 102 | 103 | # OS specific support (must be 'true' or 'false'). 104 | cygwin=false 105 | msys=false 106 | darwin=false 107 | nonstop=false 108 | case "$( uname )" in #( 109 | CYGWIN* ) cygwin=true ;; #( 110 | Darwin* ) darwin=true ;; #( 111 | MSYS* | MINGW* ) msys=true ;; #( 112 | NONSTOP* ) nonstop=true ;; 113 | esac 114 | 115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 116 | 117 | 118 | # Determine the Java command to use to start the JVM. 119 | if [ -n "$JAVA_HOME" ] ; then 120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 121 | # IBM's JDK on AIX uses strange locations for the executables 122 | JAVACMD=$JAVA_HOME/jre/sh/java 123 | else 124 | JAVACMD=$JAVA_HOME/bin/java 125 | fi 126 | if [ ! -x "$JAVACMD" ] ; then 127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 128 | 129 | Please set the JAVA_HOME variable in your environment to match the 130 | location of your Java installation." 131 | fi 132 | else 133 | JAVACMD=java 134 | if ! command -v java >/dev/null 2>&1 135 | then 136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | fi 142 | 143 | # Increase the maximum file descriptors if we can. 144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 145 | case $MAX_FD in #( 146 | max*) 147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 148 | # shellcheck disable=SC2039,SC3045 149 | MAX_FD=$( ulimit -H -n ) || 150 | warn "Could not query maximum file descriptor limit" 151 | esac 152 | case $MAX_FD in #( 153 | '' | soft) :;; #( 154 | *) 155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 156 | # shellcheck disable=SC2039,SC3045 157 | ulimit -n "$MAX_FD" || 158 | warn "Could not set maximum file descriptor limit to $MAX_FD" 159 | esac 160 | fi 161 | 162 | # Collect all arguments for the java command, stacking in reverse order: 163 | # * args from the command line 164 | # * the main class name 165 | # * -classpath 166 | # * -D...appname settings 167 | # * --module-path (only if needed) 168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 169 | 170 | # For Cygwin or MSYS, switch paths to Windows format before running java 171 | if "$cygwin" || "$msys" ; then 172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 174 | 175 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 176 | 177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 178 | for arg do 179 | if 180 | case $arg in #( 181 | -*) false ;; # don't mess with options #( 182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 183 | [ -e "$t" ] ;; #( 184 | *) false ;; 185 | esac 186 | then 187 | arg=$( cygpath --path --ignore --mixed "$arg" ) 188 | fi 189 | # Roll the args list around exactly as many times as the number of 190 | # args, so each arg winds up back in the position where it started, but 191 | # possibly modified. 192 | # 193 | # NB: a `for` loop captures its iteration list before it begins, so 194 | # changing the positional parameters here affects neither the number of 195 | # iterations, nor the values presented in `arg`. 196 | shift # remove old arg 197 | set -- "$@" "$arg" # push replacement arg 198 | done 199 | fi 200 | 201 | 202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 204 | 205 | # Collect all arguments for the java command: 206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 207 | # and any embedded shellness will be escaped. 208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 209 | # treated as '${Hostname}' itself on the command line. 210 | 211 | set -- \ 212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 213 | -classpath "$CLASSPATH" \ 214 | org.gradle.wrapper.GradleWrapperMain \ 215 | "$@" 216 | 217 | # Stop when "xargs" is not available. 218 | if ! command -v xargs >/dev/null 2>&1 219 | then 220 | die "xargs is not available" 221 | fi 222 | 223 | # Use "xargs" to parse quoted args. 224 | # 225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 226 | # 227 | # In Bash we could simply go: 228 | # 229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 230 | # set -- "${ARGS[@]}" "$@" 231 | # 232 | # but POSIX shell has neither arrays nor command substitution, so instead we 233 | # post-process each arg (as a line of input to sed) to backslash-escape any 234 | # character that might be a shell metacharacter, then use eval to reverse 235 | # that process (while maintaining the separation between arguments), and wrap 236 | # the whole thing up as a single "set" statement. 237 | # 238 | # This will of course break if any of these variables contains a newline or 239 | # an unmatched quote. 240 | # 241 | 242 | eval "set -- $( 243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 244 | xargs -n1 | 245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 246 | tr '\n' ' ' 247 | )" '"$@"' 248 | 249 | exec "$JAVACMD" "$@" 250 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 1>&2 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 48 | echo. 1>&2 49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 50 | echo location of your Java installation. 1>&2 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 1>&2 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 62 | echo. 1>&2 63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 64 | echo location of your Java installation. 1>&2 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'OneOneVideoCall' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/@react-native/gradle-plugin') 5 | include(":EnxRtcAndroid") 6 | project(":EnxRtcAndroid").projectDir = file('../node_modules/enx-rtc-react-native/android/EnxRtcAndroid') 7 | include(":LibWebRtc") 8 | project(":LibWebRtc").projectDir = file('../node_modules/enx-rtc-react-native/android/LibWebRtc') 9 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OneOneVideoCall", 3 | "displayName": "OneOneVideoCall" 4 | } 5 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | // Add this line to your `index.js` 5 | import 'react-native-get-random-values' 6 | import {AppRegistry} from 'react-native'; 7 | import App from './App'; 8 | import {name as appName} from './app.json'; 9 | 10 | AppRegistry.registerComponent(appName, () => App); 11 | -------------------------------------------------------------------------------- /ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 00E356F31AD99517003FC87E /* OneOneVideoCallTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* OneOneVideoCallTests.m */; }; 11 | 0C80B921A6F3F58F76C31292 /* libPods-OneOneVideoCall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-OneOneVideoCall.a */; }; 12 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 14 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 15 | 7699B88040F8A987B510C191 /* libPods-OneOneVideoCall-OneOneVideoCallTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-OneOneVideoCall-OneOneVideoCallTests.a */; }; 16 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A; 25 | remoteInfo = OneOneVideoCall; 26 | }; 27 | /* End PBXContainerItemProxy section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 00E356EE1AD99517003FC87E /* OneOneVideoCallTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OneOneVideoCallTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 00E356F21AD99517003FC87E /* OneOneVideoCallTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneOneVideoCallTests.m; sourceTree = ""; }; 33 | 13B07F961A680F5B00A75B9A /* OneOneVideoCall.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OneOneVideoCall.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = OneOneVideoCall/AppDelegate.h; sourceTree = ""; }; 35 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = OneOneVideoCall/AppDelegate.mm; sourceTree = ""; }; 36 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = OneOneVideoCall/Images.xcassets; sourceTree = ""; }; 37 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = OneOneVideoCall/Info.plist; sourceTree = ""; }; 38 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = OneOneVideoCall/main.m; sourceTree = ""; }; 39 | 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = OneOneVideoCall/PrivacyInfo.xcprivacy; sourceTree = ""; }; 40 | 19F6CBCC0A4E27FBF8BF4A61 /* libPods-OneOneVideoCall-OneOneVideoCallTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OneOneVideoCall-OneOneVideoCallTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 3B4392A12AC88292D35C810B /* Pods-OneOneVideoCall.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneOneVideoCall.debug.xcconfig"; path = "Target Support Files/Pods-OneOneVideoCall/Pods-OneOneVideoCall.debug.xcconfig"; sourceTree = ""; }; 42 | 5709B34CF0A7D63546082F79 /* Pods-OneOneVideoCall.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneOneVideoCall.release.xcconfig"; path = "Target Support Files/Pods-OneOneVideoCall/Pods-OneOneVideoCall.release.xcconfig"; sourceTree = ""; }; 43 | 5B7EB9410499542E8C5724F5 /* Pods-OneOneVideoCall-OneOneVideoCallTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneOneVideoCall-OneOneVideoCallTests.debug.xcconfig"; path = "Target Support Files/Pods-OneOneVideoCall-OneOneVideoCallTests/Pods-OneOneVideoCall-OneOneVideoCallTests.debug.xcconfig"; sourceTree = ""; }; 44 | 5DCACB8F33CDC322A6C60F78 /* libPods-OneOneVideoCall.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OneOneVideoCall.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = OneOneVideoCall/LaunchScreen.storyboard; sourceTree = ""; }; 46 | 89C6BE57DB24E9ADA2F236DE /* Pods-OneOneVideoCall-OneOneVideoCallTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneOneVideoCall-OneOneVideoCallTests.release.xcconfig"; path = "Target Support Files/Pods-OneOneVideoCall-OneOneVideoCallTests/Pods-OneOneVideoCall-OneOneVideoCallTests.release.xcconfig"; sourceTree = ""; }; 47 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | 00E356EB1AD99517003FC87E /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | 7699B88040F8A987B510C191 /* libPods-OneOneVideoCall-OneOneVideoCallTests.a in Frameworks */, 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | 0C80B921A6F3F58F76C31292 /* libPods-OneOneVideoCall.a in Frameworks */, 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | /* End PBXFrameworksBuildPhase section */ 68 | 69 | /* Begin PBXGroup section */ 70 | 00E356EF1AD99517003FC87E /* OneOneVideoCallTests */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 00E356F21AD99517003FC87E /* OneOneVideoCallTests.m */, 74 | 00E356F01AD99517003FC87E /* Supporting Files */, 75 | ); 76 | path = OneOneVideoCallTests; 77 | sourceTree = ""; 78 | }; 79 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 00E356F11AD99517003FC87E /* Info.plist */, 83 | ); 84 | name = "Supporting Files"; 85 | sourceTree = ""; 86 | }; 87 | 13B07FAE1A68108700A75B9A /* OneOneVideoCall */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 91 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */, 92 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 93 | 13B07FB61A68108700A75B9A /* Info.plist */, 94 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 95 | 13B07FB71A68108700A75B9A /* main.m */, 96 | 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */, 97 | ); 98 | name = OneOneVideoCall; 99 | sourceTree = ""; 100 | }; 101 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 105 | 5DCACB8F33CDC322A6C60F78 /* libPods-OneOneVideoCall.a */, 106 | 19F6CBCC0A4E27FBF8BF4A61 /* libPods-OneOneVideoCall-OneOneVideoCallTests.a */, 107 | ); 108 | name = Frameworks; 109 | sourceTree = ""; 110 | }; 111 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | ); 115 | name = Libraries; 116 | sourceTree = ""; 117 | }; 118 | 83CBB9F61A601CBA00E9B192 = { 119 | isa = PBXGroup; 120 | children = ( 121 | 13B07FAE1A68108700A75B9A /* OneOneVideoCall */, 122 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 123 | 00E356EF1AD99517003FC87E /* OneOneVideoCallTests */, 124 | 83CBBA001A601CBA00E9B192 /* Products */, 125 | 2D16E6871FA4F8E400B85C8A /* Frameworks */, 126 | BBD78D7AC51CEA395F1C20DB /* Pods */, 127 | ); 128 | indentWidth = 2; 129 | sourceTree = ""; 130 | tabWidth = 2; 131 | usesTabs = 0; 132 | }; 133 | 83CBBA001A601CBA00E9B192 /* Products */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 13B07F961A680F5B00A75B9A /* OneOneVideoCall.app */, 137 | 00E356EE1AD99517003FC87E /* OneOneVideoCallTests.xctest */, 138 | ); 139 | name = Products; 140 | sourceTree = ""; 141 | }; 142 | BBD78D7AC51CEA395F1C20DB /* Pods */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 3B4392A12AC88292D35C810B /* Pods-OneOneVideoCall.debug.xcconfig */, 146 | 5709B34CF0A7D63546082F79 /* Pods-OneOneVideoCall.release.xcconfig */, 147 | 5B7EB9410499542E8C5724F5 /* Pods-OneOneVideoCall-OneOneVideoCallTests.debug.xcconfig */, 148 | 89C6BE57DB24E9ADA2F236DE /* Pods-OneOneVideoCall-OneOneVideoCallTests.release.xcconfig */, 149 | ); 150 | path = Pods; 151 | sourceTree = ""; 152 | }; 153 | /* End PBXGroup section */ 154 | 155 | /* Begin PBXNativeTarget section */ 156 | 00E356ED1AD99517003FC87E /* OneOneVideoCallTests */ = { 157 | isa = PBXNativeTarget; 158 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "OneOneVideoCallTests" */; 159 | buildPhases = ( 160 | A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */, 161 | 00E356EA1AD99517003FC87E /* Sources */, 162 | 00E356EB1AD99517003FC87E /* Frameworks */, 163 | 00E356EC1AD99517003FC87E /* Resources */, 164 | C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */, 165 | F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */, 166 | ); 167 | buildRules = ( 168 | ); 169 | dependencies = ( 170 | 00E356F51AD99517003FC87E /* PBXTargetDependency */, 171 | ); 172 | name = OneOneVideoCallTests; 173 | productName = OneOneVideoCallTests; 174 | productReference = 00E356EE1AD99517003FC87E /* OneOneVideoCallTests.xctest */; 175 | productType = "com.apple.product-type.bundle.unit-test"; 176 | }; 177 | 13B07F861A680F5B00A75B9A /* OneOneVideoCall */ = { 178 | isa = PBXNativeTarget; 179 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "OneOneVideoCall" */; 180 | buildPhases = ( 181 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, 182 | 13B07F871A680F5B00A75B9A /* Sources */, 183 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 184 | 13B07F8E1A680F5B00A75B9A /* Resources */, 185 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 186 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */, 187 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */, 188 | ); 189 | buildRules = ( 190 | ); 191 | dependencies = ( 192 | ); 193 | name = OneOneVideoCall; 194 | productName = OneOneVideoCall; 195 | productReference = 13B07F961A680F5B00A75B9A /* OneOneVideoCall.app */; 196 | productType = "com.apple.product-type.application"; 197 | }; 198 | /* End PBXNativeTarget section */ 199 | 200 | /* Begin PBXProject section */ 201 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 202 | isa = PBXProject; 203 | attributes = { 204 | LastUpgradeCheck = 1210; 205 | TargetAttributes = { 206 | 00E356ED1AD99517003FC87E = { 207 | CreatedOnToolsVersion = 6.2; 208 | TestTargetID = 13B07F861A680F5B00A75B9A; 209 | }; 210 | 13B07F861A680F5B00A75B9A = { 211 | LastSwiftMigration = 1120; 212 | }; 213 | }; 214 | }; 215 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "OneOneVideoCall" */; 216 | compatibilityVersion = "Xcode 12.0"; 217 | developmentRegion = en; 218 | hasScannedForEncodings = 0; 219 | knownRegions = ( 220 | en, 221 | Base, 222 | ); 223 | mainGroup = 83CBB9F61A601CBA00E9B192; 224 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 225 | projectDirPath = ""; 226 | projectRoot = ""; 227 | targets = ( 228 | 13B07F861A680F5B00A75B9A /* OneOneVideoCall */, 229 | 00E356ED1AD99517003FC87E /* OneOneVideoCallTests */, 230 | ); 231 | }; 232 | /* End PBXProject section */ 233 | 234 | /* Begin PBXResourcesBuildPhase section */ 235 | 00E356EC1AD99517003FC87E /* Resources */ = { 236 | isa = PBXResourcesBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 243 | isa = PBXResourcesBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 247 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | }; 251 | /* End PBXResourcesBuildPhase section */ 252 | 253 | /* Begin PBXShellScriptBuildPhase section */ 254 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 255 | isa = PBXShellScriptBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | inputPaths = ( 260 | "$(SRCROOT)/.xcode.env.local", 261 | "$(SRCROOT)/.xcode.env", 262 | ); 263 | name = "Bundle React Native code and images"; 264 | outputPaths = ( 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | shellPath = /bin/sh; 268 | shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; 269 | }; 270 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { 271 | isa = PBXShellScriptBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | ); 275 | inputFileListPaths = ( 276 | "${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall/Pods-OneOneVideoCall-frameworks-${CONFIGURATION}-input-files.xcfilelist", 277 | ); 278 | name = "[CP] Embed Pods Frameworks"; 279 | outputFileListPaths = ( 280 | "${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall/Pods-OneOneVideoCall-frameworks-${CONFIGURATION}-output-files.xcfilelist", 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | shellPath = /bin/sh; 284 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall/Pods-OneOneVideoCall-frameworks.sh\"\n"; 285 | showEnvVarsInLog = 0; 286 | }; 287 | A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = { 288 | isa = PBXShellScriptBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | ); 292 | inputFileListPaths = ( 293 | ); 294 | inputPaths = ( 295 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 296 | "${PODS_ROOT}/Manifest.lock", 297 | ); 298 | name = "[CP] Check Pods Manifest.lock"; 299 | outputFileListPaths = ( 300 | ); 301 | outputPaths = ( 302 | "$(DERIVED_FILE_DIR)/Pods-OneOneVideoCall-OneOneVideoCallTests-checkManifestLockResult.txt", 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | shellPath = /bin/sh; 306 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 307 | showEnvVarsInLog = 0; 308 | }; 309 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = { 310 | isa = PBXShellScriptBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | ); 314 | inputFileListPaths = ( 315 | ); 316 | inputPaths = ( 317 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 318 | "${PODS_ROOT}/Manifest.lock", 319 | ); 320 | name = "[CP] Check Pods Manifest.lock"; 321 | outputFileListPaths = ( 322 | ); 323 | outputPaths = ( 324 | "$(DERIVED_FILE_DIR)/Pods-OneOneVideoCall-checkManifestLockResult.txt", 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | shellPath = /bin/sh; 328 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 329 | showEnvVarsInLog = 0; 330 | }; 331 | C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = { 332 | isa = PBXShellScriptBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | ); 336 | inputFileListPaths = ( 337 | "${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall-OneOneVideoCallTests/Pods-OneOneVideoCall-OneOneVideoCallTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", 338 | ); 339 | name = "[CP] Embed Pods Frameworks"; 340 | outputFileListPaths = ( 341 | "${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall-OneOneVideoCallTests/Pods-OneOneVideoCall-OneOneVideoCallTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | shellPath = /bin/sh; 345 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall-OneOneVideoCallTests/Pods-OneOneVideoCall-OneOneVideoCallTests-frameworks.sh\"\n"; 346 | showEnvVarsInLog = 0; 347 | }; 348 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = { 349 | isa = PBXShellScriptBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | ); 353 | inputFileListPaths = ( 354 | "${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall/Pods-OneOneVideoCall-resources-${CONFIGURATION}-input-files.xcfilelist", 355 | ); 356 | name = "[CP] Copy Pods Resources"; 357 | outputFileListPaths = ( 358 | "${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall/Pods-OneOneVideoCall-resources-${CONFIGURATION}-output-files.xcfilelist", 359 | ); 360 | runOnlyForDeploymentPostprocessing = 0; 361 | shellPath = /bin/sh; 362 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall/Pods-OneOneVideoCall-resources.sh\"\n"; 363 | showEnvVarsInLog = 0; 364 | }; 365 | F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = { 366 | isa = PBXShellScriptBuildPhase; 367 | buildActionMask = 2147483647; 368 | files = ( 369 | ); 370 | inputFileListPaths = ( 371 | "${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall-OneOneVideoCallTests/Pods-OneOneVideoCall-OneOneVideoCallTests-resources-${CONFIGURATION}-input-files.xcfilelist", 372 | ); 373 | name = "[CP] Copy Pods Resources"; 374 | outputFileListPaths = ( 375 | "${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall-OneOneVideoCallTests/Pods-OneOneVideoCall-OneOneVideoCallTests-resources-${CONFIGURATION}-output-files.xcfilelist", 376 | ); 377 | runOnlyForDeploymentPostprocessing = 0; 378 | shellPath = /bin/sh; 379 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OneOneVideoCall-OneOneVideoCallTests/Pods-OneOneVideoCall-OneOneVideoCallTests-resources.sh\"\n"; 380 | showEnvVarsInLog = 0; 381 | }; 382 | /* End PBXShellScriptBuildPhase section */ 383 | 384 | /* Begin PBXSourcesBuildPhase section */ 385 | 00E356EA1AD99517003FC87E /* Sources */ = { 386 | isa = PBXSourcesBuildPhase; 387 | buildActionMask = 2147483647; 388 | files = ( 389 | 00E356F31AD99517003FC87E /* OneOneVideoCallTests.m in Sources */, 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | }; 393 | 13B07F871A680F5B00A75B9A /* Sources */ = { 394 | isa = PBXSourcesBuildPhase; 395 | buildActionMask = 2147483647; 396 | files = ( 397 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 398 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 399 | ); 400 | runOnlyForDeploymentPostprocessing = 0; 401 | }; 402 | /* End PBXSourcesBuildPhase section */ 403 | 404 | /* Begin PBXTargetDependency section */ 405 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 406 | isa = PBXTargetDependency; 407 | target = 13B07F861A680F5B00A75B9A /* OneOneVideoCall */; 408 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; 409 | }; 410 | /* End PBXTargetDependency section */ 411 | 412 | /* Begin XCBuildConfiguration section */ 413 | 00E356F61AD99517003FC87E /* Debug */ = { 414 | isa = XCBuildConfiguration; 415 | baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-OneOneVideoCall-OneOneVideoCallTests.debug.xcconfig */; 416 | buildSettings = { 417 | BUNDLE_LOADER = "$(TEST_HOST)"; 418 | GCC_PREPROCESSOR_DEFINITIONS = ( 419 | "DEBUG=1", 420 | "$(inherited)", 421 | ); 422 | INFOPLIST_FILE = OneOneVideoCallTests/Info.plist; 423 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 424 | LD_RUNPATH_SEARCH_PATHS = ( 425 | "$(inherited)", 426 | "@executable_path/Frameworks", 427 | "@loader_path/Frameworks", 428 | ); 429 | OTHER_LDFLAGS = ( 430 | "-ObjC", 431 | "-lc++", 432 | "$(inherited)", 433 | ); 434 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 435 | PRODUCT_NAME = "$(TARGET_NAME)"; 436 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OneOneVideoCall.app/OneOneVideoCall"; 437 | }; 438 | name = Debug; 439 | }; 440 | 00E356F71AD99517003FC87E /* Release */ = { 441 | isa = XCBuildConfiguration; 442 | baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-OneOneVideoCall-OneOneVideoCallTests.release.xcconfig */; 443 | buildSettings = { 444 | BUNDLE_LOADER = "$(TEST_HOST)"; 445 | COPY_PHASE_STRIP = NO; 446 | INFOPLIST_FILE = OneOneVideoCallTests/Info.plist; 447 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 448 | LD_RUNPATH_SEARCH_PATHS = ( 449 | "$(inherited)", 450 | "@executable_path/Frameworks", 451 | "@loader_path/Frameworks", 452 | ); 453 | OTHER_LDFLAGS = ( 454 | "-ObjC", 455 | "-lc++", 456 | "$(inherited)", 457 | ); 458 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 459 | PRODUCT_NAME = "$(TARGET_NAME)"; 460 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OneOneVideoCall.app/OneOneVideoCall"; 461 | }; 462 | name = Release; 463 | }; 464 | 13B07F941A680F5B00A75B9A /* Debug */ = { 465 | isa = XCBuildConfiguration; 466 | baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-OneOneVideoCall.debug.xcconfig */; 467 | buildSettings = { 468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 469 | CLANG_ENABLE_MODULES = YES; 470 | CURRENT_PROJECT_VERSION = 1; 471 | ENABLE_BITCODE = NO; 472 | INFOPLIST_FILE = OneOneVideoCall/Info.plist; 473 | LD_RUNPATH_SEARCH_PATHS = ( 474 | "$(inherited)", 475 | "@executable_path/Frameworks", 476 | ); 477 | MARKETING_VERSION = 1.0; 478 | OTHER_LDFLAGS = ( 479 | "$(inherited)", 480 | "-ObjC", 481 | "-lc++", 482 | ); 483 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 484 | PRODUCT_NAME = OneOneVideoCall; 485 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 486 | SWIFT_VERSION = 5.0; 487 | VERSIONING_SYSTEM = "apple-generic"; 488 | }; 489 | name = Debug; 490 | }; 491 | 13B07F951A680F5B00A75B9A /* Release */ = { 492 | isa = XCBuildConfiguration; 493 | baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-OneOneVideoCall.release.xcconfig */; 494 | buildSettings = { 495 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 496 | CLANG_ENABLE_MODULES = YES; 497 | CURRENT_PROJECT_VERSION = 1; 498 | INFOPLIST_FILE = OneOneVideoCall/Info.plist; 499 | LD_RUNPATH_SEARCH_PATHS = ( 500 | "$(inherited)", 501 | "@executable_path/Frameworks", 502 | ); 503 | MARKETING_VERSION = 1.0; 504 | OTHER_LDFLAGS = ( 505 | "$(inherited)", 506 | "-ObjC", 507 | "-lc++", 508 | ); 509 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 510 | PRODUCT_NAME = OneOneVideoCall; 511 | SWIFT_VERSION = 5.0; 512 | VERSIONING_SYSTEM = "apple-generic"; 513 | }; 514 | name = Release; 515 | }; 516 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 517 | isa = XCBuildConfiguration; 518 | buildSettings = { 519 | ALWAYS_SEARCH_USER_PATHS = NO; 520 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 521 | CLANG_CXX_LANGUAGE_STANDARD = "c++20"; 522 | CLANG_CXX_LIBRARY = "libc++"; 523 | CLANG_ENABLE_MODULES = YES; 524 | CLANG_ENABLE_OBJC_ARC = YES; 525 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 526 | CLANG_WARN_BOOL_CONVERSION = YES; 527 | CLANG_WARN_COMMA = YES; 528 | CLANG_WARN_CONSTANT_CONVERSION = YES; 529 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 530 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 531 | CLANG_WARN_EMPTY_BODY = YES; 532 | CLANG_WARN_ENUM_CONVERSION = YES; 533 | CLANG_WARN_INFINITE_RECURSION = YES; 534 | CLANG_WARN_INT_CONVERSION = YES; 535 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 536 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 537 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 538 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 539 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 540 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 541 | CLANG_WARN_STRICT_PROTOTYPES = YES; 542 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 543 | CLANG_WARN_UNREACHABLE_CODE = YES; 544 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 545 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 546 | COPY_PHASE_STRIP = NO; 547 | ENABLE_STRICT_OBJC_MSGSEND = YES; 548 | ENABLE_TESTABILITY = YES; 549 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; 550 | GCC_C_LANGUAGE_STANDARD = gnu99; 551 | GCC_DYNAMIC_NO_PIC = NO; 552 | GCC_NO_COMMON_BLOCKS = YES; 553 | GCC_OPTIMIZATION_LEVEL = 0; 554 | GCC_PREPROCESSOR_DEFINITIONS = ( 555 | "DEBUG=1", 556 | "$(inherited)", 557 | ); 558 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 559 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 560 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 561 | GCC_WARN_UNDECLARED_SELECTOR = YES; 562 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 563 | GCC_WARN_UNUSED_FUNCTION = YES; 564 | GCC_WARN_UNUSED_VARIABLE = YES; 565 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 566 | LD_RUNPATH_SEARCH_PATHS = ( 567 | /usr/lib/swift, 568 | "$(inherited)", 569 | ); 570 | LIBRARY_SEARCH_PATHS = ( 571 | "\"$(SDKROOT)/usr/lib/swift\"", 572 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 573 | "\"$(inherited)\"", 574 | ); 575 | MTL_ENABLE_DEBUG_INFO = YES; 576 | ONLY_ACTIVE_ARCH = YES; 577 | OTHER_CPLUSPLUSFLAGS = ( 578 | "$(OTHER_CFLAGS)", 579 | "-DFOLLY_NO_CONFIG", 580 | "-DFOLLY_MOBILE=1", 581 | "-DFOLLY_USE_LIBCPP=1", 582 | "-DFOLLY_CFG_NO_COROUTINES=1", 583 | "-DFOLLY_HAVE_CLOCK_GETTIME=1", 584 | ); 585 | SDKROOT = iphoneos; 586 | }; 587 | name = Debug; 588 | }; 589 | 83CBBA211A601CBA00E9B192 /* Release */ = { 590 | isa = XCBuildConfiguration; 591 | buildSettings = { 592 | ALWAYS_SEARCH_USER_PATHS = NO; 593 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 594 | CLANG_CXX_LANGUAGE_STANDARD = "c++20"; 595 | CLANG_CXX_LIBRARY = "libc++"; 596 | CLANG_ENABLE_MODULES = YES; 597 | CLANG_ENABLE_OBJC_ARC = YES; 598 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 599 | CLANG_WARN_BOOL_CONVERSION = YES; 600 | CLANG_WARN_COMMA = YES; 601 | CLANG_WARN_CONSTANT_CONVERSION = YES; 602 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 603 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 604 | CLANG_WARN_EMPTY_BODY = YES; 605 | CLANG_WARN_ENUM_CONVERSION = YES; 606 | CLANG_WARN_INFINITE_RECURSION = YES; 607 | CLANG_WARN_INT_CONVERSION = YES; 608 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 609 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 610 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 611 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 612 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 613 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 614 | CLANG_WARN_STRICT_PROTOTYPES = YES; 615 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 616 | CLANG_WARN_UNREACHABLE_CODE = YES; 617 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 618 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 619 | COPY_PHASE_STRIP = YES; 620 | ENABLE_NS_ASSERTIONS = NO; 621 | ENABLE_STRICT_OBJC_MSGSEND = YES; 622 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; 623 | GCC_C_LANGUAGE_STANDARD = gnu99; 624 | GCC_NO_COMMON_BLOCKS = YES; 625 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 626 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 627 | GCC_WARN_UNDECLARED_SELECTOR = YES; 628 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 629 | GCC_WARN_UNUSED_FUNCTION = YES; 630 | GCC_WARN_UNUSED_VARIABLE = YES; 631 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 632 | LD_RUNPATH_SEARCH_PATHS = ( 633 | /usr/lib/swift, 634 | "$(inherited)", 635 | ); 636 | LIBRARY_SEARCH_PATHS = ( 637 | "\"$(SDKROOT)/usr/lib/swift\"", 638 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 639 | "\"$(inherited)\"", 640 | ); 641 | MTL_ENABLE_DEBUG_INFO = NO; 642 | OTHER_CPLUSPLUSFLAGS = ( 643 | "$(OTHER_CFLAGS)", 644 | "-DFOLLY_NO_CONFIG", 645 | "-DFOLLY_MOBILE=1", 646 | "-DFOLLY_USE_LIBCPP=1", 647 | "-DFOLLY_CFG_NO_COROUTINES=1", 648 | "-DFOLLY_HAVE_CLOCK_GETTIME=1", 649 | ); 650 | SDKROOT = iphoneos; 651 | VALIDATE_PRODUCT = YES; 652 | }; 653 | name = Release; 654 | }; 655 | /* End XCBuildConfiguration section */ 656 | 657 | /* Begin XCConfigurationList section */ 658 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "OneOneVideoCallTests" */ = { 659 | isa = XCConfigurationList; 660 | buildConfigurations = ( 661 | 00E356F61AD99517003FC87E /* Debug */, 662 | 00E356F71AD99517003FC87E /* Release */, 663 | ); 664 | defaultConfigurationIsVisible = 0; 665 | defaultConfigurationName = Release; 666 | }; 667 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "OneOneVideoCall" */ = { 668 | isa = XCConfigurationList; 669 | buildConfigurations = ( 670 | 13B07F941A680F5B00A75B9A /* Debug */, 671 | 13B07F951A680F5B00A75B9A /* Release */, 672 | ); 673 | defaultConfigurationIsVisible = 0; 674 | defaultConfigurationName = Release; 675 | }; 676 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "OneOneVideoCall" */ = { 677 | isa = XCConfigurationList; 678 | buildConfigurations = ( 679 | 83CBBA201A601CBA00E9B192 /* Debug */, 680 | 83CBBA211A601CBA00E9B192 /* Release */, 681 | ); 682 | defaultConfigurationIsVisible = 0; 683 | defaultConfigurationName = Release; 684 | }; 685 | /* End XCConfigurationList section */ 686 | }; 687 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 688 | } 689 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall.xcodeproj/xcshareddata/xcschemes/OneOneVideoCall.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"OneOneVideoCall"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | [self getPrivacyAccess]; 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | -(void)getPrivacyAccess{ 17 | AVAuthorizationStatus vStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; 18 | if(vStatus == AVAuthorizationStatusNotDetermined){ 19 | [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { 20 | }]; 21 | } 22 | AVAuthorizationStatus aStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]; 23 | if(aStatus == AVAuthorizationStatusNotDetermined){ 24 | [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) { 25 | }]; 26 | } 27 | } 28 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 29 | { 30 | return [self bundleURL]; 31 | } 32 | 33 | - (NSURL *)bundleURL 34 | { 35 | #if DEBUG 36 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 37 | #else 38 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 39 | #endif 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | OneOneVideoCall 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | 30 | NSAllowsArbitraryLoads 31 | 32 | NSAllowsLocalNetworking 33 | 34 | 35 | NSLocationWhenInUseUsageDescription 36 | 37 | UILaunchStoryboardName 38 | LaunchScreen 39 | UIRequiredDeviceCapabilities 40 | 41 | arm64 42 | 43 | UISupportedInterfaceOrientations 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | UIViewControllerBasedStatusBarAppearance 50 | 51 | NSCameraUsageDescription 52 | App User your camera to captcha Video 53 | NSMicrophoneUsageDescription 54 | App User your Micro phone to captcha audio 55 | 56 | 57 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyCollectedDataTypes 6 | 7 | 8 | NSPrivacyAccessedAPITypes 9 | 10 | 11 | NSPrivacyAccessedAPIType 12 | NSPrivacyAccessedAPICategoryFileTimestamp 13 | NSPrivacyAccessedAPITypeReasons 14 | 15 | C617.1 16 | 17 | 18 | 19 | NSPrivacyAccessedAPIType 20 | NSPrivacyAccessedAPICategoryUserDefaults 21 | NSPrivacyAccessedAPITypeReasons 22 | 23 | CA92.1 24 | 25 | 26 | 27 | NSPrivacyAccessedAPIType 28 | NSPrivacyAccessedAPICategorySystemBootTime 29 | NSPrivacyAccessedAPITypeReasons 30 | 31 | 35F9.1 32 | 33 | 34 | 35 | NSPrivacyTracking 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ios/OneOneVideoCall/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ios/OneOneVideoCallTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/OneOneVideoCallTests/OneOneVideoCallTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface OneOneVideoCallTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation OneOneVideoCallTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | 11 | linkage = ENV['USE_FRAMEWORKS'] 12 | if linkage != nil 13 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 14 | use_frameworks! :linkage => linkage.to_sym 15 | end 16 | 17 | target 'OneOneVideoCall' do 18 | #use_expo_modules! 19 | config = use_native_modules! 20 | use_frameworks! :linkage => :dynamic 21 | 22 | use_react_native!( 23 | :path => config[:reactNativePath], 24 | # An absolute path to your application root. 25 | :app_path => "#{Pod::Config.instance.installation_root}/.." 26 | ) 27 | 28 | target 'OneOneVideoCallTests' do 29 | inherit! :complete 30 | # Pods for testing 31 | end 32 | 33 | post_install do |installer| 34 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 35 | 36 | react_native_post_install( 37 | installer, 38 | config[:reactNativePath], 39 | :mac_catalyst_enabled => false, 40 | # :ccache_enabled => true 41 | ) 42 | end 43 | end 44 | pre_install do |installer| 45 | installer.pod_targets.each do |pod| 46 | if pod.name.eql?('RNScreens') || pod.name.eql?('RNCMaskedView') || pod.name.eql?('RNReanimated') 47 | def pod.build_type 48 | Pod::BuildType.static_library 49 | end 50 | end 51 | end 52 | end -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); 2 | 3 | /** 4 | * Metro configuration 5 | * https://reactnative.dev/docs/metro 6 | * 7 | * @type {import('metro-config').MetroConfig} 8 | */ 9 | const config = {}; 10 | 11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OneOneVideoCall", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "lint": "eslint .", 9 | "start": "react-native start", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "@react-navigation/native": "^7.0.18", 14 | "@react-navigation/native-stack": "^7.3.2", 15 | "@react-navigation/stack": "^7.2.2", 16 | "axios": "^1.8.4", 17 | "enx-rtc-react-native": "^2.3.48", 18 | "react": "19.0.0", 19 | "react-native": "0.78.1", 20 | "react-native-gesture-handler": "^2.24.0", 21 | "react-native-get-random-values": "^1.11.0", 22 | "react-native-reanimated": "^3.17.1", 23 | "react-native-safe-area-context": "^5.3.0", 24 | "react-native-screens": "^4.9.2", 25 | "react-native-permissions": "^4.1.5" 26 | }, 27 | "devDependencies": { 28 | "@babel/core": "^7.25.2", 29 | "@babel/preset-env": "^7.25.3", 30 | "@babel/runtime": "^7.25.0", 31 | "@react-native-community/cli": "15.0.1", 32 | "@react-native-community/cli-platform-android": "15.0.1", 33 | "@react-native-community/cli-platform-ios": "15.0.1", 34 | "@react-native/babel-preset": "0.78.1", 35 | "@react-native/eslint-config": "0.78.1", 36 | "@react-native/metro-config": "0.78.1", 37 | "@react-native/typescript-config": "0.78.1", 38 | "@types/jest": "^29.5.13", 39 | "@types/react": "^19.0.0", 40 | "@types/react-test-renderer": "^19.0.0", 41 | "eslint": "^8.19.0", 42 | "jest": "^29.6.3", 43 | "prettier": "2.8.8", 44 | "react-test-renderer": "19.0.0", 45 | "typescript": "5.0.4" 46 | }, 47 | "engines": { 48 | "node": ">=18" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/EnxConferenceScreen.tsx: -------------------------------------------------------------------------------- 1 | import React, {PureComponent} from 'react'; 2 | import { 3 | Platform, 4 | StyleSheet, 5 | Text, 6 | Alert, 7 | TouchableHighlight, 8 | TextInput, 9 | Button, 10 | View, 11 | Dimensions, 12 | Image, 13 | PermissionsAndroid, 14 | FlatList, 15 | } from 'react-native'; 16 | import PropTypes from 'prop-types'; 17 | import { 18 | EnxRoom, 19 | Enx, 20 | EnxStream, 21 | EnxPlayerView, 22 | EnxToolBarView, 23 | } from 'enx-rtc-react-native'; 24 | import axios from 'axios'; 25 | import {BackHandler} from 'react-native'; 26 | 27 | type Props = { 28 | route: any; 29 | navigation:any; 30 | }; 31 | type State = { 32 | screenHeight: number; 33 | screenWidth: number; 34 | isHorizontal: boolean; 35 | noOfColumn: number; 36 | selectedDevice: string; 37 | deviceList: any[]; 38 | base64Icon: string; 39 | activeTalkerStreams: any[]; 40 | isUpdated: boolean; 41 | recordingCheck: boolean; 42 | screenShareCheck: boolean; 43 | toolBarCheck: boolean; 44 | audioMuteUnmuteCheck: boolean; 45 | audioMuteUnmuteImage: any; 46 | videoMuteUnmuteCheck: boolean; 47 | videoMuteUnmuteImage: any; 48 | rotateCamera: boolean; 49 | rotateCameraImage: any; 50 | canvasCheck: boolean; 51 | annotationCheck: boolean; 52 | localStreamId: string; 53 | screenShareId: string | null; 54 | canvasStreamId: string | null; 55 | activeStreamId: string | null; 56 | isConnected: boolean; 57 | annotationStreamId: string | null; 58 | permissionError: boolean; 59 | localStreamInfo: { 60 | audio: boolean; 61 | video: boolean; 62 | data: boolean; 63 | maxVideoBW: string; 64 | minVideoBW: string; 65 | audioMuted: boolean; 66 | videoMuted: boolean; 67 | name: string; 68 | minWidth: string; 69 | minHeight: string; 70 | maxWidth: string; 71 | maxHeight: string; 72 | audio_only: boolean; 73 | }; 74 | videoQual: { 75 | streamType: string; 76 | videoQuality: string; 77 | }; 78 | enxRoomInfo: { 79 | allow_reconnect: boolean; 80 | number_of_attempts: number; 81 | timeout_interval: number; 82 | playerConfiguration: { 83 | audiomute: boolean; 84 | videomute: boolean; 85 | bandwidth: boolean; 86 | screenshot: boolean; 87 | avatar: boolean; 88 | iconHeight: number; 89 | iconWidth: number; 90 | avatarHeight: number; 91 | avatarWidth: number; 92 | iconColor : string; 93 | }; 94 | }; 95 | advanceOptions: { 96 | battery_updates: boolean; 97 | notify_video_resolution_change: boolean; 98 | }; 99 | chat: { 100 | message: string; 101 | from: string; 102 | timestamp: number; 103 | }; 104 | }; 105 | interface RoomEventHandlers { 106 | roomConnected: (event: any) => void; 107 | roomError: (event: any) => void; 108 | availableFiles: (event: any) => void; 109 | streamPublished: (event: any) => void; 110 | eventError: (event: any) => void; 111 | streamAdded: (event: any) => void; 112 | notifyDeviceUpdate: (event: any) => void; 113 | activeTalkerList: (event: any) => void; 114 | streamSubscribed: (event: any) => void; 115 | roomDisconnected: (event: any) => void; 116 | recordStarted: (event: any) => void; 117 | recordStopped: (event: any) => void; 118 | startRecordingEvent: (event: any) => void; 119 | stopRecordingEvent: (event: any) => void; 120 | receivedStats: (event: any) => void; 121 | acknowledgeStats: (event: any) => void; 122 | bandWidthUpdated: (event: any) => void; 123 | shareStateEvent: (event: any) => void; 124 | startScreenShareACK: (event: any) => void; 125 | canvasStateEvent: (event: any) => void; 126 | stoppedScreenShareACK: (event: any) => void; 127 | screenShareStarted: (event: any) => void; 128 | sceenShareStopped: (event: any) => void; 129 | canvasStarted: (event: any) => void; 130 | canvasStopped: (event: any) => void; 131 | mutedAllUser: (event: any) => void; 132 | unmutedAllUser: (event: any) => void; 133 | hardMutedAll: (event: any) => void; 134 | hardUnmuteAllUser: (event: any) => void; 135 | userConnected: (event: any) => void; 136 | userDisconnected: (event: any) => void; 137 | reconnect: (event: any) => void; 138 | userReconnect: (event: any) => void; 139 | connectionInterrupted: (event: any) => void; 140 | connectionLost: (event: any) => void; 141 | capturedView: (event: any) => void; 142 | 143 | // Define other event handlers... 144 | } 145 | 146 | interface StreamEventHandlers { 147 | audioEvent: (event: any) => void; 148 | playerStats: (event: any) => void; 149 | videoEvent: (event: any) => void; 150 | hardMuteAudio: (event: any) => void; 151 | hardUnmuteAudio: (event: any) => void; 152 | recievedHardMutedAudio: (event: any) => void; 153 | recievedHardUnmutedAudio: (event: any) => void; 154 | hardVideoMute: (event: any) => void; 155 | hardVideoUnmute: (event: any) => void; 156 | receivehardMuteVideo: (event: any) => void; 157 | recivehardUnmuteVideo: (event: any) => void; 158 | receiveData: (event: any) => void; 159 | remoteStreamAudioMute: (event: any) => void; 160 | remoteStreamAudioUnMute: (event: any) => void; 161 | remoteStreamVideoMute: (event: any) => void; 162 | remoteStreamVideoUnMute: (event: any) => void; 163 | // Define other event handlers... 164 | } 165 | const calculateColoum = (data: any[]) => { 166 | if (data.length == 1 || data.length == 2) return 1; 167 | else return 2; 168 | }; 169 | 170 | const calculateRow = (data: any[]) => { 171 | if (data.length == 1) return 1; 172 | else if (data.length == 2 || data.length == 3 || data.length == 4) return 2; 173 | else if (data.length == 5 || data.length == 6) return 3; 174 | else if (data.length == 7 || data.length == 8) return 4; 175 | else if (data.length == 9 || data.length == 10 || data.length > 10) return 5; 176 | }; 177 | 178 | export default class EnxVideoView extends PureComponent { 179 | roomEventHandlers: RoomEventHandlers; 180 | streamEventHandlers: StreamEventHandlers; 181 | renderItem = ({item, index}: {item: any; index: number}) => { 182 | return ( 183 | 198 | ); 199 | }; 200 | 201 | async UNSAFE_componentWillMount() { 202 | Enx.initRoom(); 203 | } 204 | 205 | constructor(props: Props) { 206 | super(props); 207 | this.state = { 208 | screenHeight: Dimensions.get('window').height, 209 | screenWidth: Dimensions.get('window').width, 210 | isHorizontal: false, 211 | noOfColumn: 0, 212 | selectedDevice: '', 213 | deviceList: [], 214 | base64Icon: '', 215 | activeTalkerStreams: [], 216 | isUpdated: false, 217 | recordingCheck: false, 218 | screenShareCheck: false, 219 | toolBarCheck: false, 220 | audioMuteUnmuteCheck: true, 221 | audioMuteUnmuteImage: require('./image_asset/unmute.png'), 222 | videoMuteUnmuteCheck: true, 223 | videoMuteUnmuteImage: require('./image_asset/startvideo.png'), 224 | rotateCamera: false, 225 | rotateCameraImage: require('./image_asset/switchcamera.png'), 226 | canvasCheck: false, 227 | annotationCheck: false, 228 | localStreamId: '0', 229 | screenShareId: null, 230 | canvasStreamId: null, 231 | activeStreamId: null, 232 | isConnected: false, 233 | permissionError: false, 234 | annotationStreamId: null, 235 | localStreamInfo: { 236 | audio: true, 237 | video: true, 238 | data: false, 239 | maxVideoBW: '400', 240 | minVideoBW: '300', 241 | audioMuted: false, 242 | videoMuted: false, 243 | name: 'React Native', 244 | minWidth: '720', 245 | minHeight: '480', 246 | maxWidth: '1280', 247 | maxHeight: '720', 248 | audio_only: false, 249 | }, 250 | videoQual: { 251 | streamType: 'talker', 252 | videoQuality: 'SD', 253 | }, 254 | enxRoomInfo: { 255 | allow_reconnect: true, 256 | number_of_attempts: 3, 257 | timeout_interval: 15, 258 | playerConfiguration: { 259 | audiomute: true, 260 | videomute: true, 261 | bandwidth: true, 262 | screenshot: true, 263 | avatar: true, 264 | iconHeight: 30, 265 | iconWidth: 30, 266 | avatarHeight: 50, 267 | avatarWidth: 50, 268 | iconColor : '#dfc0ef' 269 | }, 270 | }, 271 | advanceOptions: { 272 | battery_updates: true, 273 | notify_video_resolution_change: true, 274 | }, 275 | chat: { 276 | message: 'Test chat', 277 | from: 'React-Native', 278 | timestamp: Date.now(), 279 | }, 280 | }; 281 | const { navigation } = this.props; 282 | this.requestPermission = this.requestPermission.bind(this); 283 | 284 | this.roomEventHandlers = { 285 | roomConnected: event => { 286 | console.log('roomConnected', event); 287 | this.setState({ 288 | isConnected: true, 289 | }); 290 | Enx.getLocalStreamId(status => { 291 | this.setState({ 292 | localStreamId: status, 293 | }); 294 | }); 295 | Enx.publish(); 296 | }, 297 | roomError: event => { 298 | console.log('roomError', event); 299 | if (event.msg == 'Network disconnected') { 300 | navigation.goBack(); 301 | } 302 | // Navigation.pop(this.props.componentId); 303 | }, 304 | availableFiles: event => { 305 | console.log('availableFiles', event); 306 | }, 307 | streamPublished: event => { 308 | console.log('streamPublished', event); 309 | }, 310 | eventError: event => { 311 | console.log('eventErrorrr', event); 312 | if (this.state.permissionError) { 313 | alert('Kindly grant camera and microphone permission to continue.'); 314 | } 315 | }, 316 | streamAdded: event => { 317 | console.log('streamAdded', event); 318 | Enx.subscribe(event.streamId, error => { 319 | console.log('streamAdded', error); 320 | }); 321 | }, 322 | notifyDeviceUpdate: event => { 323 | console.log('NotifyDeviceUpdate', event); 324 | }, 325 | activeTalkerList: event => { 326 | var tempArray = []; 327 | if (event.length == 0) { 328 | this.setState({ 329 | activeTalkerStreams: [], 330 | }); 331 | 332 | this.forceUpdate(); 333 | return; 334 | } 335 | if (event.lenght == this.state.activeTalkerStreams.length) return; 336 | if (this.state.activeTalkerStreams.length > 0) { 337 | this.setState({ 338 | activeTalkerStreams: [], 339 | }); 340 | } 341 | for (var i = 0; i < event.length; i++) { 342 | this.setState({ 343 | activeStreamId: event[0].streamId, 344 | }); 345 | 346 | tempArray.push(event[i]); 347 | } 348 | if (tempArray.length > 0) { 349 | this.setState({ 350 | activeTalkerStreams: tempArray, 351 | }); 352 | } 353 | }, 354 | streamSubscribed: event => { 355 | console.log('streamSubscribed', event); 356 | }, 357 | 358 | roomDisconnected: event => { 359 | console.log('disconnecteddddd', event); 360 | navigation.goBack(); 361 | }, 362 | recordStarted: event => { 363 | console.log('recordStartedddddd', event.msg); 364 | this.setState({recordingCheck: true}); 365 | }, 366 | recordStopped: event => { 367 | console.log('recordStopped', event.msg); 368 | this.setState({recordingCheck: false}); 369 | }, 370 | startRecordingEvent: event => { 371 | console.log('startRecordingEvent', event); 372 | if (event.result == '0') { 373 | this.setState({recordingCheck: true}); 374 | } 375 | }, 376 | stopRecordingEvent: event => { 377 | console.log('stopRecordingEvent', event); 378 | if (event.result == '0') { 379 | this.setState({recordingCheck: false}); 380 | } 381 | }, 382 | receivedStats: event => { 383 | console.log('receivedStats', event); 384 | }, 385 | acknowledgeStats: event => { 386 | console.log('acknowledgeStats', event); 387 | }, 388 | bandWidthUpdated: event => { 389 | console.log('bandWidthUpdated', event); 390 | }, 391 | shareStateEvent: event => { 392 | console.log('shareStateEvent', event); 393 | }, 394 | canvasStateEvent: event => { 395 | console.log('canvasStateEvent', event); 396 | }, 397 | 398 | startScreenShareACK: event => { 399 | console.log('startScreenShareACK', event); 400 | }, 401 | stoppedScreenShareACK: event => { 402 | console.log('stoppedScreenShareACK', event); 403 | }, 404 | 405 | screenShareStarted: event => { 406 | console.log('screenShareStarted', event); 407 | this.setState({ 408 | screenShareId: String(event.streamId), 409 | screenShareCheck: true, 410 | }); 411 | }, 412 | sceenShareStopped: event => { 413 | console.log('sceenShareStoppedddd', event); 414 | this.setState({screenShareCheck: false}); 415 | }, 416 | canvasStarted: event => { 417 | this.setState({ 418 | canvasStreamId: String(event.streamId), 419 | canvasCheck: true, 420 | }); 421 | }, 422 | canvasStopped: event => { 423 | console.log('canvasStoppedddd', event); 424 | this.setState({canvasCheck: false}); 425 | }, 426 | 427 | mutedAllUser: event => { 428 | console.log('mutedAllUser', event); 429 | }, 430 | unmutedAllUser: event => { 431 | console.log('unmutedAllUser', event); 432 | }, 433 | hardMutedAll: event => { 434 | console.log('hardMutedAll', event); 435 | }, 436 | hardUnmuteAllUser: event => { 437 | console.log('hardUnmuteAllUser', event); 438 | }, 439 | userConnected: event => { 440 | console.log('userConnected', event); 441 | }, 442 | userDisconnected: event => { 443 | console.log('userDisconnected', event); 444 | }, 445 | 446 | reconnect: event => { 447 | console.log('reconnect', event); 448 | }, 449 | userReconnect: event => { 450 | console.log('userReconnect', event); 451 | this.setState({ 452 | activeTalkerStreams: [], 453 | }); 454 | 455 | this.forceUpdate(); 456 | }, 457 | connectionInterrupted: event => { 458 | console.log('connectionInterrupted', event); 459 | }, 460 | connectionLost: event => { 461 | console.log('connectionLost', event); 462 | }, 463 | capturedView: event => { 464 | console.log('capturedView', event); 465 | this.setState({ 466 | base64Icon: event, 467 | }); 468 | }, 469 | // Bandwidth 470 | }; 471 | 472 | this.streamEventHandlers = { 473 | audioEvent: event => { 474 | console.log('audioEvent', event); 475 | if (event.result == '0') { 476 | if (event.msg == 'Audio Off') { 477 | this.setState({audioMuteUnmuteCheck: false}); 478 | this.setState({ 479 | audioMuteUnmuteImage: require('./image_asset/mute.png'), 480 | }); 481 | } else { 482 | this.setState({audioMuteUnmuteCheck: true}); 483 | this.setState({ 484 | audioMuteUnmuteImage: require('./image_asset/unmute.png'), 485 | }); 486 | } 487 | } 488 | }, 489 | playerStats: event => { 490 | console.log('playerStats', event); 491 | }, 492 | videoEvent: event => { 493 | if (event.result == '0') { 494 | if (event.msg == 'Video Off') { 495 | this.setState({ 496 | videoMuteUnmuteCheck: false, 497 | }); 498 | this.setState({ 499 | videoMuteUnmuteImage: require('./image_asset/stopvideo.png'), 500 | }); 501 | } else { 502 | this.setState({ 503 | videoMuteUnmuteCheck: true, 504 | }); 505 | this.setState({ 506 | videoMuteUnmuteImage: require('./image_asset/startvideo.png'), 507 | }); 508 | } 509 | } 510 | }, 511 | hardMuteAudio: event => { 512 | console.log('hardMuteAudio', event); 513 | }, 514 | hardUnmuteAudio: event => { 515 | console.log('hardUnmuteAudio', event); 516 | }, 517 | recievedHardMutedAudio: event => { 518 | console.log('recievedHardMutedAudio', event); 519 | }, 520 | recievedHardUnmutedAudio: event => { 521 | console.log('recievedHardUnmutedAudio', event); 522 | }, 523 | hardVideoMute: event => { 524 | console.log('hardVideoMute', event); 525 | }, 526 | hardVideoUnmute: event => { 527 | console.log('hardVideoUnmute', event); 528 | }, 529 | receivehardMuteVideo: event => { 530 | console.log('receivehardMuteVideo', event); 531 | }, 532 | recivehardUnmuteVideo: event => { 533 | console.log('recivehardUnmuteVideo', event); 534 | }, 535 | receiveData: event => { 536 | console.log('receiveData', event); 537 | }, 538 | remoteStreamAudioMute: event => { 539 | console.log('remoteStreamAudioMute', event); 540 | }, 541 | remoteStreamAudioUnMute: event => { 542 | console.log('remoteStreamAudioUnMute', event); 543 | }, 544 | remoteStreamVideoMute: event => { 545 | console.log('remoteStreamVideoMute', event); 546 | }, 547 | remoteStreamVideoUnMute: event => { 548 | console.log('remoteStreamVideoUnMute', event); 549 | }, 550 | }; 551 | 552 | this._onPressMute = this._onPressMute.bind(this); 553 | this._onPressSwitchCamera = this._onPressSwitchCamera.bind(this); 554 | this._onPressVideoMute = this._onPressVideoMute.bind(this); 555 | this._onPressSpeaker = this._onPressSpeaker.bind(this); 556 | this._onPressDisconnect = this._onPressDisconnect.bind(this); 557 | } 558 | 559 | async requestPermission() { 560 | try { 561 | const granted = await PermissionsAndroid.request( 562 | PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, 563 | { 564 | title: 'Enablex Storage Permission', 565 | message: 'Enablex needs access to your storage ' + 'to write logs.', 566 | buttonNeutral: 'Ask Me Later', 567 | buttonNegative: 'Cancel', 568 | buttonPositive: 'OK', 569 | }, 570 | ); 571 | if (granted === PermissionsAndroid.RESULTS.GRANTED) { 572 | this.setState({permissionError: true}); 573 | Enx.postClientLogs(); 574 | } else { 575 | alert('Kindly grant storage permission to send logs.'); 576 | } 577 | } catch (err) { 578 | console.warn(err); 579 | } 580 | } 581 | 582 | render() { 583 | const {route} = this.props; 584 | 585 | const token = route.params ? route.params.token : ''; 586 | const username = route.params ? route.params.username : null; 587 | 588 | return ( 589 | 590 | 591 | {this.state.activeTalkerStreams.length > 0 ? ( 592 | this.state.activeTalkerStreams.length < 3 ? ( 593 | index.toString()} 599 | numColumns={calculateColoum(this.state.activeTalkerStreams)} 600 | /> 601 | ) : ( 602 | index.toString()} 608 | numColumns={calculateColoum(this.state.activeTalkerStreams)} 609 | /> 610 | ) 611 | ) : null} 612 | 613 | 618 | {this.state.isConnected ? ( 619 | 627 | ) : ( 628 | 629 | )} 630 | 631 | 632 | 633 | 634 | 635 | 638 | 642 | 643 | 646 | 650 | 651 | 654 | 658 | 659 | 662 | 666 | 667 | 668 | {/* Other TouchableHighlight components */} 669 | 670 | 671 | 672 | 673 | ); 674 | } 675 | 676 | componentDidMount() { 677 | BackHandler.addEventListener('hardwareBackPress', this.handleBackButton); 678 | } 679 | 680 | componentWillUnmount() { 681 | BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton); 682 | } 683 | 684 | handleBackButton() { 685 | Alert.alert( 686 | 'Exit App', 687 | 'Exiting the application?', 688 | [ 689 | { 690 | text: 'Cancel', 691 | onPress: () => console.log('Cancel Pressed'), 692 | style: 'cancel', 693 | }, 694 | { 695 | text: 'OK', 696 | onPress: () => BackHandler.exitApp(), 697 | }, 698 | ], 699 | { 700 | cancelable: false, 701 | }, 702 | ); 703 | return true; 704 | } 705 | 706 | async _onLayout(event: any) { 707 | var {x, y, width, height} = event.nativeEvent.layout; 708 | await this.setState({screenHeight: height, screenWidth: width}); 709 | } 710 | _onPressMute = () => { 711 | Enx.muteSelfAudio( 712 | this.state.localStreamId, 713 | this.state.audioMuteUnmuteCheck, 714 | ); 715 | }; 716 | 717 | _onPressVideoMute = () => { 718 | Enx.muteSelfVideo( 719 | this.state.localStreamId, 720 | this.state.videoMuteUnmuteCheck, 721 | ); 722 | }; 723 | 724 | _onPressSpeaker = () => { 725 | console.log('_onPressSpeaker', 'clicked'); 726 | }; 727 | 728 | _onPressSwitchCamera = () => { 729 | Enx.switchCamera(this.state.localStreamId); 730 | if (!this.state.rotateCamera) { 731 | this.setState({ 732 | rotateCamera: true, 733 | }); 734 | this.setState({ 735 | rotateCameraImage: require('./image_asset/switchcamera.png'), 736 | }); 737 | } else { 738 | this.setState({ 739 | rotateCamera: false, 740 | }); 741 | this.setState({ 742 | rotateCameraImage: require('./image_asset/switchcamera.png'), 743 | }); 744 | } 745 | }; 746 | 747 | _onPressDisconnect = () => { 748 | Enx.disconnect(); 749 | }; 750 | } 751 | 752 | const styles = StyleSheet.create({ 753 | container: { 754 | flex: 1, 755 | 756 | backgroundColor: '#000000', 757 | justifyContent: 'center', 758 | 759 | }, 760 | flexList: { 761 | flexDirection: 'column', 762 | flexWrap: 'wrap', 763 | }, 764 | toolBarView: { 765 | height: 70, 766 | backgroundColor: '#0A0A0A', 767 | }, 768 | toolBar: { 769 | height: 70, 770 | backgroundColor: '#0A0A0A', 771 | }, 772 | logo: { 773 | marginBottom: 40, 774 | }, 775 | inputContainer: { 776 | paddingTop: 15, 777 | }, 778 | input: { 779 | marginBottom: 20, 780 | }, 781 | btnContainer: { 782 | marginTop: 10, 783 | }, 784 | selfView: { 785 | position: 'absolute', 786 | width: 101, 787 | height: 101, 788 | top: 10, 789 | right: 10, 790 | backgroundColor: 'white', 791 | justifyContent: 'center', 792 | alignItems: 'center', 793 | }, 794 | inlineImg: { 795 | width: 40, 796 | alignSelf: 'center', 797 | height: 40, 798 | zIndex: 50, 799 | top: 10, 800 | }, 801 | 802 | 803 | bottomBar: { 804 | position: 'absolute', 805 | width: '100%', 806 | height: 60, 807 | bottom: 0, 808 | 809 | marginRight:25, 810 | backgroundColor: 'transparent', 811 | 812 | }, 813 | rowContainer: { 814 | flexDirection: 'row', 815 | justifyContent: 'space-between', 816 | paddingHorizontal: 15, 817 | borderRadius: 20, 818 | marginLeft:20, 819 | marginRight:20, 820 | backgroundColor: '#D3D3D3', 821 | }, 822 | inlineImg1: { 823 | width: 40, 824 | height: 40, 825 | resizeMode: 'contain', 826 | }, 827 | }); 828 | 829 | //if you are using function base use below code with jsx 830 | // import React, { useState, useEffect, useCallback } from 'react'; 831 | // import { 832 | // Platform, 833 | // StyleSheet, 834 | // Text, 835 | // Alert, 836 | // TouchableHighlight, 837 | // TextInput, 838 | // Button, 839 | // View, 840 | // Dimensions, 841 | // Image, 842 | // PermissionsAndroid, 843 | // FlatList, 844 | // } from 'react-native'; 845 | // import PropTypes from 'prop-types'; 846 | // import { 847 | // EnxRoom, 848 | // Enx, 849 | // EnxStream, 850 | // EnxPlayerView, 851 | // EnxToolBarView, 852 | 853 | // } from 'enx-rtc-react-native'; 854 | // import axios from 'axios'; 855 | // import { BackHandler } from 'react-native'; 856 | 857 | // const EnxConferenceScreen = ({ route, navigation }) => { 858 | // // State management 859 | // const [screenHeight, setScreenHeight] = useState(Dimensions.get('window').height); 860 | // const [screenWidth, setScreenWidth] = useState(Dimensions.get('window').width); 861 | // const [isHorizontal, setIsHorizontal] = useState(false); 862 | // const [noOfColumn, setNoOfColumn] = useState(0); 863 | // const [selectedDevice, setSelectedDevice] = useState(''); 864 | // const [deviceList, setDeviceList] = useState([]); 865 | // const [base64Icon, setBase64Icon] = useState(''); 866 | // const [isInitialize, setIsInitialize] = useState(false); 867 | // const [activeTalkerStreams, setActiveTalkerStreams] = useState([]); 868 | // const [isUpdated, setIsUpdated] = useState(false); 869 | // const [recordingCheck, setRecordingCheck] = useState(false); 870 | // const [screenShareCheck, setScreenShareCheck] = useState(false); 871 | // const [toolBarCheck, setToolBarCheck] = useState(false); 872 | // const [audioMuteUnmuteCheck, setAudioMuteUnmuteCheck] = useState(true); 873 | // const [audioMuteUnmuteImage, setAudioMuteUnmuteImage] = useState(require('./image_asset/unmute.png')); 874 | // const [videoMuteUnmuteCheck, setVideoMuteUnmuteCheck] = useState(true); 875 | // const [videoMuteUnmuteImage, setVideoMuteUnmuteImage] = useState(require('./image_asset/startvideo.png')); 876 | // const [rotateCamera, setRotateCamera] = useState(false); 877 | // const [rotateCameraImage, setRotateCameraImage] = useState(require('./image_asset/switchcamera.png')); 878 | // const [canvasCheck, setCanvasCheck] = useState(false); 879 | // const [annotationCheck, setAnnotationCheck] = useState(false); 880 | // const [localStreamId, setLocalStreamId] = useState('0'); 881 | // const [screenShareId, setScreenShareId] = useState(null); 882 | // const [canvasStreamId, setCanvasStreamId] = useState(null); 883 | // const [activeStreamId, setActiveStreamId] = useState(null); 884 | // const [isConnected, setIsConnected] = useState(false); 885 | // const [annotationStreamId, setAnnotationStreamId] = useState(null); 886 | // const [permissionError, setPermissionError] = useState(false); 887 | 888 | // // Configuration objects 889 | // const [localStreamInfo] = useState({ 890 | // audio: true, 891 | // video: true, 892 | // data: false, 893 | // maxVideoBW: '400', 894 | // minVideoBW: '300', 895 | // audioMuted: false, 896 | // videoMuted: false, 897 | // name: 'React Native', 898 | // minWidth: '720', 899 | // minHeight: '480', 900 | // maxWidth: '1280', 901 | // maxHeight: '720', 902 | // audio_only: false, 903 | // }); 904 | 905 | // const [videoQual] = useState({ 906 | // streamType: 'talker', 907 | // videoQuality: 'SD', 908 | // }); 909 | 910 | // const [enxRoomInfo] = useState({ 911 | // allow_reconnect: false, 912 | // number_of_attempts: 3, 913 | // timeout_interval: 15, 914 | // playerConfiguration: { 915 | // audiomute: true, 916 | // videomute: true, 917 | // bandwidth: true, 918 | // screenshot: true, 919 | // avatar: true, 920 | // iconHeight: 30, 921 | // iconWidth: 30, 922 | // avatarHeight: 50, 923 | // avatarWidth: 50, 924 | // iconColor: '#dfc0ef' 925 | // }, 926 | // }); 927 | 928 | // const [advanceOptions] = useState({ 929 | // battery_updates: true, 930 | // notify_video_resolution_change: true, 931 | // }); 932 | 933 | // const [chat] = useState({ 934 | // message: 'Test chat', 935 | // from: 'React-Native', 936 | // timestamp: Date.now(), 937 | // }); 938 | 939 | // // Helper functions 940 | // const calculateColoum = (data) => { 941 | // if (data.length == 1 || data.length == 2) return 1; 942 | // else return 2; 943 | // }; 944 | 945 | // const calculateRow = (data) => { 946 | // if (data.length == 1) return 1; 947 | // else if (data.length == 2 || data.length == 3 || data.length == 4) return 2; 948 | // else if (data.length == 5 || data.length == 6) return 3; 949 | // else if (data.length == 7 || data.length == 8) return 4; 950 | // else if (data.length == 9 || data.length == 10 || data.length > 10) return 5; 951 | // }; 952 | 953 | // // Event handlers 954 | // const roomEventHandlers = { 955 | // roomConnected: (event) => { 956 | // console.log('roomConnected', event); 957 | // setIsConnected(true); 958 | // Enx.getLocalStreamId((status) => { 959 | // setLocalStreamId(status); 960 | // console.log("streamId2", "" + status); 961 | // }); 962 | // Enx.publish(); 963 | // }, 964 | // roomError: (event) => { 965 | // console.log('roomError', event); 966 | // if (event.msg == 'Network disconnected') { 967 | // navigation.goBack(); 968 | // } 969 | // }, 970 | // availableFiles: (event) => { 971 | // console.log('availableFiles', event); 972 | // }, 973 | // streamPublished: (event) => { 974 | // console.log('streamPublished', event); 975 | // }, 976 | // eventError: (event) => { 977 | // console.log('eventErrorrr', event); 978 | // if (permissionError) { 979 | // alert('Kindly grant camera and microphone permission to continue.'); 980 | // } 981 | // }, 982 | // streamAdded: (event) => { 983 | // console.log('streamAdded', event); 984 | // Enx.subscribe(event.streamId, (error) => { 985 | // console.log('streamAdded', error); 986 | // }); 987 | // }, 988 | // notifyDeviceUpdate: (event) => { 989 | // console.log('NotifyDeviceUpdate', event); 990 | // }, 991 | // activeTalkerList: (event) => { 992 | // var tempArray = []; 993 | // if (event.length == 0) { 994 | // setActiveTalkerStreams([]); 995 | // return; 996 | // } 997 | // if (event.lenght == activeTalkerStreams.length) return; 998 | // if (activeTalkerStreams.length > 0) { 999 | // setActiveTalkerStreams([]); 1000 | // } 1001 | // for (var i = 0; i < event.length; i++) { 1002 | // setActiveStreamId(event[0].streamId); 1003 | // tempArray.push(event[i]); 1004 | // } 1005 | // if (tempArray.length > 0) { 1006 | // setActiveTalkerStreams(tempArray); 1007 | // } 1008 | // }, 1009 | // streamSubscribed: (event) => { 1010 | // console.log('streamSubscribed', event); 1011 | // }, 1012 | // roomDisconnected: (event) => { 1013 | // console.log('disconnecteddddd', event); 1014 | // navigation.goBack(); 1015 | // }, 1016 | // recordStarted: (event) => { 1017 | // console.log('recordStartedddddd', event.msg); 1018 | // setRecordingCheck(true); 1019 | // }, 1020 | // recordStopped: (event) => { 1021 | // console.log('recordStopped', event.msg); 1022 | // setRecordingCheck(false); 1023 | // }, 1024 | // startRecordingEvent: (event) => { 1025 | // console.log('startRecordingEvent', event); 1026 | // if (event.result == '0') { 1027 | // setRecordingCheck(true); 1028 | // } 1029 | // }, 1030 | // stopRecordingEvent: (event) => { 1031 | // console.log('stopRecordingEvent', event); 1032 | // if (event.result == '0') { 1033 | // setRecordingCheck(false); 1034 | // } 1035 | // }, 1036 | // receivedStats: (event) => { 1037 | // console.log('receivedStats', event); 1038 | // }, 1039 | // acknowledgeStats: (event) => { 1040 | // console.log('acknowledgeStats', event); 1041 | // }, 1042 | // bandWidthUpdated: (event) => { 1043 | // console.log('bandWidthUpdated', event); 1044 | // }, 1045 | // shareStateEvent: (event) => { 1046 | // console.log('shareStateEvent', event); 1047 | // }, 1048 | // canvasStateEvent: (event) => { 1049 | // console.log('canvasStateEvent', event); 1050 | // }, 1051 | // startScreenShareACK: (event) => { 1052 | // console.log('startScreenShareACK', event); 1053 | // setScreenShareCheck(true); 1054 | // }, 1055 | // stoppedScreenShareACK: (event) => { 1056 | // console.log('stoppedScreenShareACK', event); 1057 | // setScreenShareCheck(false); 1058 | // }, 1059 | // screenShareStarted: (event) => { 1060 | // console.log('screenShareStarted', event); 1061 | // setScreenShareId(String(event.streamId)); 1062 | // setScreenShareCheck(true); 1063 | // }, 1064 | // sceenShareStopped: (event) => { 1065 | // console.log('sceenShareStoppedddd', event); 1066 | // setScreenShareCheck(false); 1067 | // }, 1068 | // canvasStarted: (event) => { 1069 | // setCanvasStreamId(String(event.streamId)); 1070 | // setCanvasCheck(true); 1071 | // }, 1072 | // canvasStopped: (event) => { 1073 | // console.log('canvasStoppedddd', event); 1074 | // setCanvasCheck(false); 1075 | // }, 1076 | // mutedAllUser: (event) => { 1077 | // console.log('mutedAllUser', event); 1078 | // }, 1079 | // unmutedAllUser: (event) => { 1080 | // console.log('unmutedAllUser', event); 1081 | // }, 1082 | // hardMutedAll: (event) => { 1083 | // console.log('hardMutedAll', event); 1084 | // }, 1085 | // hardUnmuteAllUser: (event) => { 1086 | // console.log('hardUnmuteAllUser', event); 1087 | // }, 1088 | // userConnected: (event) => { 1089 | // console.log('userConnected', event); 1090 | // }, 1091 | // userDisconnected: (event) => { 1092 | // console.log('userDisconnected', event); 1093 | // }, 1094 | // reconnect: (event) => { 1095 | // console.log('reconnect', event); 1096 | // }, 1097 | // userReconnect: (event) => { 1098 | // console.log('userReconnect', event); 1099 | // setActiveTalkerStreams([]); 1100 | // }, 1101 | // connectionInterrupted: (event) => { 1102 | // console.log('connectionInterrupted', event); 1103 | // }, 1104 | // connectionLost: (event) => { 1105 | // console.log('connectionLost', event); 1106 | // }, 1107 | // capturedView: (event) => { 1108 | // console.log('capturedView', event); 1109 | // setBase64Icon(event); 1110 | // }, 1111 | // ackStartStreaming: (event) => { 1112 | // console.log('ackStartStreaming', event); 1113 | // }, 1114 | // ackStopStreaming: (event) => { 1115 | // console.log('ackStopStreaming', event); 1116 | // }, 1117 | // streamingStarted: (event) => { 1118 | // console.log('streamingStarted', event); 1119 | // }, 1120 | // streamingStopped: (event) => { 1121 | // console.log('streamingStopped', event); 1122 | // }, 1123 | // streamingFailed: (event) => { 1124 | // console.log('streamingFailed', event); 1125 | // }, 1126 | // streamingUpdated: (event) => { 1127 | // console.log('streamingUpdated', event); 1128 | // }, 1129 | // customDataUpdated: (event) => { 1130 | // console.log('customDataUpdated', event); 1131 | // }, 1132 | // getCustomData: (event) => { 1133 | // console.log('getCustomData', event); 1134 | // }, 1135 | // ackCustomDataUpdated: (event) => { 1136 | // console.log('ackCustomDataUpdated', event); 1137 | // }, 1138 | // customDataSaved: (event) => { 1139 | // console.log('customDataSaved', event); 1140 | // }, 1141 | // }; 1142 | 1143 | // const streamEventHandlers = { 1144 | // audioEvent: (event) => { 1145 | // console.log('audioEvent', event); 1146 | // if (event.result == '0') { 1147 | // if (event.msg == 'Audio Off') { 1148 | // setAudioMuteUnmuteCheck(false); 1149 | // setAudioMuteUnmuteImage(require('./image_asset/mute.png')); 1150 | // } else { 1151 | // setAudioMuteUnmuteCheck(true); 1152 | // setAudioMuteUnmuteImage(require('./image_asset/unmute.png')); 1153 | // } 1154 | // } 1155 | // }, 1156 | // playerStats: (event) => { 1157 | // console.log('playerStats', event); 1158 | // }, 1159 | // videoEvent: (event) => { 1160 | // if (event.result == '0') { 1161 | // if (event.msg == 'Video Off') { 1162 | // setVideoMuteUnmuteCheck(false); 1163 | // setVideoMuteUnmuteImage(require('./image_asset/stopvideo.png')); 1164 | // } else { 1165 | // setVideoMuteUnmuteCheck(true); 1166 | // setVideoMuteUnmuteImage(require('./image_asset/startvideo.png')); 1167 | // } 1168 | // } 1169 | // }, 1170 | // hardMuteAudio: (event) => { 1171 | // console.log('hardMuteAudio', event); 1172 | // }, 1173 | // hardUnmuteAudio: (event) => { 1174 | // console.log('hardUnmuteAudio', event); 1175 | // }, 1176 | // recievedHardMutedAudio: (event) => { 1177 | // console.log('recievedHardMutedAudio', event); 1178 | // }, 1179 | // recievedHardUnmutedAudio: (event) => { 1180 | // console.log('recievedHardUnmutedAudio', event); 1181 | // }, 1182 | // hardVideoMute: (event) => { 1183 | // console.log('hardVideoMute', event); 1184 | // }, 1185 | // hardVideoUnmute: (event) => { 1186 | // console.log('hardVideoUnmute', event); 1187 | // }, 1188 | // receivehardMuteVideo: (event) => { 1189 | // console.log('receivehardMuteVideo', event); 1190 | // }, 1191 | // recivehardUnmuteVideo: (event) => { 1192 | // console.log('recivehardUnmuteVideo', event); 1193 | // }, 1194 | // receiveData: (event) => { 1195 | // console.log('receiveData', event); 1196 | // }, 1197 | // remoteStreamAudioMute: (event) => { 1198 | // console.log('remoteStreamAudioMute', event); 1199 | // }, 1200 | // remoteStreamAudioUnMute: (event) => { 1201 | // console.log('remoteStreamAudioUnMute', event); 1202 | // }, 1203 | // remoteStreamVideoMute: (event) => { 1204 | // console.log('remoteStreamVideoMute', event); 1205 | // }, 1206 | // remoteStreamVideoUnMuteevent: (event) => { 1207 | // console.log('remoteStreamVideoMute', event); 1208 | // }, 1209 | // }; 1210 | 1211 | // // Component methods converted to functions 1212 | // const renderItem = ({ item, index }) => { 1213 | // return ( 1214 | // 1225 | // ); 1226 | // }; 1227 | 1228 | // const requestPermission = async () => { 1229 | // try { 1230 | // const granted = await PermissionsAndroid.request( 1231 | // PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, 1232 | // { 1233 | // title: 'Enablex Storage Permission', 1234 | // message: 'Enablex needs access to your storage to write logs.', 1235 | // buttonNeutral: 'Ask Me Later', 1236 | // buttonNegative: 'Cancel', 1237 | // buttonPositive: 'OK', 1238 | // }, 1239 | // ); 1240 | // if (granted === PermissionsAndroid.RESULTS.GRANTED) { 1241 | // setPermissionError(true); 1242 | // Enx.postClientLogs(); 1243 | // } else { 1244 | // alert('Kindly grant storage permission to send logs.'); 1245 | // } 1246 | // } catch (err) { 1247 | // console.warn(err); 1248 | // } 1249 | // }; 1250 | 1251 | // const handleBackButton = useCallback(() => { 1252 | // Alert.alert( 1253 | // 'Exit App', 1254 | // 'Exiting the application?', 1255 | // [ 1256 | // { 1257 | // text: 'Cancel', 1258 | // onPress: () => console.log('Cancel Pressed'), 1259 | // style: 'cancel', 1260 | // }, 1261 | // { 1262 | // text: 'OK', 1263 | // onPress: () => BackHandler.exitApp(), 1264 | // }, 1265 | // ], 1266 | // { 1267 | // cancelable: false, 1268 | // }, 1269 | // ); 1270 | // return true; 1271 | // }, []); 1272 | 1273 | // const onLayout = (event) => { 1274 | // const { height, width } = event.nativeEvent.layout; 1275 | // setScreenHeight(height); 1276 | // setScreenWidth(width); 1277 | // }; 1278 | 1279 | // const onPressMute = () => { 1280 | // Enx.muteSelfAudio(localStreamId, audioMuteUnmuteCheck); 1281 | // }; 1282 | 1283 | // const onPressVideoMute = () => { 1284 | // Enx.muteSelfVideo(localStreamId, videoMuteUnmuteCheck); 1285 | // }; 1286 | 1287 | // const onPressSpeaker = () => { 1288 | // console.log('_onPressSpeaker', 'clicked'); 1289 | // Enx.getDevices((devices) => { 1290 | // console.log('_onPressSpeaker', devices); 1291 | // }); 1292 | // }; 1293 | 1294 | // const onPressSwitchCamera = () => { 1295 | // Enx.switchCamera(localStreamId); 1296 | // if (!rotateCamera) { 1297 | // setRotateCamera(true); 1298 | // setRotateCameraImage(require('./image_asset/switchcamera.png')); 1299 | // } else { 1300 | // setRotateCamera(false); 1301 | // setRotateCameraImage(require('./image_asset/switchcamera.png')); 1302 | // } 1303 | // }; 1304 | 1305 | // const onPressDisconnect = () => { 1306 | // Enx.disconnect(); 1307 | // }; 1308 | 1309 | // // Effects 1310 | // useEffect(() => { 1311 | // if (!isInitialize) { 1312 | // Enx.initRoom(); 1313 | // setIsInitialize(true); 1314 | 1315 | // } 1316 | 1317 | // const backHandler = BackHandler.addEventListener( 1318 | // 'hardwareBackPress', 1319 | // handleBackButton 1320 | // ); 1321 | 1322 | // return () => { 1323 | // backHandler.remove(); 1324 | // if (isInitialize) { 1325 | // setIsInitialize(false); 1326 | // } 1327 | 1328 | 1329 | // }; 1330 | // }, [isInitialize, handleBackButton]); 1331 | 1332 | // // Render 1333 | // const token = route.params ? route.params.token : ''; 1334 | // const username = route.params ? route.params.username : null; 1335 | 1336 | // if (!isInitialize) { 1337 | // return ( 1338 | // 1339 | // Initializing... 1340 | // 1341 | // ); 1342 | // } 1343 | 1344 | // return ( 1345 | // 1346 | // 1347 | // {activeTalkerStreams.length > 0 ? ( 1348 | // index.toString()} 1354 | // numColumns={calculateColoum(activeTalkerStreams)} 1355 | // /> 1356 | // ) : null} 1357 | // 1358 | // 1364 | // 1365 | // {isConnected ? ( 1366 | // 1376 | // ) : null} 1377 | // 1378 | // 1379 | // 1380 | // 1381 | // 1384 | // 1388 | // 1389 | // 1392 | // 1396 | // 1397 | // 1400 | // 1404 | // 1405 | // 1408 | // 1412 | // 1413 | // 1416 | // 1420 | // 1421 | // 1422 | // 1423 | // 1424 | // 1425 | // ); 1426 | // }; 1427 | 1428 | // const styles = StyleSheet.create({ 1429 | // container: { 1430 | // flex: 1, 1431 | // backgroundColor: '#000000', 1432 | // justifyContent: 'center', 1433 | // }, 1434 | // flexList: { 1435 | // flexDirection: 'column', 1436 | // }, 1437 | // toolBarView: { 1438 | // height: 70, 1439 | // backgroundColor: '#0A0A0A', 1440 | // }, 1441 | // toolBar: { 1442 | // height: 70, 1443 | // backgroundColor: '#0A0A0A', 1444 | // }, 1445 | // logo: { 1446 | // marginBottom: 40, 1447 | // }, 1448 | // inputContainer: { 1449 | // paddingTop: 15, 1450 | // }, 1451 | // input: { 1452 | // marginBottom: 20, 1453 | // }, 1454 | // btnContainer: { 1455 | // marginTop: 10, 1456 | // }, 1457 | // selfView: { 1458 | // position: 'absolute', 1459 | // width: 101, 1460 | // height: 101, 1461 | // top: 10, 1462 | // right: 10, 1463 | // backgroundColor: 'white', 1464 | // justifyContent: 'center', 1465 | // alignItems: 'center', 1466 | // }, 1467 | // inlineImg: { 1468 | // width: 40, 1469 | // alignSelf: 'center', 1470 | // height: 40, 1471 | // zIndex: 50, 1472 | // top: 10, 1473 | // }, 1474 | // bottomBar: { 1475 | // position: 'absolute', 1476 | // width: '100%', 1477 | // height: 60, 1478 | // bottom: 0, 1479 | // marginRight: 25, 1480 | // backgroundColor: 'transparent', 1481 | // }, 1482 | // rowContainer: { 1483 | // flexDirection: 'row', 1484 | // justifyContent: 'space-between', 1485 | // paddingHorizontal: 15, 1486 | // borderRadius: 20, 1487 | // marginLeft: 20, 1488 | // marginRight: 20, 1489 | // backgroundColor: '#D3D3D3', 1490 | // }, 1491 | // inlineImg1: { 1492 | // width: 40, 1493 | // height: 40, 1494 | // resizeMode: 'contain', 1495 | // }, 1496 | // }); 1497 | 1498 | // export default EnxConferenceScreen; 1499 | -------------------------------------------------------------------------------- /src/EnxJoinScreen.tsx: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from "react"; 2 | import { 3 | Platform, 4 | StyleSheet, 5 | Text, 6 | Alert, 7 | TouchableHighlight, 8 | TextInput, 9 | View, 10 | ScrollView, 11 | PermissionsAndroid 12 | } from "react-native"; 13 | import axios from "axios"; 14 | import Logo from "./Logo"; 15 | 16 | interface Props { 17 | navigation: any; 18 | } 19 | 20 | interface State { 21 | user_name: string; 22 | room_id: string; 23 | } 24 | 25 | export default class App extends PureComponent { 26 | infos: any = null; 27 | res_token: any = null; 28 | 29 | constructor(props: Props) { 30 | super(props); 31 | this.state = { 32 | user_name: "React Native", 33 | room_id: "" 34 | }; 35 | } 36 | 37 | render() { 38 | return ( 39 | 43 | 44 | 45 | 46 | this.setState({ user_name })} 52 | value={this.state.user_name} 53 | returnKeyType="next" 54 | autoCorrect={false} 55 | placeholderTextColor="#757575" 56 | underlineColorAndroid="transparent" 57 | /> 58 | 59 | this.setState({ room_id })} 65 | value={this.state.room_id} 66 | keyboardType="default" 67 | returnKeyType="next" 68 | autoCorrect={false} 69 | placeholderTextColor="#757575" 70 | underlineColorAndroid="transparent" 71 | /> 72 | 73 | 74 | this._onCreate_Room()} 78 | > 79 | Create Room 80 | 81 | 82 | this._onJoin_Room()} 86 | > 87 | Join 88 | 89 | 90 | 91 | 92 | ); 93 | } 94 | 95 | async _onCreate_Room() { 96 | if (Platform.OS === "android") { 97 | try { 98 | await this.checkAndroidPermissions(); 99 | 100 | await this.getRoomIDWebCall(); 101 | } catch (error) { 102 | console.log("checkAndroidPermissions", error); 103 | } 104 | } else { 105 | await this.getRoomIDWebCall(); 106 | } 107 | } 108 | 109 | _onJoin_Room() { 110 | const { user_name, room_id } = this.state; 111 | if (!user_name && !room_id) { 112 | alert("Please enter your details"); 113 | } else if (!user_name) { 114 | alert("Please enter your name"); 115 | } else if (!room_id) { 116 | alert("Please enter roomId"); 117 | } else { 118 | this.navigateToVideo(); 119 | } 120 | } 121 | 122 | async getRoomIDWebCall() { 123 | const header = kTry 124 | ? { "x-app-id": kAppId, "x-app-key": kAppkey } 125 | : {}; 126 | const options = { 127 | headers: header 128 | }; 129 | 130 | try { 131 | const response = await axios.post( 132 | kBaseURL + "createRoom/", 133 | {}, 134 | options 135 | ); 136 | if (response.data.result !== 0) { 137 | alert(response.data.desc); 138 | return; 139 | } else { 140 | const infos = response.data; 141 | if (typeof infos === 'object' && infos !== null) { 142 | const infosObj = infos as { room?: { room_id?: string } }; 143 | this.setState({ room_id: infosObj.room?.room_id ?? "" }); 144 | } else { 145 | this.setState({ room_id: "" }); 146 | } 147 | } 148 | } catch (error) { 149 | console.log("axiosRoomIdCatchError", error); 150 | } 151 | } 152 | 153 | async getRoomTokenWebCall() { 154 | const header = kTry 155 | ? { "x-app-id": kAppId, "x-app-key": kAppkey } 156 | : {}; 157 | const options = { 158 | headers: header 159 | }; 160 | try { 161 | const response = await axios.post( 162 | kBaseURL + "createToken/", 163 | { 164 | name: this.state.user_name, 165 | role: "participant", 166 | user_ref: "2236", 167 | roomId: this.state.room_id 168 | }, 169 | options 170 | ); 171 | this.res_token = response.data; 172 | console.log("axiosResponsetoken", this.res_token); 173 | } catch (error) { 174 | console.log("axiosCreateTokenCatch", error); 175 | } 176 | } 177 | 178 | async navigateToVideo() { 179 | await this.getRoomTokenWebCall(); 180 | if (!this.res_token) { 181 | console.error("Token is not fetched"); 182 | return; 183 | } 184 | 185 | const { user_name, room_id } = this.state; 186 | const { navigation } = this.props; 187 | 188 | try { 189 | if (typeof this.res_token === 'object' && this.res_token !== null) { 190 | const tokenObj = this.res_token as { result?: number; token?: string; error?: string }; 191 | if (tokenObj.result === 0) { 192 | navigation.navigate("EnxConferenceScreen", { 193 | username: user_name, 194 | token: tokenObj.token 195 | }); 196 | } else { 197 | alert(tokenObj.error); 198 | console.log(tokenObj.error); 199 | } 200 | } else { 201 | // Handle the case where this.res_token is not an object 202 | } 203 | } catch (error) { 204 | console.log("navigationError", error); 205 | } 206 | } 207 | 208 | checkAndroidPermissions = async () => { 209 | try { 210 | const result = await PermissionsAndroid.requestMultiple([ 211 | PermissionsAndroid.PERMISSIONS.CAMERA, 212 | PermissionsAndroid.PERMISSIONS.RECORD_AUDIO 213 | ]); 214 | const permissionsError = { permissionsDenied: [], type: "Permissions error" }; 215 | for (const [permissionType, permissionValue] of Object.entries(result)) { 216 | if (permissionValue === "denied") { 217 | console.log("denied Permission"); 218 | permissionsError.permissionsDenied.push(permissionType); 219 | } 220 | } 221 | if (permissionsError.permissionsDenied.length > 0) { 222 | console.log("denied Permission"); 223 | throw permissionsError; 224 | } else { 225 | console.log("granted Permission"); 226 | } 227 | } catch (error) { 228 | throw error; 229 | } 230 | }; 231 | } 232 | 233 | const styles = StyleSheet.create({ 234 | container: { 235 | marginLeft: 10, 236 | marginRight: 10, 237 | marginBottom: 10 238 | }, 239 | input: { 240 | height: 40, 241 | width: 300, 242 | borderColor: "#eae7e7", 243 | backgroundColor: "#eae7e7", 244 | borderWidth: 2, 245 | borderRadius: 10, 246 | marginBottom: 20, 247 | alignSelf: "center", 248 | color: "black" 249 | }, 250 | buttonsContainer: { 251 | flex: 2, 252 | flexDirection: "row", 253 | width: 250, 254 | bottom: 0, 255 | alignSelf: "center", 256 | alignItems: "center", 257 | justifyContent: "space-between", 258 | borderRadius: 25 259 | }, 260 | button: { 261 | height: 40, 262 | width: 120, 263 | borderColor: "#534367", 264 | backgroundColor: "#534367", 265 | borderRadius: 20, 266 | alignItems: "center" 267 | }, 268 | buttonText: { 269 | color: "white", 270 | marginTop: 5, 271 | fontSize: 16, 272 | alignSelf: "center", 273 | justifyContent: "center" 274 | } 275 | }); 276 | 277 | /* Your webservice host URL, Keep the defined host when kTry = true */ 278 | const kBaseURL = "https://demo.enablex.io/"; 279 | /* To try the app with Enablex hosted service you need to set the kTry = true */ 280 | const kTry = true; 281 | /* Use Enablex portal to create your app and get these following credentials */ 282 | const kAppId = "app-Id"; 283 | const kAppkey = "App-Key"; -------------------------------------------------------------------------------- /src/Logo.tsx: -------------------------------------------------------------------------------- 1 | // Import React and other necessary modules 2 | import React, { Component } from "react"; 3 | import { StyleSheet, View, Text, Image } from "react-native"; 4 | 5 | // Import the logo image 6 | import logoImg from "./image_asset/logofront.png"; 7 | 8 | // Define the Logo component 9 | export default class Logo extends Component { 10 | // Method to focus on the component 11 | focusOnComponent() { 12 | // Type assertion to bypass type checking 13 | (this.refs.container as any).focus(); 14 | } 15 | 16 | // Render method 17 | render() { 18 | return ( 19 | 20 | 21 | Welcome! 22 | 23 | ); 24 | } 25 | } 26 | 27 | // Styles for the Logo component 28 | const styles = StyleSheet.create({ 29 | container: { 30 | alignSelf: "center" 31 | }, 32 | image: { 33 | height: 50, 34 | width: 220, 35 | marginTop: 100 36 | }, 37 | text: { 38 | color: "black", 39 | alignSelf: "center", 40 | fontSize: 28, 41 | marginTop: 75 42 | } 43 | }); 44 | -------------------------------------------------------------------------------- /src/image_asset/disconnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/disconnect.png -------------------------------------------------------------------------------- /src/image_asset/logofront.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/logofront.png -------------------------------------------------------------------------------- /src/image_asset/menuList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/menuList.png -------------------------------------------------------------------------------- /src/image_asset/mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/mute.png -------------------------------------------------------------------------------- /src/image_asset/raise_hand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/raise_hand.png -------------------------------------------------------------------------------- /src/image_asset/recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/recording.png -------------------------------------------------------------------------------- /src/image_asset/speaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/speaker.png -------------------------------------------------------------------------------- /src/image_asset/speakermute@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/speakermute@2x.png -------------------------------------------------------------------------------- /src/image_asset/startvideo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/startvideo.png -------------------------------------------------------------------------------- /src/image_asset/stopvideo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/stopvideo.png -------------------------------------------------------------------------------- /src/image_asset/switchcamera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/switchcamera.png -------------------------------------------------------------------------------- /src/image_asset/unmute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnableX/One-to-One-Video-Calling-Open-Source-React-Native-Application/41ab800ad202de5b173ee3523c161ba7e40e1901/src/image_asset/unmute.png -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react" 4 | }, 5 | "compilerOptions": { 6 | "jsx": "react" 7 | }, 8 | "extends": "@react-native/typescript-config/tsconfig.json" 9 | } -------------------------------------------------------------------------------- /types/images.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.png" { 2 | const value: any; 3 | export = value; 4 | } --------------------------------------------------------------------------------