├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── RNChat ├── .bundle │ └── config ├── .config-files ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── .yarn │ └── releases │ │ └── yarn-4.5.3.cjs ├── .yarnrc.yml ├── App.js ├── Gemfile ├── Gemfile.lock ├── README.md ├── __tests__ │ └── App.test.tsx ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── rnchat │ │ │ │ ├── MainActivity.kt │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable-mdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable-xhdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable-xxhdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable-xxxhdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable │ │ │ ├── ic_launcher.png │ │ │ ├── rn_edit_text_material.xml │ │ │ └── splash_screen.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 │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── assets │ └── image │ │ ├── icon.png │ │ ├── logo.png │ │ └── splash.png ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── Podfile │ ├── Podfile.lock │ ├── RNChat.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── RNChat.xcscheme │ ├── RNChat.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── RNChat │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── 1024.png │ │ │ │ ├── 120.png │ │ │ │ ├── 180.png │ │ │ │ ├── 40.png │ │ │ │ ├── 58.png │ │ │ │ ├── 60.png │ │ │ │ ├── 80.png │ │ │ │ ├── 87.png │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── PrivacyInfo.xcprivacy │ │ └── main.m │ └── RNChatTests │ │ ├── Info.plist │ │ └── RNChatTests.m ├── jest.config.js ├── metro.config.js ├── package.json ├── src │ ├── config.js │ ├── events.js │ ├── helpers │ │ ├── alert.js │ │ ├── constants.js │ │ ├── file.js │ │ ├── getTime.js │ │ └── platform.js │ ├── hooks │ │ └── useKeyboardOffset.js │ ├── models │ │ ├── dialogs.js │ │ ├── message.js │ │ └── user.js │ ├── navigation │ │ ├── AppStack.js │ │ ├── AuthStack.js │ │ ├── MainStack.js │ │ └── index.js │ ├── redux │ │ ├── reducer-function.js │ │ ├── slices │ │ │ ├── app.js │ │ │ ├── currentUser.js │ │ │ ├── dialogs.js │ │ │ ├── messages.js │ │ │ ├── selectedDialog.js │ │ │ └── users.js │ │ └── store.js │ ├── screens │ │ ├── auth │ │ │ ├── AuthForm.js │ │ │ ├── AuthLinks.js │ │ │ ├── AuthLogo.js │ │ │ └── index.js │ │ ├── components │ │ │ ├── avatar.js │ │ │ ├── chatImage.js │ │ │ ├── createBtn.js │ │ │ ├── imgPicker.js │ │ │ ├── indicator.js │ │ │ └── messageStatus.js │ │ ├── main │ │ │ ├── chat │ │ │ │ ├── contactDetails.js │ │ │ │ ├── groupDetails.js │ │ │ │ ├── imageViewer.js │ │ │ │ ├── index.js │ │ │ │ └── message.js │ │ │ ├── contacts │ │ │ │ ├── createDialog.js │ │ │ │ ├── index.js │ │ │ │ └── participant.js │ │ │ ├── dialogs │ │ │ │ ├── elements │ │ │ │ │ ├── dialog.js │ │ │ │ │ ├── dialogLastDate.js │ │ │ │ │ ├── dialogTitle.js │ │ │ │ │ └── dialogUnreadCounter.js │ │ │ │ └── index.js │ │ │ └── settings │ │ │ │ └── index.js │ │ └── splash.js │ └── services │ │ ├── auth-service.js │ │ ├── chat-service.js │ │ ├── index.js │ │ ├── push-notification.js │ │ └── users-service.js ├── tsconfig.json └── yarn.lock ├── RNVideoChat ├── .bundle │ └── config ├── .config-files ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── .yarn │ └── releases │ │ └── yarn-3.6.4.cjs ├── .yarnrc.yml ├── App.jsx ├── Gemfile ├── Gemfile.lock ├── README.md ├── __tests__ │ └── App.test.tsx ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── rnvideochat │ │ │ │ ├── CallNotificationFCMService.kt │ │ │ │ ├── CallNotificationHeadlessJsTask.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable-mdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable-xhdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable-xxhdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable-xxxhdpi │ │ │ └── ic_notification.png │ │ │ ├── drawable │ │ │ ├── ic_check.png │ │ │ ├── ic_close.png │ │ │ ├── ic_launcher.png │ │ │ ├── rn_edit_text_material.xml │ │ │ └── splash_screen.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 │ │ │ ├── raw │ │ │ └── calling.mp3 │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── assets │ ├── image │ │ ├── icon.png │ │ ├── logo.png │ │ └── splash.png │ └── sounds │ │ ├── calling.mp3 │ │ ├── dialing.mp3 │ │ └── end_call.mp3 ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── Podfile │ ├── Podfile.lock │ ├── RNVideoChat.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── RNVideoChat.xcscheme │ ├── RNVideoChat.xcworkspace │ │ └── contents.xcworkspacedata │ ├── RNVideoChat │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── 1024.png │ │ │ │ ├── 120 1.png │ │ │ │ ├── 120.png │ │ │ │ ├── 180.png │ │ │ │ ├── 40.png │ │ │ │ ├── 58.png │ │ │ │ ├── 60.png │ │ │ │ ├── 80.png │ │ │ │ ├── 87.png │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── PrivacyInfo.xcprivacy │ │ └── main.m │ ├── RNVideoChatTests │ │ ├── Info.plist │ │ └── RNVideoChatTests.m │ └── icon.png ├── jest.config.js ├── metro.config.js ├── package.json ├── src │ ├── components │ │ ├── generic │ │ │ ├── loader.js │ │ │ ├── logout-button.js │ │ │ ├── video-grid.js │ │ │ └── video-toolbar.js │ │ └── screens │ │ │ ├── incoming-call-screen.js │ │ │ ├── initiate-call-screen.js │ │ │ ├── login-screen.js │ │ │ └── video-screen.js │ ├── config.js │ ├── redux │ │ ├── slices │ │ │ ├── activeCall.js │ │ │ ├── currentUser.js │ │ │ └── isLogging.js │ │ └── store.js │ ├── services │ │ ├── auth-service.js │ │ ├── call-keep-service.js │ │ ├── call-service.js │ │ ├── index.js │ │ └── push-notifications-service.js │ └── utils.js ├── tsconfig.json └── yarn.lock └── RNVideoChatConf ├── .bundle └── config ├── .config-files ├── .eslintrc.js ├── .gitignore ├── .node-version ├── .prettierrc.js ├── .watchmanconfig ├── .yarn └── releases │ └── yarn-4.5.0.cjs ├── .yarnrc.yml ├── App.js ├── Gemfile ├── Gemfile.lock ├── README.md ├── __tests__ └── App.test.tsx ├── android ├── app │ ├── build.gradle │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── rnvideochatconf │ │ │ ├── MainActivity.kt │ │ │ └── MainApplication.kt │ │ └── res │ │ ├── drawable │ │ ├── ic_launcher.png │ │ ├── rn_edit_text_material.xml │ │ └── splash_screen.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 │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── app.json ├── assets ├── icon.png ├── logo.png └── sounds │ ├── calling.mp3 │ ├── dialing.mp3 │ └── end_call.mp3 ├── babel.config.js ├── index.js ├── ios ├── .xcode.env ├── Podfile ├── Podfile.lock ├── RNVideoChatConf.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── RNVideoChatConf.xcscheme ├── RNVideoChatConf.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── RNVideoChatConf │ ├── AppDelegate.h │ ├── AppDelegate.mm │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── 1024.png │ │ │ ├── 120.png │ │ │ ├── 180.png │ │ │ ├── 40.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ ├── LaunchScreen.storyboard │ ├── PrivacyInfo.xcprivacy │ ├── RNVideoChatConf.entitlements │ └── main.m ├── RNVideoChatConfTests │ ├── Info.plist │ └── RNVideoChatConfTests.m └── broadcast-extension │ ├── Atomic.swift │ ├── DarwinNotificationCenter.swift │ ├── Info.plist │ ├── SampleHandler.swift │ ├── SampleUploader.swift │ ├── SocketConnection.swift │ └── broadcast-extension.entitlements ├── jest.config.js ├── metro.config.js ├── package.json ├── src ├── components │ ├── AuthScreen │ │ └── index.js │ └── VideoScreen │ │ ├── CallingLoader.js │ │ ├── RTCViewFullScreenModal.js │ │ ├── RTCViewGrid.js │ │ ├── ShareScreenButton.js │ │ ├── ToolBar.js │ │ ├── UsersSelect.js │ │ └── index.js ├── config.js ├── navigator.js └── services │ ├── auth-service.js │ ├── call-service.js │ ├── customEvents.js │ └── index.js ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | .DS_Store 64 | 65 | google-services.json 66 | GoogleService-Info.plist 67 | 68 | index.android.bundle -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "Notifee" 4 | ], 5 | "editor.defaultFormatter": "esbenp.prettier-vscode", 6 | "notebook.defaultFormatter": "esbenp.prettier-vscode" 7 | } -------------------------------------------------------------------------------- /RNChat/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /RNChat/.config-files: -------------------------------------------------------------------------------- 1 | src/config.js -------------------------------------------------------------------------------- /RNChat/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /RNChat/.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 | -------------------------------------------------------------------------------- /RNChat/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /RNChat/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /RNChat/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | nodeLinker: node-modules 6 | 7 | yarnPath: .yarn/releases/yarn-4.5.3.cjs 8 | -------------------------------------------------------------------------------- /RNChat/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Provider } from 'react-redux'; 3 | import { KeyboardProvider } from 'react-native-keyboard-controller'; 4 | import store from './src/redux/store'; 5 | import Navigation from './src/navigation'; 6 | 7 | export default function App() { 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /RNChat/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 | # Exclude problematic versions of cocoapods and activesupport that causes build failures. 7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' 8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' 9 | -------------------------------------------------------------------------------- /RNChat/__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 | -------------------------------------------------------------------------------- /RNChat/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/debug.keystore -------------------------------------------------------------------------------- /RNChat/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 | -------------------------------------------------------------------------------- /RNChat/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /RNChat/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /RNChat/android/app/src/main/java/com/rnchat/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.connectycube.samplechatrn 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 = "RNChat" 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 | -------------------------------------------------------------------------------- /RNChat/android/app/src/main/java/com/rnchat/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.connectycube.samplechatrn 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 | import com.wix.reactnativenotifications.RNNotificationsPackage 14 | 15 | class MainApplication : Application(), ReactApplication { 16 | 17 | override val reactNativeHost: ReactNativeHost = 18 | object : DefaultReactNativeHost(this) { 19 | override fun getPackages(): List = 20 | PackageList(this).packages.apply { 21 | // Packages that cannot be autolinked yet can be added manually here, for example: 22 | // add(MyReactNativePackage()) 23 | } 24 | 25 | override fun getJSMainModuleName(): String = "index" 26 | 27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 28 | 29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 31 | } 32 | 33 | override val reactHost: ReactHost 34 | get() = getDefaultReactHost(applicationContext, reactNativeHost) 35 | 36 | override fun onCreate() { 37 | super.onCreate() 38 | SoLoader.init(this, false) 39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 40 | // If you opted-in for the New Architecture, we load the native entry point for this app. 41 | load() 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/drawable-hdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/drawable-hdpi/ic_notification.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/drawable-mdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/drawable-mdpi/ic_notification.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/drawable-xhdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/drawable-xhdpi/ic_notification.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/drawable-xxhdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/drawable-xxhdpi/ic_notification.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/drawable/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/drawable/ic_launcher.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #00D2D3 4 | #ffffff 5 | #000000 6 | #00000000 7 | -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RNChat 3 | 4 | -------------------------------------------------------------------------------- /RNChat/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /RNChat/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 23 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "26.1.10909125" 8 | kotlinVersion = "1.9.24" 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 | classpath("com.google.gms:google-services:4.4.2") 19 | } 20 | } 21 | 22 | apply plugin: "com.facebook.react.rootproject" 23 | -------------------------------------------------------------------------------- /RNChat/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 | 25 | # Use this property to specify which architecture you want to build. 26 | # You can also override it from the CLI using 27 | # ./gradlew -PreactNativeArchitectures=x86_64 28 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 29 | 30 | # Use this property to enable support to the new architecture. 31 | # This will allow you to use TurboModules and the Fabric render in 32 | # your application. You should enable this flag either if you want 33 | # to write custom TurboModules/Fabric components OR use libraries that 34 | # are providing them. 35 | newArchEnabled=false 36 | 37 | # Use this property to enable or disable the Hermes JS engine. 38 | # If set to false, you will be using JSC instead. 39 | hermesEnabled=true 40 | -------------------------------------------------------------------------------- /RNChat/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /RNChat/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /RNChat/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } 2 | plugins { id("com.facebook.react.settings") } 3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } 4 | rootProject.name = 'RNChat' 5 | include ':react-native-notifications' 6 | project(':react-native-notifications').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-notifications/lib/android/app') 7 | include ':app' 8 | includeBuild('../node_modules/@react-native/gradle-plugin') 9 | -------------------------------------------------------------------------------- /RNChat/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RNChat", 3 | "displayName": "RNChat" 4 | } 5 | -------------------------------------------------------------------------------- /RNChat/assets/image/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/assets/image/icon.png -------------------------------------------------------------------------------- /RNChat/assets/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/assets/image/logo.png -------------------------------------------------------------------------------- /RNChat/assets/image/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/assets/image/splash.png -------------------------------------------------------------------------------- /RNChat/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | plugins: ['react-native-reanimated/plugin'], 4 | }; 5 | -------------------------------------------------------------------------------- /RNChat/index.js: -------------------------------------------------------------------------------- 1 | import 'react-native-gesture-handler'; 2 | import { AppRegistry, LogBox } from 'react-native'; 3 | import App from './App'; 4 | import { name as appName } from './app.json'; 5 | import { PushNotificationService } from './src/services'; 6 | 7 | LogBox.ignoreLogs(['']); 8 | PushNotificationService.registerEvents(); 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /RNChat/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 | -------------------------------------------------------------------------------- /RNChat/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 'RNChat' do 18 | config = use_native_modules! 19 | 20 | use_react_native!( 21 | :path => config[:reactNativePath], 22 | # An absolute path to your application root. 23 | :app_path => "#{Pod::Config.instance.installation_root}/.." 24 | ) 25 | 26 | target 'RNChatTests' do 27 | inherit! :complete 28 | # Pods for testing 29 | end 30 | 31 | post_install do |installer| 32 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 33 | react_native_post_install( 34 | installer, 35 | config[:reactNativePath], 36 | :mac_catalyst_enabled => false, 37 | # :ccache_enabled => true 38 | ) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | #import "RNNotifications.h" // react-native-notifications 6 | 7 | @implementation AppDelegate 8 | 9 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 10 | { 11 | self.moduleName = @"RNChat"; 12 | // You can add your custom initial props in the dictionary below. 13 | // They will be passed down to the ViewController used by React Native. 14 | self.initialProps = @{}; 15 | 16 | [RNNotifications startMonitorNotifications]; // react-native-notifications 17 | 18 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 19 | } 20 | 21 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 22 | { 23 | return [self bundleURL]; 24 | } 25 | 26 | - (NSURL *)bundleURL 27 | { 28 | #if DEBUG 29 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 30 | #else 31 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 32 | #endif 33 | } 34 | 35 | // react-native-notifications 36 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 37 | [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; 38 | } 39 | 40 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { 41 | [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error]; 42 | } 43 | 44 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler { 45 | [RNNotifications didReceiveBackgroundNotification:userInfo withCompletionHandler:completionHandler]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "40.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "60.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "58.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "87.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "80.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "120.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "120.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "180.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "1024.png", 53 | "idiom" : "ios-marketing", 54 | "scale" : "1x", 55 | "size" : "1024x1024" 56 | } 57 | ], 58 | "info" : { 59 | "author" : "xcode", 60 | "version" : 1 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RNChat 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 | NSAllowsArbitraryLoads 30 | 31 | NSAllowsLocalNetworking 32 | 33 | 34 | NSLocationWhenInUseUsageDescription 35 | 36 | NSPhotoLibraryUsageDescription 37 | $(PRODUCT_NAME) would like access to your photo gallery 38 | UIAppFonts 39 | 40 | AntDesign.ttf 41 | Entypo.ttf 42 | FontAwesome.ttf 43 | MaterialIcons.ttf 44 | 45 | UIBackgroundModes 46 | 47 | remote-notification 48 | 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | arm64 55 | 56 | UISupportedInterfaceOrientations 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationLandscapeLeft 60 | UIInterfaceOrientationLandscapeRight 61 | 62 | UIViewControllerBasedStatusBarAppearance 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryFileTimestamp 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | C617.1 13 | 3B52.1 14 | 15 | 16 | 17 | NSPrivacyAccessedAPIType 18 | NSPrivacyAccessedAPICategorySystemBootTime 19 | NSPrivacyAccessedAPITypeReasons 20 | 21 | 35F9.1 22 | 23 | 24 | 25 | NSPrivacyAccessedAPIType 26 | NSPrivacyAccessedAPICategoryUserDefaults 27 | NSPrivacyAccessedAPITypeReasons 28 | 29 | CA92.1 30 | 31 | 32 | 33 | NSPrivacyAccessedAPIType 34 | NSPrivacyAccessedAPICategoryDiskSpace 35 | NSPrivacyAccessedAPITypeReasons 36 | 37 | 85F4.1 38 | 39 | 40 | 41 | NSPrivacyCollectedDataTypes 42 | 43 | NSPrivacyTracking 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /RNChat/ios/RNChat/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 | -------------------------------------------------------------------------------- /RNChat/ios/RNChatTests/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 | -------------------------------------------------------------------------------- /RNChat/ios/RNChatTests/RNChatTests.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 RNChatTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation RNChatTests 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 | -------------------------------------------------------------------------------- /RNChat/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /RNChat/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 | -------------------------------------------------------------------------------- /RNChat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RNChat", 3 | "version": "2.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "react-native start", 7 | "restart": "yarn start --reset-cache", 8 | "android": "react-native run-android", 9 | "ios": "react-native run-ios", 10 | "xcode": "open ios/RNVideoChatConf.xcworkspace", 11 | "clean:ios": "rm -f ios/Podfile.lock && rm -rf ios/Pods && rm -rf ios/build", 12 | "clean:android": "rm -rf android/app/build && rm -rf android/.gradle", 13 | "clean:gradle": "cd android && ./gradlew --stop && ./gradlew clean && ./gradlew cleanBuild && cd ..", 14 | "clean:yarn": "rm -rf node_modules/ && rm -f yarn.lock", 15 | "lint": "eslint .", 16 | "test": "jest" 17 | }, 18 | "dependencies": { 19 | "@react-native-async-storage/async-storage": "^2.0.0", 20 | "@react-navigation/elements": "^1.3.31", 21 | "@react-navigation/native": "^6.1.18", 22 | "@react-navigation/native-stack": "^6.11.0", 23 | "@reduxjs/toolkit": "^2.2.8", 24 | "react": "18.3.1", 25 | "react-native": "0.75.4", 26 | "react-native-connectycube": "^4.0.0", 27 | "react-native-device-info": "^13.0.0", 28 | "react-native-gesture-handler": "^2.20.0", 29 | "react-native-image-crop-picker": "^0.41.3", 30 | "react-native-keyboard-controller": "1.14.0", 31 | "react-native-notifications": "^5.1.0", 32 | "react-native-reanimated": "^3.15.4", 33 | "react-native-safe-area-context": "^4.11.0", 34 | "react-native-screens": "^3.34.0", 35 | "react-native-vector-icons": "^10.2.0", 36 | "react-native-webrtc": "^124.0.4", 37 | "react-native-zoom-toolkit": "^3.1.0", 38 | "react-redux": "^9.1.2", 39 | "redux": "^5.0.1" 40 | }, 41 | "devDependencies": { 42 | "@babel/core": "^7.20.0", 43 | "@babel/preset-env": "^7.20.0", 44 | "@babel/runtime": "^7.20.0", 45 | "@react-native/babel-preset": "0.75.4", 46 | "@react-native/eslint-config": "0.75.4", 47 | "@react-native/metro-config": "0.75.4", 48 | "@react-native/typescript-config": "0.75.4", 49 | "@types/react": "^18.2.6", 50 | "@types/react-test-renderer": "^18.0.0", 51 | "babel-jest": "^29.6.3", 52 | "eslint": "^8.19.0", 53 | "jest": "^29.6.3", 54 | "prettier": "2.8.8", 55 | "react-test-renderer": "18.3.1", 56 | "typescript": "5.0.4" 57 | }, 58 | "engines": { 59 | "node": ">=18" 60 | }, 61 | "packageManager": "yarn@4.5.3" 62 | } 63 | -------------------------------------------------------------------------------- /RNChat/src/config.js: -------------------------------------------------------------------------------- 1 | export const appCredentials = { 2 | appId: REPLACE_APP_ID, 3 | authKey: 'REPLACE_APP_AUTH_KEY', 4 | }; 5 | 6 | export const appConfig = { 7 | chat: { 8 | streamManagement: { 9 | enable: true, 10 | }, 11 | }, 12 | debug: { 13 | mode: 1, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /RNChat/src/events.js: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'events'; 2 | 3 | const CUSTOM_EVENTS = { 4 | ON_NOTIFICATION_OPEN: 'ON_NOTIFICATION_OPEN', 5 | }; 6 | 7 | const customEventEmitter = new EventEmitter(); 8 | 9 | export { CUSTOM_EVENTS }; 10 | 11 | export default customEventEmitter; 12 | -------------------------------------------------------------------------------- /RNChat/src/helpers/alert.js: -------------------------------------------------------------------------------- 1 | import { Alert } from 'react-native'; 2 | 3 | export function showAlert(message, title = '') { 4 | Alert.alert( 5 | title, 6 | message, 7 | [ 8 | { text: 'Ok' }, 9 | ], 10 | { cancelable: false }, 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /RNChat/src/helpers/constants.js: -------------------------------------------------------------------------------- 1 | import { Dimensions } from 'react-native'; 2 | 3 | export const SIZE_SCREEN = Dimensions.get('screen'); 4 | 5 | export const BTN_TYPE = { 6 | DIALOG: 1, 7 | CONTACTS: 2, 8 | CREATE_GROUP: 3, 9 | }; 10 | 11 | export const DIALOG_TYPE = { 12 | PRIVATE: 3, 13 | GROUP: 2, 14 | BROADCAST: 1, 15 | PUBLIC_CHANNEL: 4, 16 | }; 17 | -------------------------------------------------------------------------------- /RNChat/src/helpers/file.js: -------------------------------------------------------------------------------- 1 | import ConnectyCube from 'react-native-connectycube'; 2 | 3 | export function preparationUploadImg(file) { 4 | const str = file.path.split('/'); 5 | const name = str[str.length - 1]; 6 | return { 7 | caption: '', 8 | duration: null, 9 | height: file.height, 10 | name, 11 | path: file.path, 12 | size: file.size, 13 | type: file.mime, 14 | width: file.width, 15 | uri: `file://${file.path}`, 16 | }; 17 | } 18 | 19 | export function preparationAttachment(file, uid) { 20 | const str = file.path.split('/'); 21 | const name = str[str.length - 1]; 22 | return { 23 | height: file.height, 24 | name, 25 | uid: uid ? uid : file.path, 26 | url: file.path, 27 | size: file.size, 28 | type: file.mime, 29 | width: file.width, 30 | }; 31 | } 32 | 33 | export function getImageLinkFromUID(uid) { 34 | if (!uid) { 35 | return null; 36 | } 37 | return ConnectyCube.storage.privateUrl(uid); 38 | } 39 | 40 | 41 | export function getCbToken(uri) { 42 | const source = { uri, headers: {} }; 43 | const matchResult = uri.match(/^(.+)\?token=(.+)/i); 44 | source.uri = matchResult[1]; 45 | source.headers['CB-Token'] = matchResult[2]; 46 | return source; 47 | } 48 | -------------------------------------------------------------------------------- /RNChat/src/helpers/getTime.js: -------------------------------------------------------------------------------- 1 | export function getTime(dateSent) { 2 | const date = dateSent ? new Date(dateSent * 1000) : new Date(); 3 | const hours = date.getHours(); 4 | const minutes = date.getMinutes(); 5 | return `${(hours > 9) ? hours : ('0' + hours)}:${(minutes > 9) ? minutes : ('0' + minutes)}`; 6 | } 7 | -------------------------------------------------------------------------------- /RNChat/src/helpers/platform.js: -------------------------------------------------------------------------------- 1 | import { Platform } from 'react-native'; 2 | 3 | const platformOS = Platform.OS; 4 | const isIOS = platformOS === 'ios'; 5 | const isAndroid = platformOS === 'android'; 6 | const versionAndroid = Number(isAndroid ? Platform.Version : 0); 7 | 8 | export { 9 | platformOS, 10 | isIOS, 11 | isAndroid, 12 | versionAndroid, 13 | }; 14 | -------------------------------------------------------------------------------- /RNChat/src/hooks/useKeyboardOffset.js: -------------------------------------------------------------------------------- 1 | import { StatusBar } from 'react-native'; 2 | import { useHeaderHeight } from '@react-navigation/elements'; 3 | import { isAndroid } from '../helpers/platform'; 4 | 5 | export default function useKeyboardOffset() { 6 | const headerHeight = useHeaderHeight(); 7 | const statusBarHeight = StatusBar.currentHeight || 0; 8 | 9 | return isAndroid ? headerHeight + statusBarHeight : headerHeight; 10 | } 11 | -------------------------------------------------------------------------------- /RNChat/src/models/dialogs.js: -------------------------------------------------------------------------------- 1 | import { getImageLinkFromUID } from '../helpers/file'; 2 | 3 | export default class Dialog { 4 | constructor(dialog) { 5 | this.id = dialog._id || dialog.id; 6 | this.type = dialog.type; 7 | this.xmpp_room_jid = dialog.xmpp_room_jid; 8 | this.xmpp_type = dialog.type === 3 ? 'chat' : dialog.type ? 'groupchat' : ''; 9 | this.name = dialog.name; 10 | this.photo = Dialog.getAvatarUrl(dialog.photo); 11 | this.description = dialog.description; 12 | this.destination = dialog.xmpp_room_jid || dialog.room_jid; // ????? 13 | this.user_id = dialog.user_id; 14 | this.admins_ids = dialog.admins_ids; 15 | this.occupants_ids = dialog.occupants_ids; 16 | this.updated_date = Date.parse(dialog.updated_at) || Date.now(); 17 | this.last_message_date_sent = dialog.last_message_date_sent || Date.parse(dialog.updated_at) / 1000 || Date.parse(dialog.created_at) / 1000; 18 | this.last_message = dialog.last_message || ''; 19 | this.last_message_id = dialog.last_message_id; 20 | this.last_message_user_id = dialog.last_message_user_id; 21 | this.unread_messages_count = dialog.unread_messages_count; 22 | this.unread_messages_ids = dialog.unread_messages_ids; 23 | this.pinned_messages_ids = dialog.pinned_messages_ids; 24 | } 25 | 26 | static getAvatarUrl(avatarUID) { 27 | return getImageLinkFromUID(avatarUID); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /RNChat/src/models/message.js: -------------------------------------------------------------------------------- 1 | import { getImageLinkFromUID } from '../helpers/file'; 2 | 3 | export const STATUS = { 4 | PENDING: 0, 5 | SENT: 1, 6 | DELIVERED: 2, 7 | READ: 3, 8 | }; 9 | 10 | const defaultMessage = { 11 | id: '', 12 | body: '', 13 | dialog_id: '', 14 | date_sent: Math.floor(Date.now() / 1000), 15 | attachments: null, 16 | sender_id: null, 17 | sender: null, 18 | }; 19 | 20 | export class Message { 21 | constructor(msg = defaultMessage, currentUser) { 22 | this.id = msg.id || msg._id; 23 | this.body = msg.body || msg.message; 24 | this.dialog_id = msg.chat_dialog_id || (msg.extension && msg.extension.dialog_id); 25 | this.date_sent = msg.date_sent || (msg.extension && msg.extension.date_sent) || Math.floor(Date.now() / 1000); 26 | this.send_state = Message.getSendState(msg, currentUser); 27 | this.attachment = Message.getAttachment(msg); 28 | this.sender_id = msg.sender_id || (msg.extension && msg.extension.sender_id); 29 | this.sender = msg.sender_id; 30 | } 31 | 32 | static getAttachment(msg) { 33 | if (msg.attachments && msg.attachments.length > 0) { 34 | const attachments = { ...msg.attachments[0] }; 35 | const parseLink = getImageLinkFromUID(msg.attachments[0].uid); 36 | attachments.url = parseLink; 37 | return [attachments]; 38 | } else if (msg?.extension?.attachments && msg.extension.attachments.length > 0) { 39 | const attachments = { ...msg.extension.attachments[0] }; 40 | const parseLink = getImageLinkFromUID(msg.extension.attachments[0].uid); 41 | attachments.url = parseLink; 42 | return [attachments]; 43 | } else { return null; } 44 | } 45 | 46 | static getSendState(msg, currentUser) { 47 | if (msg?.read_ids?.find(_id => _id !== currentUser)) { 48 | return STATUS.READ; 49 | } 50 | if (msg?.delivered_ids?.find(msg => msg.delivered_ids !== currentUser)) { 51 | return STATUS.DELIVERED; 52 | } 53 | return STATUS.PENDING; 54 | } 55 | 56 | } 57 | 58 | export class FakeMessage { 59 | constructor(msg) { 60 | this.attachment = msg.extension.attachments; 61 | this.body = msg.body; 62 | this.date_sent = msg.extension.date_sent; 63 | this.dialog_id = msg.extension.dialog_id; 64 | this.id = msg.id; 65 | this.send_state = 0; 66 | this.sender = undefined; 67 | this.sender_id = msg.extension.sender_id; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /RNChat/src/models/user.js: -------------------------------------------------------------------------------- 1 | import { getImageLinkFromUID } from '../helpers/file'; 2 | 3 | export default class User { 4 | constructor(user) { 5 | this.id = user.id; 6 | this.avatar = User.getAvatarUrl(user.avatar); 7 | this.login = user.login; 8 | this.custom_data = user.custom_data ? user.custom_data : ''; 9 | this.full_name = user.full_name; 10 | this.phone = user.phone; 11 | this.created_at = user.created_at; 12 | this.updated_at = user.updated_at; 13 | this.last_request_at = user.last_request_at; 14 | } 15 | static getAvatarUrl(avatarUID) { 16 | return getImageLinkFromUID(avatarUID); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /RNChat/src/navigation/AppStack.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import MainStack from './MainStack'; 4 | import AuthStack from './AuthStack'; 5 | 6 | export default function AppStack() { 7 | const currentUser = useSelector((state) => state.currentUser); 8 | 9 | return currentUser ? : ; 10 | } 11 | -------------------------------------------------------------------------------- /RNChat/src/navigation/AuthStack.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createNativeStackNavigator } from '@react-navigation/native-stack'; 3 | import Auth from '../screens/auth'; 4 | 5 | const Stack = createNativeStackNavigator(); 6 | 7 | export default function AuthStack() { 8 | return ( 9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /RNChat/src/navigation/MainStack.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createNativeStackNavigator } from '@react-navigation/native-stack'; 3 | import Dialogs from '../screens/main/dialogs'; 4 | import Settings from '../screens/main/settings/index'; 5 | import Chat from '../screens/main/chat/index'; 6 | import ImageViewer from '../screens/main/chat/imageViewer'; 7 | import Contacts from '../screens/main/contacts/index'; 8 | import CreateDialog from '../screens/main/contacts/createDialog'; 9 | import GroupDetails from '../screens/main/chat/groupDetails'; 10 | import ContactDetails from '../screens/main/chat/contactDetails'; 11 | 12 | const Stack = createNativeStackNavigator(); 13 | 14 | export default function MainStack() { 15 | const commonHeaderOptions = { 16 | headerTitleAlign: 'center', 17 | headerTitleStyle: { 18 | fontSize: 18, 19 | color: 'black', 20 | }, 21 | headerBackTitle: 'Back', 22 | }; 23 | 24 | return ( 25 | 26 | 27 | 28 | 37 | 43 | 49 | 55 | 61 | 67 | 68 | ); 69 | } 70 | -------------------------------------------------------------------------------- /RNChat/src/navigation/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import { NavigationContainer } from '@react-navigation/native'; 4 | import Splash from '../screens/splash'; 5 | import AppStack from './AppStack'; 6 | 7 | export default function () { 8 | const appIsLoading = useSelector((state) => state.appIsLoading); 9 | 10 | return appIsLoading 11 | ? 12 | : ( 13 | 14 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /RNChat/src/redux/reducer-function.js: -------------------------------------------------------------------------------- 1 | const getUpdatedDialogs = (updatedDialog, dialogs) => { 2 | const updatedDialogs = dialogs.map(dialog => 3 | dialog.id === updatedDialog.id 4 | ? Object.assign(dialog, updatedDialog) 5 | : dialog); 6 | 7 | return [...updatedDialogs]; 8 | }; 9 | 10 | const getLazyFetchMessages = ({ dialogId, messages }, history) => { 11 | const mergeMessages = history[dialogId].concat(messages); 12 | return Object.assign({}, history, { [dialogId]: mergeMessages }); 13 | }; 14 | 15 | const getSortedDialogs = ({ message, count }, dialogs) => { 16 | const updatedDialogs = dialogs.map(elem => { 17 | if (elem.id === message.dialog_id) { 18 | const newObj = { 19 | last_message: message.body, 20 | last_message_date_sent: message.date_sent, 21 | updated_date: message.date_sent, 22 | unread_messages_count: count ? elem.unread_messages_count += 1 : elem.unread_messages_count, 23 | }; 24 | return Object.assign(elem, newObj); 25 | } return elem; 26 | }); 27 | 28 | const sort = (items, inverted = false) => items.sort((itemA, itemB) => { 29 | const result = new Date(itemB.last_message_date_sent * 1000) - new Date(itemA.last_message_date_sent * 1000); 30 | return inverted ? !result : result; 31 | }); 32 | 33 | const result = sort(updatedDialogs); 34 | 35 | return [...result]; 36 | }; 37 | 38 | const updateStatusMessages = ({ dialogId, messageId, sendState }, messages) => { 39 | if (Object.keys(messages).length === 0) { 40 | return messages; 41 | } 42 | 43 | let isBreak = true; 44 | const history = messages[dialogId]; 45 | const updatedMessages = history.map(message => { 46 | if (message.id === messageId) { 47 | isBreak = false; 48 | return Object.assign({}, message, { send_state: sendState }); 49 | } else if (isBreak) { 50 | return Object.assign({}, message, { send_state: sendState }); 51 | } 52 | return message; 53 | }); 54 | 55 | return Object.assign({}, messages, { [dialogId]: updatedMessages }); 56 | }; 57 | 58 | const getFetchedUsers = (newUsers, users) => { 59 | const newObjUsers = {}; 60 | newUsers.forEach(user => { 61 | newObjUsers[user.id] = user; 62 | }); 63 | return Object.assign({}, users, newObjUsers); 64 | }; 65 | 66 | export { 67 | getUpdatedDialogs, 68 | getSortedDialogs, 69 | getFetchedUsers, 70 | getLazyFetchMessages, 71 | updateStatusMessages, 72 | }; 73 | -------------------------------------------------------------------------------- /RNChat/src/redux/slices/app.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const appIsLoadingInitialState = true; 4 | const appIsLoadingSlice = createSlice({ 5 | name: 'appIsLoading', 6 | initialState: appIsLoadingInitialState, 7 | reducers: { 8 | setAppIsLoading: (_, action) => action.payload, 9 | resetAppIsLoading: () => appIsLoadingInitialState, 10 | }, 11 | }); 12 | 13 | export const appIsLoading = appIsLoadingSlice.reducer; 14 | export const { setAppIsLoading, resetAppIsLoading } = appIsLoadingSlice.actions; 15 | -------------------------------------------------------------------------------- /RNChat/src/redux/slices/currentUser.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const currentUserInitialState = null; 4 | const currentUserSlice = createSlice({ 5 | name: 'currentUser', 6 | initialState: currentUserInitialState, 7 | reducers: { 8 | setCurrentUser: (_, action) => action.payload, 9 | updateCurrentUser: (currentUser, action) => Object.assign(currentUser, { user: action.payload }), 10 | resetCurrentUser: () => currentUserInitialState, 11 | }, 12 | }); 13 | 14 | export const currentUser = currentUserSlice.reducer; 15 | export const { setCurrentUser, updateCurrentUser, resetCurrentUser } = currentUserSlice.actions; 16 | -------------------------------------------------------------------------------- /RNChat/src/redux/slices/dialogs.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | import { getUpdatedDialogs, getSortedDialogs } from '../reducer-function'; 3 | 4 | const dialogsInitialState = []; 5 | const dialogsSlice = createSlice({ 6 | name: 'dialogs', 7 | initialState: dialogsInitialState, 8 | reducers: { 9 | fetchDialogs: (_dialogs, action) => action.payload, 10 | updateDialog: (dialogs, action) => getUpdatedDialogs(action.payload, dialogs), 11 | addNewDialog: (dialogs, action) => [action.payload, ...dialogs], 12 | sortDialogs: (dialogs, action) => getSortedDialogs(action.payload, dialogs), 13 | deleteDialog: (dialogs, action) => dialogs.filter(dialog => dialog.id !== action.payload), 14 | resetDialogs: () => dialogsInitialState, 15 | }, 16 | }); 17 | 18 | export const dialogs = dialogsSlice.reducer; 19 | export const { fetchDialogs, updateDialog, addNewDialog, sortDialogs, deleteDialog, resetDialogs } = dialogsSlice.actions; 20 | -------------------------------------------------------------------------------- /RNChat/src/redux/slices/messages.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | import { getLazyFetchMessages, updateStatusMessages } from '../reducer-function'; 3 | 4 | const messagesInitialState = {}; 5 | const messagesSlice = createSlice({ 6 | name: 'messages', 7 | initialState: messagesInitialState, 8 | reducers: { 9 | fetchMessages: (history, action) => { 10 | const { messages, dialogId } = action.payload; 11 | return { ...history, [dialogId]: messages }; 12 | }, 13 | lazyFetchMessages: (history, action) => getLazyFetchMessages(action.payload, history), 14 | updateMessages: (history, action) => updateStatusMessages(action.payload, history), 15 | pushMessage: (history, action) => { 16 | const { message, dialogId } = action.payload; 17 | const id = dialogId || message.dialog_id; 18 | const copiedMessages = history[id] || []; 19 | return { ...history, [id]: [message, ...copiedMessages] }; 20 | }, 21 | clearMessages: (history, action) => { 22 | const { dialogId } = action.payload; 23 | delete history[dialogId]; 24 | return { ...history }; 25 | }, 26 | resetMessages: () => messagesInitialState, 27 | }, 28 | }); 29 | 30 | export const messages = messagesSlice.reducer; 31 | export const { fetchMessages, lazyFetchMessages, updateMessages, pushMessage, clearMessages, resetMessages } = messagesSlice.actions; 32 | -------------------------------------------------------------------------------- /RNChat/src/redux/slices/selectedDialog.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const selectedDialogInitialState = ''; 4 | const selectedDialogSlice = createSlice({ 5 | name: 'selectedDialog', 6 | initialState: selectedDialogInitialState, 7 | reducers: { 8 | selectDialog: (_, action) => action.payload, 9 | unselectDialog: () => selectedDialogInitialState, 10 | }, 11 | }); 12 | 13 | export const selectedDialog = selectedDialogSlice.reducer; 14 | export const { selectDialog, unselectDialog } = selectedDialogSlice.actions; 15 | -------------------------------------------------------------------------------- /RNChat/src/redux/slices/users.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | import { getFetchedUsers } from '../reducer-function'; 3 | 4 | const usersInitialState = {}; 5 | const usersSlice = createSlice({ 6 | name: 'users', 7 | initialState: usersInitialState, 8 | reducers: { 9 | fetchUsers: (users, action) => getFetchedUsers(action.payload, users), 10 | resetUsers: () => usersInitialState, 11 | }, 12 | }); 13 | 14 | export const users = usersSlice.reducer; 15 | export const { fetchUsers, resetUsers } = usersSlice.actions; 16 | -------------------------------------------------------------------------------- /RNChat/src/redux/store.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from '@reduxjs/toolkit'; 2 | import { combineReducers } from 'redux'; 3 | import { currentUser, resetCurrentUser } from '../redux/slices/currentUser'; 4 | import { appIsLoading, resetAppIsLoading } from '../redux/slices/app'; 5 | import { dialogs, resetDialogs } from '../redux/slices/dialogs'; 6 | import { messages, resetMessages } from '../redux/slices/messages'; 7 | import { users, resetUsers } from '../redux/slices/users'; 8 | import { selectedDialog, unselectDialog } from '../redux/slices/selectedDialog'; 9 | 10 | const rootReducer = combineReducers({ 11 | currentUser, 12 | appIsLoading, 13 | dialogs, 14 | messages, 15 | users, 16 | selectedDialog, 17 | }); 18 | 19 | const store = configureStore({ 20 | reducer: rootReducer, 21 | middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }), 22 | }); 23 | 24 | export const resetStore = () => { 25 | store.dispatch(resetAppIsLoading()); 26 | store.dispatch(resetDialogs()); 27 | store.dispatch(resetMessages()); 28 | store.dispatch(resetUsers()); 29 | store.dispatch(unselectDialog()); 30 | store.dispatch(resetCurrentUser()); 31 | }; 32 | 33 | export default store; 34 | -------------------------------------------------------------------------------- /RNChat/src/screens/auth/AuthLinks.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Text, TouchableOpacity } from 'react-native'; 3 | import { useSafeAreaInsets } from 'react-native-safe-area-context'; 4 | 5 | export default function AuthLinks({ toggleAuthState, isLogin }) { 6 | const { bottom } = useSafeAreaInsets(); 7 | const authText = isLogin ? "Don't have an account?" : 'Already have an account?'; 8 | const authLink = isLogin ? 'Sign up' : 'Sign in'; 9 | const contentPosition = { justifyContent: isLogin ? 'space-between' : 'flex-end' }; 10 | 11 | return ( 12 | 13 | 14 | {authText} 15 | 16 | {authLink} 17 | 18 | 19 | 20 | ); 21 | } 22 | 23 | const styles = StyleSheet.create({ 24 | container: (bottom = 0) => ({ 25 | alignItems: 'center', 26 | marginTop: 10, 27 | paddingBottom: 20 + bottom, 28 | }), 29 | text: { 30 | fontSize: 16, 31 | color: 'grey', 32 | }, 33 | switchAuthContainer: { 34 | flexDirection: 'row', 35 | justifyContent: 'center', 36 | alignItems: 'center', 37 | }, 38 | switchAuth: { 39 | fontWeight: '700', 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /RNChat/src/screens/auth/AuthLogo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Image } from 'react-native'; 3 | 4 | const AuthLogo = () => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | justifyContent: 'flex-end', 16 | alignItems: 'center', 17 | }, 18 | imageSize: { 19 | width: 200, 20 | height: 150, 21 | }, 22 | }); 23 | 24 | export default AuthLogo; 25 | -------------------------------------------------------------------------------- /RNChat/src/screens/auth/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { StatusBar, StyleSheet, View } from 'react-native'; 3 | import { KeyboardAvoidingView, KeyboardAwareScrollView } from 'react-native-keyboard-controller'; 4 | import { useSafeAreaInsets } from 'react-native-safe-area-context'; 5 | import AuthLogo from './AuthLogo'; 6 | import AuthForm from './AuthForm'; 7 | import AuthLinks from './AuthLinks'; 8 | import { isAndroid } from '../../helpers/platform'; 9 | 10 | export default function Auth() { 11 | const { bottom } = useSafeAreaInsets(); 12 | const kbOffset = isAndroid ? StatusBar.currentHeight : -bottom; 13 | const [isLogin, setIsLogin] = useState(false); 14 | const toggleAuthState = () => { 15 | setIsLogin(!isLogin); 16 | }; 17 | 18 | return ( 19 | 20 | 21 | 22 | 23 | 24 | ); 25 | } 26 | 27 | const styles = StyleSheet.create({ 28 | wrap: { 29 | flex: 1, 30 | backgroundColor: 'white', 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /RNChat/src/screens/components/chatImage.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Image } from 'react-native'; 3 | import { getCbToken } from '../../helpers/file'; 4 | 5 | export default function ChatImage({ photo, width, height }) { 6 | const source = photo.startsWith('https://') ? getCbToken(photo) : { uri: photo }; 7 | 8 | return ; 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /RNChat/src/screens/components/createBtn.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, TouchableOpacity } from 'react-native'; 3 | import { KeyboardStickyView } from 'react-native-keyboard-controller'; 4 | import Icon from 'react-native-vector-icons/MaterialIcons'; 5 | import { BTN_TYPE } from '../../helpers/constants'; 6 | import { useSafeAreaInsets } from 'react-native-safe-area-context'; 7 | 8 | export default function CreateBtn({ goToScreen, type }) { 9 | const { bottom } = useSafeAreaInsets(); 10 | 11 | let renderIcon; 12 | switch (type) { 13 | case BTN_TYPE.DIALOG: { 14 | renderIcon = ; 15 | break; 16 | } 17 | case BTN_TYPE.CONTACTS: { 18 | renderIcon = ; 19 | break; 20 | } 21 | case BTN_TYPE.CREATE_GROUP: { 22 | renderIcon = ; 23 | break; 24 | } 25 | } 26 | 27 | return ( 28 | 29 | 30 | {renderIcon} 31 | 32 | 33 | ); 34 | } 35 | 36 | const styles = StyleSheet.create({ 37 | container: (bottom = 0) => ({ 38 | position: 'absolute', 39 | bottom: 20 + bottom, 40 | right: 20, 41 | }), 42 | createDialog: { 43 | width: 55, 44 | height: 55, 45 | borderRadius: 30, 46 | alignItems: 'center', 47 | justifyContent: 'center', 48 | backgroundColor: '#48A6E3', 49 | }, 50 | }); 51 | -------------------------------------------------------------------------------- /RNChat/src/screens/components/imgPicker.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { StyleSheet, View, TouchableOpacity, Image } from 'react-native'; 3 | import Avatar from './avatar'; 4 | import Icon from 'react-native-vector-icons/MaterialIcons'; 5 | import ImagePicker from 'react-native-image-crop-picker'; 6 | 7 | export default function ImgPicker({ name, photo, onPickPhoto, onCancelPickPhoto, disabled = false }) { 8 | 9 | const [selectedPhoto, setSelectedPhoto] = useState(null); 10 | 11 | const onPickImage = () => { 12 | ImagePicker.openPicker({ 13 | width: 300, 14 | height: 400, 15 | cropping: true, 16 | }).then(image => { 17 | onPickPhoto(image); 18 | setSelectedPhoto(image); 19 | }).catch((_error) => { 20 | onCancelPickPhoto(); 21 | }); 22 | }; 23 | 24 | return ( 25 | 26 | {selectedPhoto ? ( 27 | <> 28 | 32 | 33 | 34 | 35 | 36 | ) : 37 | 38 | 43 | {!disabled && 44 | 45 | 46 | 47 | } 48 | 49 | } 50 | 51 | ); 52 | } 53 | 54 | const styles = StyleSheet.create({ 55 | picker: { 56 | width: 102, 57 | height: 102, 58 | }, 59 | imgPicker: { 60 | width: 100, 61 | height: 100, 62 | borderRadius: 50, 63 | }, 64 | icon: { 65 | position: 'absolute', 66 | bottom: 0, 67 | left: 0, 68 | padding: 5, 69 | backgroundColor: 'white', 70 | width: 32, 71 | height: 32, 72 | borderRadius: 16, 73 | borderWidth: 1, 74 | borderColor: '#48A6E3', 75 | }, 76 | }); 77 | -------------------------------------------------------------------------------- /RNChat/src/screens/components/indicator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, StyleSheet, ActivityIndicator } from 'react-native'; 3 | import { SIZE_SCREEN } from '../../helpers/constants'; 4 | import { useHeaderHeight } from '@react-navigation/elements'; 5 | import { useSafeAreaInsets } from 'react-native-safe-area-context'; 6 | 7 | export default function Indicator({ isActive }) { 8 | const headerHeight = useHeaderHeight(); 9 | const { bottom } = useSafeAreaInsets(); 10 | 11 | return isActive 12 | ? ( 13 | 14 | 15 | 16 | ) : null; 17 | } 18 | 19 | const styles = StyleSheet.create({ 20 | container: (offset = 0) => ({ 21 | position: 'absolute', 22 | alignItems: 'center', 23 | justifyContent: 'center', 24 | width: SIZE_SCREEN.width, 25 | height: SIZE_SCREEN.height - offset, 26 | zIndex: 1000, 27 | }), 28 | }); 29 | -------------------------------------------------------------------------------- /RNChat/src/screens/components/messageStatus.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Icon from 'react-native-vector-icons/MaterialIcons'; 3 | import { STATUS } from '../../models/message'; 4 | 5 | export default function MessageStatus({ send_state }) { 6 | switch (send_state) { 7 | case STATUS.PENDING: 8 | return (); 9 | case STATUS.SENT: 10 | return (); 11 | case STATUS.DELIVERED: 12 | return (); 13 | case STATUS.READ: 14 | return (); 15 | } 16 | 17 | return (null); 18 | } 19 | -------------------------------------------------------------------------------- /RNChat/src/screens/main/chat/imageViewer.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useMemo } from 'react'; 2 | import { Image } from 'react-native'; 3 | import { useNavigation, useRoute } from '@react-navigation/native'; 4 | import { getAspectRatioSize, ResumableZoom } from 'react-native-zoom-toolkit'; 5 | import { SIZE_SCREEN } from '../../../helpers/constants'; 6 | import { GestureHandlerRootView } from 'react-native-gesture-handler'; 7 | 8 | export default function ImageViewer() { 9 | const navigation = useNavigation(); 10 | const route = useRoute(); 11 | const attachment = route.params?.attachment ?? {}; 12 | const headerTitle = useMemo(() => 13 | attachment.name <= 18 14 | ? attachment.name 15 | : `${attachment.name.slice(0, 9)}...${attachment.name.slice(-9)}`, 16 | [attachment.name]); 17 | const source = { uri: attachment.url }; 18 | const imageSize = getAspectRatioSize({ 19 | aspectRatio: +attachment.width / +attachment.height, 20 | width: SIZE_SCREEN.width, 21 | }); 22 | 23 | useEffect(() => { 24 | navigation.setOptions({ headerTitle }); 25 | }, [navigation, headerTitle]); 26 | 27 | const onHandleSwipe = direction => { 28 | if (direction === 'up' || direction === 'down') { 29 | navigation.goBack(); 30 | } 31 | }; 32 | 33 | return ( 34 | 35 | 36 | 37 | 38 | 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /RNChat/src/screens/main/contacts/participant.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, TouchableOpacity, Text } from 'react-native'; 3 | import Avatar from '../../components/avatar'; 4 | import Icon from 'react-native-vector-icons/MaterialIcons'; 5 | 6 | export default function Participant({ isSelected, onSelectUser, user, isGroupDialog }) { 7 | const toggleUserSelect = () => { 8 | onSelectUser(user); 9 | }; 10 | 11 | return ( 12 | 13 | 14 | 15 | 20 | {user.full_name} 21 | 22 | <> 23 | {isGroupDialog ? 24 | isSelected ? ( 25 | 26 | ) : ( 27 | 28 | ) : 29 | } 30 | 31 | 32 | 33 | ); 34 | } 35 | 36 | const styles = StyleSheet.create({ 37 | container: { 38 | flex: 1, 39 | flexDirection: 'row', 40 | justifyContent: 'space-between', 41 | alignItems: 'center', 42 | paddingHorizontal: 10, 43 | borderBottomWidth: 0.5, 44 | borderBottomColor: 'lightgrey', 45 | }, 46 | userContainer: { 47 | flex: 1, 48 | flexDirection: 'row', 49 | justifyContent: 'flex-start', 50 | alignItems: 'center', 51 | }, 52 | nameTitle: { 53 | fontSize: 18, 54 | fontWeight: '700', 55 | color: 'grey', 56 | }, 57 | select: { 58 | color: 'green', 59 | fontSize: 10, 60 | fontWeight: '500', 61 | }, 62 | }); 63 | -------------------------------------------------------------------------------- /RNChat/src/screens/main/dialogs/elements/dialog.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, TouchableOpacity } from 'react-native'; 3 | import Avatar from '../../../components/avatar'; 4 | import DialogTitle from './dialogTitle'; 5 | import DialogLastDate from './dialogLastDate'; 6 | import DialogUnreadCounter from './dialogUnreadCounter'; 7 | import { UsersService } from '../../../../services'; 8 | import { DIALOG_TYPE } from '../../../../helpers/constants'; 9 | 10 | export default function Dialog({ dialog, onDialogClick }) { 11 | 12 | const onPress = async () => { 13 | onDialogClick(dialog); 14 | }; 15 | 16 | const dialogPhoto = dialog.type === DIALOG_TYPE.PRIVATE 17 | ? UsersService.getUsersAvatar(dialog.occupants_ids) 18 | : dialog.photo; 19 | 20 | return ( 21 | 22 | 23 | 28 | 29 | 33 | 34 | 39 | 42 | 43 | 44 | 45 | 46 | ); 47 | } 48 | 49 | const styles = StyleSheet.create({ 50 | container: { 51 | flex: 1, 52 | flexDirection: 'row', 53 | justifyContent: 'flex-start', 54 | alignItems: 'flex-start', 55 | paddingHorizontal: 10, 56 | }, 57 | border: { 58 | flex: 1, 59 | flexDirection: 'row', 60 | justifyContent: 'space-between', 61 | borderBottomWidth: 0.5, 62 | borderBottomColor: 'lightgrey', 63 | }, 64 | infoContainer: { 65 | maxWidth: 75, 66 | height: 50, 67 | justifyContent: 'flex-start', 68 | alignItems: 'flex-end', 69 | paddingVertical: 10, 70 | marginLeft: 5, 71 | }, 72 | }); 73 | -------------------------------------------------------------------------------- /RNChat/src/screens/main/dialogs/elements/dialogLastDate.js: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react'; 2 | import { Text, StyleSheet } from 'react-native'; 3 | 4 | export default function DialogLastDate({ lastDate, lastMessage, updatedDate }) { 5 | const timeValue = useMemo(() => { 6 | const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; 7 | const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; 8 | const msgLastDate = lastMessage ? new Date(lastDate * 1000) : new Date(updatedDate); 9 | const msgYear = msgLastDate.getFullYear(); 10 | const msgMonth = msgLastDate.getMonth(); 11 | const msgDate = msgLastDate.getDate(); 12 | const msgDay = msgLastDate.getDay(); 13 | const msgHours = msgLastDate.getHours(); 14 | const msgMinutes = msgLastDate.getMinutes(); 15 | const LastDate = new Date(); 16 | const curYear = LastDate.getFullYear(); 17 | const curMonth = LastDate.getMonth(); 18 | const curDate = LastDate.getDate(); 19 | const curDay = LastDate.getDay(); 20 | 21 | if (curYear > msgYear) { 22 | return `${months[msgMonth]} ${msgDate}, ${msgYear}`; 23 | } else if (curMonth > msgMonth) { 24 | return `${months[msgMonth]} ${msgDate}`; 25 | } else if (curDate > (msgDate + 6)) { 26 | return `${months[msgMonth]} ${msgDate}`; 27 | } else if (curDay > msgDay) { 28 | return `${days[msgDay]}`; 29 | } else { 30 | return `${(msgHours > 9) ? msgHours : ('0' + msgHours)}:${(msgMinutes > 9) ? msgMinutes : ('0' + msgMinutes)}`; 31 | } 32 | }, [lastDate, lastMessage, updatedDate]); 33 | 34 | return {timeValue}; 35 | } 36 | 37 | const styles = StyleSheet.create({ 38 | time: { 39 | color: 'grey', 40 | lineHeight: 25, 41 | fontSize: 12, 42 | fontWeight: '500', 43 | }, 44 | }); 45 | -------------------------------------------------------------------------------- /RNChat/src/screens/main/dialogs/elements/dialogTitle.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, StyleSheet } from 'react-native'; 3 | 4 | export default function DialogTitles({ name, message }) { 5 | return ( 6 | 7 | {name} 8 | {message} 9 | 10 | ); 11 | } 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | flex: 1, 16 | justifyContent: 'flex-start', 17 | alignItems: 'flex-start', 18 | paddingVertical: 10, 19 | }, 20 | name: { 21 | height: 30, 22 | lineHeight: 30, 23 | color: 'grey', 24 | fontSize: 18, 25 | fontWeight: '700', 26 | }, 27 | message: { 28 | height: 15, 29 | lineHeight: 15, 30 | color: 'grey', 31 | fontSize: 15, 32 | fontWeight: '400', 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /RNChat/src/screens/main/dialogs/elements/dialogUnreadCounter.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, StyleSheet } from 'react-native'; 3 | 4 | export default function DialogUnreadCounter({ unreadMessagesCount }) { 5 | return ( 6 | unreadMessagesCount > 0 && 7 | 8 | {unreadMessagesCount < 100 ? unreadMessagesCount : 99} 9 | 10 | ); 11 | } 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | width: 25, 16 | height: 25, 17 | lineHeight: 25, 18 | borderRadius: 25, 19 | justifyContent: 'center', 20 | alignItems: 'center', 21 | backgroundColor: 'forestgreen', 22 | }, 23 | counter: { 24 | color: 'white', 25 | fontSize: 14, 26 | fontWeight: '700', 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /RNChat/src/screens/splash.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { StyleSheet, View, ActivityIndicator } from 'react-native'; 3 | import { AuthService } from '../services'; 4 | 5 | export default function Splash() { 6 | const initSDK = async () => { 7 | await AuthService.init(); 8 | }; 9 | 10 | useEffect(() => { 11 | initSDK(); 12 | }, []); 13 | 14 | return ( 15 | 16 | 17 | 18 | ); 19 | } 20 | 21 | const styles = StyleSheet.create({ 22 | container: { 23 | flex: 1, 24 | justifyContent: 'center', 25 | alignItems: 'center', 26 | backgroundColor: 'white', 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /RNChat/src/services/index.js: -------------------------------------------------------------------------------- 1 | export { default as UsersService } from './users-service'; 2 | export { default as ChatService } from './chat-service'; 3 | export { default as AuthService } from './auth-service'; 4 | export { default as PushNotificationService } from './push-notification'; 5 | -------------------------------------------------------------------------------- /RNChat/src/services/users-service.js: -------------------------------------------------------------------------------- 1 | import ConnectyCube from 'react-native-connectycube'; 2 | import UserModel from '../models/user'; 3 | import store from '../redux/store'; 4 | import {fetchUsers} from '../redux/slices/users'; 5 | 6 | class UsersService { 7 | constructor() { 8 | if (UsersService.instance) { 9 | return UsersService.instance; 10 | } 11 | 12 | UsersService.instance = this; 13 | } 14 | 15 | async getOccupants(ids) { 16 | const users = this.getUsers; 17 | let idsForFetch = []; 18 | 19 | ids.forEach(elem => { 20 | if (elem !== this.currentUser?.id && !users[elem]) { 21 | idsForFetch.push(elem); 22 | } 23 | }); 24 | 25 | if (idsForFetch.length === 0) { 26 | return; 27 | } 28 | 29 | const usersFromServer = await ConnectyCube.users.getV2({ 30 | id: {in: idsForFetch}, 31 | }); 32 | const newUsers = usersFromServer.items.map(elem => { 33 | return new UserModel(elem.user); 34 | }); 35 | store.dispatch(fetchUsers(newUsers)); 36 | } 37 | 38 | getUsersAvatar(ids) { 39 | let userId = null; 40 | ids.forEach(elem => { 41 | if (elem != this.currentUser?.id) { 42 | userId = elem; 43 | } 44 | }); 45 | return store.getState().users[userId].avatar; 46 | } 47 | 48 | async listUsersByFullName(name, usersIdsToIgnore = []) { 49 | console.log('usersIdsToIgnore', usersIdsToIgnore); 50 | if (!usersIdsToIgnore || usersIdsToIgnore.length === 0) { 51 | usersIdsToIgnore = [this.currentUser?.id]; 52 | } 53 | console.log('usersIdsToIgnore2', usersIdsToIgnore); 54 | const allUsers = await ConnectyCube.users.getV2({ 55 | full_name: {start_with: name}, 56 | }); 57 | let contacts = []; 58 | allUsers.items.forEach(user => { 59 | if (!usersIdsToIgnore.includes(user.id)) { 60 | contacts.push(new UserModel(user)); 61 | } 62 | }); 63 | return contacts; 64 | } 65 | 66 | getUsersInfoFromRedux(ids) { 67 | const users = this.getUsers; 68 | const usersInfo = []; 69 | ids.forEach(id => { 70 | if (id !== this.currentUser?.id) { 71 | users[id] && usersInfo.push(users[id]); 72 | } 73 | }); 74 | return usersInfo; 75 | } 76 | 77 | get currentUser() { 78 | return store.getState().currentUser?.user; 79 | } 80 | 81 | get getUsers() { 82 | return store.getState().users; 83 | } 84 | } 85 | 86 | export default new UsersService(); 87 | -------------------------------------------------------------------------------- /RNChat/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /RNVideoChat/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /RNVideoChat/.config-files: -------------------------------------------------------------------------------- 1 | src/config.js -------------------------------------------------------------------------------- /RNVideoChat/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /RNVideoChat/.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 | -------------------------------------------------------------------------------- /RNVideoChat/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /RNVideoChat/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /RNVideoChat/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-3.6.4.cjs 4 | -------------------------------------------------------------------------------- /RNVideoChat/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {NavigationContainer} from '@react-navigation/native'; 3 | import {createNativeStackNavigator} from '@react-navigation/native-stack'; 4 | import {Provider, useSelector} from 'react-redux'; 5 | import store from './src/redux/store'; 6 | import LoginScreen from './src/components/screens/login-screen'; 7 | import VideoScreen from './src/components/screens/video-screen'; 8 | import InitiateCallScreen from './src/components/screens/initiate-call-screen'; 9 | import IncomingCallScreen from './src/components/screens/incoming-call-screen'; 10 | 11 | const Stack = createNativeStackNavigator(); 12 | 13 | function AppNavigator() { 14 | const currentUser = useSelector(state => state.currentUser); 15 | 16 | return currentUser ? ( 17 | 18 | <>, 24 | headerStyle: { 25 | backgroundColor: 'black', 26 | }, 27 | headerTitleAlign: 'center', 28 | headerTintColor: 'white', 29 | gestureEnabled: false, 30 | }} 31 | /> 32 | 37 | 42 | 43 | ) : ( 44 | 45 | 50 | 51 | ); 52 | } 53 | 54 | export default function App() { 55 | return ( 56 | 57 | 58 | 59 | 60 | 61 | ); 62 | } 63 | -------------------------------------------------------------------------------- /RNVideoChat/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 | # Exclude problematic versions of cocoapods and activesupport that causes build failures. 7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' 8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' 9 | -------------------------------------------------------------------------------- /RNVideoChat/__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 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/debug.keystore -------------------------------------------------------------------------------- /RNVideoChat/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 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/java/com/rnvideochat/CallNotificationHeadlessJsTask.kt: -------------------------------------------------------------------------------- 1 | package com.rnvideochat; 2 | 3 | import android.content.Intent 4 | import android.util.Log 5 | import com.facebook.react.HeadlessJsTaskService 6 | import com.facebook.react.bridge.Arguments 7 | import com.facebook.react.bridge.ReactApplicationContext 8 | import com.facebook.react.jstasks.HeadlessJsTaskConfig 9 | import com.facebook.react.jstasks.HeadlessJsTaskRetryPolicy 10 | import com.facebook.react.jstasks.LinearCountingRetryPolicy 11 | 12 | class CallNotificationHeadlessJsTask : HeadlessJsTaskService() { 13 | 14 | private val LOGTAG = "CallNotificationBroadcastReceiver" 15 | 16 | override fun getTaskConfig(intent: Intent): HeadlessJsTaskConfig? { 17 | return intent.extras?.let { 18 | HeadlessJsTaskConfig( 19 | "CallNotificationHeadlessJsTask", 20 | Arguments.fromBundle(it), 21 | 5000, // timeout for the task 22 | false, // optional: defines whether or not the task is allowed in foreground. 23 | ) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/java/com/rnvideochat/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.rnvideochat 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 = "RNVideoChat" 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 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/java/com/rnvideochat/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.rnvideochat 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 | import com.oney.WebRTCModule.WebRTCModuleOptions 15 | import com.wix.reactnativenotifications.RNNotificationsPackage 16 | 17 | class MainApplication : Application(), ReactApplication { 18 | 19 | override val reactNativeHost: ReactNativeHost = 20 | object : DefaultReactNativeHost(this) { 21 | override fun getPackages(): List = 22 | PackageList(this).packages.apply { 23 | // Packages that cannot be autolinked yet can be added manually here, for example: 24 | // add(MyModulePackage()) 25 | } 26 | 27 | override fun getJSMainModuleName(): String = "index" 28 | 29 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 30 | 31 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 32 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 33 | } 34 | 35 | override val reactHost: ReactHost 36 | get() = getDefaultReactHost(applicationContext, reactNativeHost) 37 | 38 | override fun onCreate() { 39 | super.onCreate() 40 | SoLoader.init(this, false) 41 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 42 | // If you opted-in for the New Architecture, we load the native entry point for this app. 43 | load() 44 | } 45 | // Initialize the WebRTC module options. 46 | WebRTCModuleOptions.getInstance().enableMediaProjectionService = true 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable-hdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/drawable-hdpi/ic_notification.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable-mdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/drawable-mdpi/ic_notification.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable-xhdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/drawable-xhdpi/ic_notification.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable-xxhdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/drawable-xxhdpi/ic_notification.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/drawable/ic_check.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/drawable/ic_close.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/drawable/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/raw/calling.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/app/src/main/res/raw/calling.mp3 -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #00D2D3 4 | #ffffff 5 | #000000 6 | #00000000 7 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RNVideoChat 3 | 4 | -------------------------------------------------------------------------------- /RNVideoChat/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /RNVideoChat/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 23 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "26.1.10909125" 8 | kotlinVersion = "1.9.24" 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 | classpath("com.google.gms:google-services:4.4.2") 19 | } 20 | } 21 | 22 | apply plugin: "com.facebook.react.rootproject" 23 | -------------------------------------------------------------------------------- /RNVideoChat/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 | 25 | # Use this property to specify which architecture you want to build. 26 | # You can also override it from the CLI using 27 | # ./gradlew -PreactNativeArchitectures=x86_64 28 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 29 | 30 | # Use this property to enable support to the new architecture. 31 | # This will allow you to use TurboModules and the Fabric render in 32 | # your application. You should enable this flag either if you want 33 | # to write custom TurboModules/Fabric components OR use libraries that 34 | # are providing them. 35 | newArchEnabled=false 36 | 37 | # Use this property to enable or disable the Hermes JS engine. 38 | # If set to false, you will be using JSC instead. 39 | hermesEnabled=true 40 | -------------------------------------------------------------------------------- /RNVideoChat/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /RNVideoChat/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /RNVideoChat/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } 2 | plugins { id("com.facebook.react.settings") } 3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } 4 | rootProject.name = 'RNVideoChat' 5 | include ':react-native-notifications' 6 | project(':react-native-notifications').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-notifications/lib/android/app') 7 | include ':app' 8 | includeBuild('../node_modules/@react-native/gradle-plugin') 9 | -------------------------------------------------------------------------------- /RNVideoChat/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RNVideoChat", 3 | "displayName": "RNVideoChat" 4 | } 5 | -------------------------------------------------------------------------------- /RNVideoChat/assets/image/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/assets/image/icon.png -------------------------------------------------------------------------------- /RNVideoChat/assets/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/assets/image/logo.png -------------------------------------------------------------------------------- /RNVideoChat/assets/image/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/assets/image/splash.png -------------------------------------------------------------------------------- /RNVideoChat/assets/sounds/calling.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/assets/sounds/calling.mp3 -------------------------------------------------------------------------------- /RNVideoChat/assets/sounds/dialing.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/assets/sounds/dialing.mp3 -------------------------------------------------------------------------------- /RNVideoChat/assets/sounds/end_call.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/assets/sounds/end_call.mp3 -------------------------------------------------------------------------------- /RNVideoChat/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /RNVideoChat/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import { AppRegistry, LogBox } from 'react-native'; 6 | import ConnectyCube from 'react-native-connectycube'; 7 | import { name as appName } from './app.json'; 8 | import { appCredentials, appConfig } from './src/config'; 9 | import { CallKeepService, CallService, PushNotificationsService } from './src/services'; 10 | import App from './App'; 11 | 12 | LogBox.ignoreLogs(['']); 13 | 14 | ConnectyCube.init(appCredentials, appConfig); 15 | PushNotificationsService.registerEvents(); 16 | CallService.registerEvents(); 17 | CallKeepService.setup(); 18 | AppRegistry.registerComponent(appName, () => App); 19 | -------------------------------------------------------------------------------- /RNVideoChat/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 | -------------------------------------------------------------------------------- /RNVideoChat/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 'RNVideoChat' do 18 | config = use_native_modules! 19 | 20 | use_react_native!( 21 | :path => config[:reactNativePath], 22 | # An absolute path to your application root. 23 | :app_path => "#{Pod::Config.instance.installation_root}/.." 24 | ) 25 | 26 | target 'RNVideoChatTests' do 27 | inherit! :complete 28 | # Pods for testing 29 | end 30 | 31 | post_install do |installer| 32 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 33 | react_native_post_install( 34 | installer, 35 | config[:reactNativePath], 36 | :mac_catalyst_enabled => false, 37 | # :ccache_enabled => true 38 | ) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/120 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/120 1.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "40.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "60.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "58.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "87.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "80.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "120.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "120 1.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "180.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "1024.png", 53 | "idiom" : "ios-marketing", 54 | "scale" : "1x", 55 | "size" : "1024x1024" 56 | } 57 | ], 58 | "info" : { 59 | "author" : "xcode", 60 | "version" : 1 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RNVideoChat 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 | NSAllowsArbitraryLoads 30 | 31 | NSAllowsLocalNetworking 32 | 33 | 34 | NSCameraUsageDescription 35 | Camera permission 36 | NSLocationWhenInUseUsageDescription 37 | 38 | NSMicrophoneUsageDescription 39 | Microphone permission 40 | UIAppFonts 41 | 42 | MaterialIcons.ttf 43 | 44 | UIBackgroundModes 45 | 46 | voip 47 | remote-notification 48 | 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | arm64 55 | 56 | UIStatusBarStyle 57 | 58 | UISupportedInterfaceOrientations 59 | 60 | UIInterfaceOrientationPortrait 61 | 62 | UISupportedInterfaceOrientations~ipad 63 | 64 | UIInterfaceOrientationLandscapeLeft 65 | UIInterfaceOrientationLandscapeRight 66 | UIInterfaceOrientationPortrait 67 | 68 | UIViewControllerBasedStatusBarAppearance 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryFileTimestamp 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | C617.1 13 | 14 | 15 | 16 | NSPrivacyAccessedAPIType 17 | NSPrivacyAccessedAPICategorySystemBootTime 18 | NSPrivacyAccessedAPITypeReasons 19 | 20 | 35F9.1 21 | 22 | 23 | 24 | NSPrivacyAccessedAPIType 25 | NSPrivacyAccessedAPICategoryUserDefaults 26 | NSPrivacyAccessedAPITypeReasons 27 | 28 | CA92.1 29 | 30 | 31 | 32 | NSPrivacyAccessedAPIType 33 | NSPrivacyAccessedAPICategoryDiskSpace 34 | NSPrivacyAccessedAPITypeReasons 35 | 36 | 85F4.1 37 | 38 | 39 | 40 | NSPrivacyCollectedDataTypes 41 | 42 | NSPrivacyTracking 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChat/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 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChatTests/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 | -------------------------------------------------------------------------------- /RNVideoChat/ios/RNVideoChatTests/RNVideoChatTests.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 RNVideoChatTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation RNVideoChatTests 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 | -------------------------------------------------------------------------------- /RNVideoChat/ios/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChat/ios/icon.png -------------------------------------------------------------------------------- /RNVideoChat/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /RNVideoChat/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 | -------------------------------------------------------------------------------- /RNVideoChat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RNVideoChat", 3 | "version": "2.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "react-native start", 7 | "restart": "yarn start --reset-cache", 8 | "android": "react-native run-android", 9 | "ios": "react-native run-ios", 10 | "xcode": "xed -b ios", 11 | "clean:ios": "rm -f ios/Podfile.lock && rm -rf ios/Pods && rm -rf ios/build", 12 | "clean:android": "rm -rf android/app/build && rm -rf android/.gradle", 13 | "clean:gradle": "cd android && ./gradlew --stop && ./gradlew clean && ./gradlew cleanBuild && cd ..", 14 | "clean:yarn": "rm -rf node_modules/ && rm -f yarn.lock", 15 | "lint": "eslint .", 16 | "test": "jest" 17 | }, 18 | "dependencies": { 19 | "@notifee/react-native": "^9.1.1", 20 | "@react-native-async-storage/async-storage": "^2.0.0", 21 | "@react-navigation/elements": "^1.3.31", 22 | "@react-navigation/native": "^6.1.18", 23 | "@react-navigation/native-stack": "^6.11.0", 24 | "@reduxjs/toolkit": "^2.2.8", 25 | "react": "18.3.1", 26 | "react-native": "0.75.4", 27 | "react-native-callkeep": "^4.3.14", 28 | "react-native-connectycube": "^4.0.0", 29 | "react-native-device-info": "^13.0.0", 30 | "react-native-incall-manager": "^4.2.0", 31 | "react-native-notifications": "^5.1.0", 32 | "react-native-safe-area-context": "^4.11.0", 33 | "react-native-screens": "^3.34.0", 34 | "react-native-simple-toast": "^3.3.1", 35 | "react-native-sound": "^0.11.2", 36 | "react-native-vector-icons": "^10.2.0", 37 | "react-native-webrtc": "^124.0.4", 38 | "react-redux": "^9.1.2", 39 | "redux": "^5.0.1" 40 | }, 41 | "devDependencies": { 42 | "@babel/core": "^7.20.0", 43 | "@babel/preset-env": "^7.20.0", 44 | "@babel/runtime": "^7.20.0", 45 | "@react-native/babel-preset": "0.75.4", 46 | "@react-native/eslint-config": "0.75.4", 47 | "@react-native/metro-config": "0.75.4", 48 | "@react-native/typescript-config": "0.75.4", 49 | "@types/react": "^18.2.6", 50 | "@types/react-test-renderer": "^18.0.0", 51 | "babel-jest": "^29.6.3", 52 | "eslint": "^8.19.0", 53 | "jest": "^29.6.3", 54 | "prettier": "2.8.8", 55 | "react-test-renderer": "18.3.1", 56 | "typescript": "5.0.4" 57 | }, 58 | "engines": { 59 | "node": ">=18" 60 | }, 61 | "packageManager": "yarn@3.6.4" 62 | } 63 | -------------------------------------------------------------------------------- /RNVideoChat/src/components/generic/loader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ActivityIndicator, View, Text, StyleSheet } from 'react-native'; 3 | 4 | export default ({ text }) => ( 5 | 6 | 7 | {text} 8 | 9 | 10 | 11 | ); 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | ...StyleSheet.absoluteFill, 16 | flex: 1, 17 | justifyContent: 'center', 18 | }, 19 | info: { 20 | flexDirection: 'row', 21 | justifyContent: 'center', 22 | }, 23 | text: { 24 | fontSize: 16, 25 | color: 'white', 26 | marginRight: 16, 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /RNVideoChat/src/components/generic/logout-button.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { TouchableOpacity, Text, StyleSheet } from 'react-native'; 3 | 4 | export default ({ onPress }) => ( 5 | 6 | Logout 7 | 8 | ); 9 | 10 | const styles = StyleSheet.create({ 11 | text: { 12 | fontSize: 16, 13 | color: 'white', 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /RNVideoChat/src/components/generic/video-grid.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, StyleSheet } from 'react-native'; 3 | import { RTCView } from 'react-native-webrtc'; 4 | 5 | import Loader from './loader'; 6 | import { getUserById } from '../../utils'; 7 | 8 | const RTCViewRendered = ({ userId, stream }) => { 9 | return stream ? ( 10 | 17 | ) : ( 18 | 19 | 20 | 21 | ); 22 | }; 23 | 24 | export default ({ streams }) => { 25 | let RTCListView = null; 26 | 27 | switch (streams.length) { 28 | case 1: 29 | RTCListView = ( 30 | 31 | ); 32 | break; 33 | 34 | case 2: 35 | RTCListView = ( 36 | 37 | 38 | 39 | 40 | ); 41 | break; 42 | 43 | case 3: 44 | RTCListView = ( 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ); 53 | break; 54 | 55 | case 4: 56 | RTCListView = ( 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | ); 68 | break; 69 | 70 | default: 71 | break; 72 | } 73 | 74 | return {RTCListView}; 75 | }; 76 | 77 | const styles = StyleSheet.create({ 78 | blackView: { 79 | flex: 1, 80 | backgroundColor: 'black', 81 | }, 82 | inColumn: { 83 | flex: 1, 84 | flexDirection: 'column', 85 | }, 86 | inRow: { 87 | flex: 1, 88 | flexDirection: 'row', 89 | }, 90 | }); 91 | -------------------------------------------------------------------------------- /RNVideoChat/src/components/screens/video-screen.js: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useEffect } from 'react'; 2 | import { SafeAreaView } from 'react-native-safe-area-context'; 3 | import { useNavigation } from '@react-navigation/native'; 4 | import { useSelector } from 'react-redux'; 5 | import ConnectyCube from 'react-native-connectycube'; 6 | import VideoGrid from '../generic/video-grid'; 7 | import { CallService } from '../../services'; 8 | import VideoToolBar from '../generic/video-toolbar'; 9 | import Loader from '../generic/loader'; 10 | import { showToast } from '../../utils'; 11 | import { StyleSheet } from 'react-native'; 12 | 13 | export default function VideoScreen() { 14 | const navigation = useNavigation(); 15 | const streams = useSelector(state => state.activeCall.streams); 16 | const callSession = useSelector(state => state.activeCall.session); 17 | const isEarlyAccepted = useSelector(state => state.activeCall.isEarlyAccepted); 18 | const isVideoCall = callSession?.callType === ConnectyCube.videochat.CallType.VIDEO; 19 | 20 | useEffect(() => { 21 | if (streams.length <= 1) { 22 | stopCall(); // stop call if all opponents are left 23 | } 24 | 25 | return () => { 26 | showToast('Call is ended'); 27 | }; 28 | }, [streams, stopCall]); 29 | 30 | const stopCall = useCallback(() => { 31 | CallService.stopCall(); 32 | navigation.goBack(); 33 | }, [navigation]); 34 | 35 | const muteCall = (isAudioMuted) => { 36 | CallService.muteMicrophone(isAudioMuted); 37 | }; 38 | 39 | const switchCamera = () => { 40 | CallService.switchCamera(); 41 | }; 42 | 43 | return ( 44 | 45 | 46 | {isEarlyAccepted && } 47 | 1} 53 | /> 54 | 55 | ); 56 | } 57 | 58 | const styles = StyleSheet.create({ 59 | container: { 60 | flex: 1, 61 | backgroundColor: 'black', 62 | }, 63 | }); 64 | -------------------------------------------------------------------------------- /RNVideoChat/src/config.js: -------------------------------------------------------------------------------- 1 | export const appCredentials = { 2 | appId: REPLACE_APP_ID, 3 | authKey: 'REPLACE_APP_AUTH_KEY', 4 | }; 5 | 6 | export const appConfig = { 7 | debug: { 8 | mode: 1, 9 | }, 10 | }; 11 | 12 | export const users = [ 13 | { 14 | id: REPLACE_USER_1_ID, 15 | full_name: 'REPLACE_USER_1_FULL_NAME', 16 | login: 'REPLACE_USER_1_LOGIN', 17 | password: 'REPLACE_USER_1_PASSWORD', 18 | color: '#34ad86', 19 | }, 20 | { 21 | id: REPLACE_USER_2_ID, 22 | full_name: 'REPLACE_USER_2_FULL_NAME', 23 | login: 'REPLACE_USER_2_LOGIN', 24 | password: 'REPLACE_USER_2_PASSWORD', 25 | color: '#077988', 26 | }, 27 | { 28 | id: REPLACE_USER_3_ID, 29 | full_name: 'REPLACE_USER_3_FULL_NAME', 30 | login: 'REPLACE_USER_3_LOGIN', 31 | password: 'REPLACE_USER_3_PASSWORD', 32 | color: '#13aaae', 33 | }, 34 | { 35 | id: REPLACE_USER_4_ID, 36 | full_name: 'REPLACE_USER_4_FULL_NAME', 37 | login: 'REPLACE_USER_4_LOGIN', 38 | password: 'REPLACE_USER_4_PASSWORD', 39 | color: '#056a96', 40 | }, 41 | ]; 42 | 43 | -------------------------------------------------------------------------------- /RNVideoChat/src/redux/slices/activeCall.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const activeCallInitialState = { 4 | session: null, 5 | isIncoming: false, 6 | isAccepted: false, 7 | isEarlyAccepted: false, // used when accepted via Call Kit, but the call session is not arrived yet 8 | isDummySession: false, // used when got incoming call on Android in bg/killed 9 | isMicrophoneMuted: false, 10 | streams: [], 11 | }; 12 | 13 | const activeCallSlice = createSlice({ 14 | name: 'activeCall', 15 | initialState: activeCallInitialState, 16 | reducers: { 17 | setCallSession: (state, { payload }) => Object.assign({}, state, { 18 | session: payload.session, 19 | isIncoming: payload.isIncoming ?? false, 20 | isDummySession: false, 21 | }), 22 | setDummyCallSession: (state, { payload }) => Object.assign({}, state, { 23 | session: payload, 24 | isIncoming: true, 25 | isDummySession: true, 26 | }), 27 | acceptCall: (state) => Object.assign({}, state, { 28 | isAccepted: true, 29 | isEarlyAccepted: false, 30 | isIncoming: true, 31 | }), 32 | earlyAcceptCall: (state) => Object.assign({}, state, { 33 | isAccepted: false, 34 | isEarlyAccepted: true, 35 | isIncoming: true, 36 | }), 37 | muteMicrophone: (state, { payload }) => Object.assign({}, state, { 38 | isMicrophoneMuted: payload, 39 | }), 40 | upsertStreams: (state, { payload }) => { 41 | let streams = [...state.streams]; 42 | for (let stream of payload) { 43 | streams = streams.find(s => s.userId === stream.userId) 44 | ? streams.map(s => s.userId !== stream.userId ? s : stream) // replace 45 | : [...streams, stream]; // add 46 | } 47 | return Object.assign({}, state, { streams }); 48 | }, 49 | removeStream: (state, { payload }) => Object.assign({}, state, { 50 | streams: state.streams.filter(s => s.userId !== payload.userId), 51 | }), 52 | resetActiveCall: () => activeCallInitialState, 53 | }, 54 | }); 55 | 56 | export const activeCall = activeCallSlice.reducer; 57 | export const { 58 | setCallSession, 59 | setDummyCallSession, 60 | acceptCall, 61 | earlyAcceptCall, 62 | muteMicrophone, 63 | upsertStreams, 64 | removeStream, 65 | resetActiveCall, 66 | } = activeCallSlice.actions; 67 | -------------------------------------------------------------------------------- /RNVideoChat/src/redux/slices/currentUser.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const currentUserInitialState = null; 4 | 5 | const currentUserSlice = createSlice({ 6 | name: 'currentUser', 7 | initialState: currentUserInitialState, 8 | reducers: { 9 | setCurrentUser: (_, action) => action.payload, 10 | resetCurrentUser: () => currentUserInitialState, 11 | }, 12 | }); 13 | 14 | export const currentUser = currentUserSlice.reducer; 15 | export const { setCurrentUser, resetCurrentUser } = currentUserSlice.actions; 16 | -------------------------------------------------------------------------------- /RNVideoChat/src/redux/slices/isLogging.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const isLoggingInitialState = false; 4 | 5 | const isLoggingSlice = createSlice({ 6 | name: 'isLogging', 7 | initialState: isLoggingInitialState, 8 | reducers: { 9 | setIsLogging: (_, action) => action.payload, 10 | resetIsLogging: () => isLoggingInitialState, 11 | }, 12 | }); 13 | 14 | export const isLogging = isLoggingSlice.reducer; 15 | export const { setIsLogging, resetIsLogging } = isLoggingSlice.actions; 16 | -------------------------------------------------------------------------------- /RNVideoChat/src/redux/store.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from '@reduxjs/toolkit'; 2 | import { combineReducers } from 'redux'; 3 | import { activeCall, resetActiveCall } from './slices/activeCall'; 4 | import { currentUser, resetCurrentUser } from './slices/currentUser'; 5 | import { isLogging, resetIsLogging } from './slices/isLogging'; 6 | 7 | const rootReducer = combineReducers({ 8 | activeCall, 9 | currentUser, 10 | isLogging, 11 | }); 12 | 13 | const store = configureStore({ 14 | reducer: rootReducer, 15 | middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }), 16 | }); 17 | 18 | export const resetStore = () => { 19 | store.dispatch(resetActiveCall()); 20 | store.dispatch(resetCurrentUser()); 21 | store.dispatch(resetIsLogging()); 22 | }; 23 | 24 | export default store; 25 | -------------------------------------------------------------------------------- /RNVideoChat/src/services/auth-service.js: -------------------------------------------------------------------------------- 1 | import ConnectyCube from 'react-native-connectycube'; 2 | import AsyncStorage from '@react-native-async-storage/async-storage'; 3 | import store, { resetStore } from '../redux/store'; 4 | import { setCurrentUser } from '../redux/slices/currentUser'; 5 | import { setIsLogging } from '../redux/slices/isLogging'; 6 | import { PushNotificationsService } from '.'; 7 | 8 | class AuthService { 9 | constructor() { 10 | if (AuthService.instance) { 11 | return AuthService.instance; 12 | } 13 | 14 | AuthService.instance = this; 15 | } 16 | 17 | async login(user) { 18 | store.dispatch(setIsLogging(true)); 19 | await ConnectyCube.createSession(user); 20 | await PushNotificationsService.register(); 21 | await this.setUserToAsyncStorage(user); 22 | await ConnectyCube.chat.connect({ 23 | userId: user.id, 24 | password: user.password, 25 | }); 26 | store.dispatch(setCurrentUser(user)); 27 | store.dispatch(setIsLogging(false)); 28 | 29 | return user; 30 | } 31 | 32 | async autoLogin() { 33 | const user = await this.getUserFromAsyncStorage(); 34 | 35 | if (user) { 36 | await this.login(user); 37 | } 38 | 39 | return user; 40 | } 41 | 42 | async logout() { 43 | ConnectyCube.chat.disconnect(); 44 | await ConnectyCube.destroySession(); 45 | await this.removeUserFromAsyncStorage(); 46 | store.dispatch(resetStore()); 47 | } 48 | 49 | async setUserToAsyncStorage(user) { 50 | try { 51 | const jsonValue = JSON.stringify(user); 52 | await AsyncStorage.setItem('@currentUser', jsonValue); 53 | } catch (e) { 54 | console.error('[AsyncStorage] setUserToAsyncStorage error: ', e); 55 | } 56 | } 57 | 58 | async removeUserFromAsyncStorage() { 59 | try { 60 | await AsyncStorage.removeItem('@currentUser'); 61 | } catch (e) { 62 | console.error('[AsyncStorage] removeUserFromAsyncStorage error: ', e); 63 | } 64 | } 65 | 66 | async getUserFromAsyncStorage() { 67 | try { 68 | const jsonValue = await AsyncStorage.getItem('@currentUser'); 69 | return jsonValue != null ? JSON.parse(jsonValue) : null; 70 | } catch (e) { 71 | console.error('[AsyncStorage] getUserFromAsyncStorage error: ', e); 72 | } 73 | } 74 | } 75 | 76 | export default new AuthService(); 77 | -------------------------------------------------------------------------------- /RNVideoChat/src/services/index.js: -------------------------------------------------------------------------------- 1 | export { default as AuthService } from './auth-service'; 2 | export { default as CallService } from './call-service'; 3 | export { default as CallKeepService } from './call-keep-service'; 4 | export { default as PushNotificationsService } from './push-notifications-service'; 5 | -------------------------------------------------------------------------------- /RNVideoChat/src/utils.js: -------------------------------------------------------------------------------- 1 | import { users } from './config'; 2 | import { Platform } from 'react-native'; 3 | import Toast from 'react-native-simple-toast'; 4 | 5 | export const platformOS = Platform.OS; 6 | export const isIOS = platformOS === 'ios'; 7 | export const isAndroid = platformOS === 'android'; 8 | export const versionAndroid = Number(isAndroid ? Platform.Version : -1); 9 | 10 | export function getUserById(userId, key) { 11 | const user = users.find(({ id }) => id === userId); 12 | 13 | return typeof key === 'string' && user?.hasOwnProperty(key) 14 | ? user[key] 15 | : user; 16 | } 17 | 18 | export function getCallRecipientString(usersIds) { 19 | let opponentsNamesString = ''; 20 | for (let i = 0; i < usersIds.length; ++i) { 21 | opponentsNamesString += getUserById(usersIds[i]).full_name; 22 | if (i !== (usersIds.length - 1)) { 23 | opponentsNamesString += ', '; 24 | } 25 | } 26 | return opponentsNamesString; 27 | } 28 | 29 | export function uuidv4() { 30 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 31 | const r = Math.random() * 16 | 0; 32 | const v = c == 'x' ? r : (r & 0x3 | 0x8); 33 | return v.toString(16); 34 | }); 35 | } 36 | 37 | export function showToast(text) { 38 | Toast.showWithGravity(text, Toast.LONG, Toast.TOP); 39 | } 40 | 41 | export function isCurrentRoute(navigation, routeName) { 42 | const routes = navigation.getState().routes; 43 | const currentRoute = routes[routes.length - 1]; 44 | return currentRoute.name === routeName; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /RNVideoChat/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /RNVideoChatConf/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /RNVideoChatConf/.config-files: -------------------------------------------------------------------------------- 1 | src/config.js -------------------------------------------------------------------------------- /RNVideoChatConf/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /RNVideoChatConf/.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 | -------------------------------------------------------------------------------- /RNVideoChatConf/.node-version: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /RNVideoChatConf/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /RNVideoChatConf/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /RNVideoChatConf/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | nodeLinker: node-modules 6 | 7 | yarnPath: .yarn/releases/yarn-4.5.0.cjs 8 | -------------------------------------------------------------------------------- /RNVideoChatConf/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Navigator from './src/navigator'; 3 | import { AuthService } from './src/services'; 4 | 5 | export default class App extends Component { 6 | constructor(props) { 7 | super(props); 8 | AuthService.init(); 9 | } 10 | 11 | render = () => ; 12 | } 13 | -------------------------------------------------------------------------------- /RNVideoChatConf/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 | # Exclude problematic versions of cocoapods and activesupport that causes build failures. 7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' 8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' 9 | -------------------------------------------------------------------------------- /RNVideoChatConf/__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 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/debug.keystore -------------------------------------------------------------------------------- /RNVideoChatConf/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 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 35 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/java/com/rnvideochatconf/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.rnconference 2 | 3 | import android.os.Bundle; 4 | import com.facebook.react.ReactActivity 5 | import com.facebook.react.ReactActivityDelegate 6 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled 7 | import com.facebook.react.defaults.DefaultReactActivityDelegate 8 | 9 | class MainActivity : ReactActivity() { 10 | 11 | /** 12 | * Returns the name of the main component registered from JavaScript. This is used to schedule 13 | * rendering of the component. 14 | */ 15 | override fun getMainComponentName(): String = "RNVideoChatConf" 16 | 17 | /** 18 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] 19 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] 20 | */ 21 | override fun createReactActivityDelegate(): ReactActivityDelegate = 22 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) 23 | 24 | override fun onCreate(savedInstanceState: Bundle?) { 25 | super.onCreate(null) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/java/com/rnvideochatconf/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.rnconference 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 | import com.oney.WebRTCModule.WebRTCModuleOptions 15 | 16 | class MainApplication : Application(), ReactApplication { 17 | 18 | override val reactNativeHost: ReactNativeHost = 19 | object : DefaultReactNativeHost(this) { 20 | override fun getPackages(): List = 21 | PackageList(this).packages.apply { 22 | // Packages that cannot be autolinked yet can be added manually here, for example: 23 | // add(MyPackage()) 24 | } 25 | 26 | override fun getJSMainModuleName(): String = "index" 27 | 28 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 29 | 30 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 31 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 32 | } 33 | 34 | override val reactHost: ReactHost 35 | get() = getDefaultReactHost(applicationContext, reactNativeHost) 36 | 37 | override fun onCreate() { 38 | super.onCreate() 39 | SoLoader.init(this, false) 40 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 41 | // If you opted-in for the New Architecture, we load the native entry point for this app. 42 | load() 43 | } 44 | // Initialize the WebRTC module options. 45 | WebRTCModuleOptions.getInstance().enableMediaProjectionService = true 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/drawable/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/drawable/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ffffff 4 | #000000 5 | #00000000 6 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RNVideoChatConf 3 | 4 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 23 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "26.1.10909125" 8 | kotlinVersion = "1.9.24" 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 | -------------------------------------------------------------------------------- /RNVideoChatConf/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 | 25 | # Use this property to specify which architecture you want to build. 26 | # You can also override it from the CLI using 27 | # ./gradlew -PreactNativeArchitectures=x86_64 28 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 29 | 30 | # Use this property to enable support to the new architecture. 31 | # This will allow you to use TurboModules and the Fabric render in 32 | # your application. You should enable this flag either if you want 33 | # to write custom TurboModules/Fabric components OR use libraries that 34 | # are providing them. 35 | newArchEnabled=false 36 | 37 | # Use this property to enable or disable the Hermes JS engine. 38 | # If set to false, you will be using JSC instead. 39 | hermesEnabled=true 40 | 41 | DEVELOP_STORE_FILE=debug.keystore 42 | DEVELOP_KEY_ALIAS=androiddebugkey 43 | DEVELOP_STORE_PASSWORD=android 44 | DEVELOP_KEY_PASSWORD=android 45 | 46 | RELEASE_STORE_FILE=cc-sample.keystore 47 | RELEASE_KEY_ALIAS=cc-sample-alias 48 | RELEASE_STORE_PASSWORD=connectycube00 49 | RELEASE_KEY_PASSWORD=connectycube00 -------------------------------------------------------------------------------- /RNVideoChatConf/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /RNVideoChatConf/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /RNVideoChatConf/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } 2 | plugins { id("com.facebook.react.settings") } 3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } 4 | rootProject.name = 'RNVideoChatConf' 5 | include ':app' 6 | includeBuild('../node_modules/@react-native/gradle-plugin') 7 | -------------------------------------------------------------------------------- /RNVideoChatConf/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RNVideoChatConf", 3 | "displayName": "RNVideoChatConf" 4 | } 5 | -------------------------------------------------------------------------------- /RNVideoChatConf/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/assets/icon.png -------------------------------------------------------------------------------- /RNVideoChatConf/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/assets/logo.png -------------------------------------------------------------------------------- /RNVideoChatConf/assets/sounds/calling.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/assets/sounds/calling.mp3 -------------------------------------------------------------------------------- /RNVideoChatConf/assets/sounds/dialing.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/assets/sounds/dialing.mp3 -------------------------------------------------------------------------------- /RNVideoChatConf/assets/sounds/end_call.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/assets/sounds/end_call.mp3 -------------------------------------------------------------------------------- /RNVideoChatConf/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /RNVideoChatConf/index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry, LogBox } from 'react-native'; 2 | import notifee from '@notifee/react-native'; 3 | import App from './App'; 4 | import { name as appName } from './app.json'; 5 | 6 | LogBox.ignoreLogs(['']); 7 | 8 | notifee.registerForegroundService((notification) => { 9 | return new Promise(() => { }); 10 | }); 11 | 12 | AppRegistry.registerComponent(appName, () => App); 13 | -------------------------------------------------------------------------------- /RNVideoChatConf/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 | -------------------------------------------------------------------------------- /RNVideoChatConf/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 'RNVideoChatConf' do 18 | config = use_native_modules! 19 | 20 | use_react_native!( 21 | :path => config[:reactNativePath], 22 | # An absolute path to your application root. 23 | :app_path => "#{Pod::Config.instance.installation_root}/.." 24 | ) 25 | 26 | target 'RNVideoChatConfTests' do 27 | inherit! :complete 28 | # Pods for testing 29 | end 30 | 31 | post_install do |installer| 32 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 33 | react_native_post_install( 34 | installer, 35 | config[:reactNativePath], 36 | :mac_catalyst_enabled => false, 37 | # :ccache_enabled => true 38 | ) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"RNVideoChatConf"; 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 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | return [self bundleURL]; 20 | } 21 | 22 | - (NSURL *)bundleURL 23 | { 24 | #if DEBUG 25 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 26 | #else 27 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 28 | #endif 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConnectyCube/connectycube-reactnative-samples/d2faf9f9c9f652c18fbdcb522a83b3ba2bafce84/RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "40.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "60.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "58.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "87.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "80.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "120.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "120.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "180.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "1024.png", 53 | "idiom" : "ios-marketing", 54 | "scale" : "1x", 55 | "size" : "1024x1024" 56 | } 57 | ], 58 | "info" : { 59 | "author" : "xcode", 60 | "version" : 1 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RNVideoChatConf 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 | NSAllowsArbitraryLoads 30 | 31 | NSAllowsLocalNetworking 32 | 33 | 34 | NSCameraUsageDescription 35 | Camera permission 36 | NSMicrophoneUsageDescription 37 | Microphone permission 38 | RTCAppGroupIdentifier 39 | group.com.rnconference 40 | RTCScreenSharingExtension 41 | com.rnconference.broadcast-ext 42 | UIAppFonts 43 | 44 | MaterialIcons.ttf 45 | 46 | UIBackgroundModes 47 | 48 | audio 49 | voip 50 | 51 | UILaunchStoryboardName 52 | LaunchScreen.storyboard 53 | UIRequiredDeviceCapabilities 54 | 55 | armv7 56 | 57 | UIStatusBarHidden 58 | 59 | UIStatusBarStyle 60 | UIStatusBarStyleLightContent 61 | UISupportedInterfaceOrientations 62 | 63 | UIInterfaceOrientationPortrait 64 | 65 | UISupportedInterfaceOrientations~ipad 66 | 67 | UIInterfaceOrientationLandscapeLeft 68 | UIInterfaceOrientationLandscapeRight 69 | UIInterfaceOrientationPortrait 70 | 71 | UIViewControllerBasedStatusBarAppearance 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryFileTimestamp 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | C617.1 13 | 14 | 15 | 16 | NSPrivacyAccessedAPIType 17 | NSPrivacyAccessedAPICategoryUserDefaults 18 | NSPrivacyAccessedAPITypeReasons 19 | 20 | CA92.1 21 | 22 | 23 | 24 | NSPrivacyAccessedAPIType 25 | NSPrivacyAccessedAPICategorySystemBootTime 26 | NSPrivacyAccessedAPITypeReasons 27 | 28 | 35F9.1 29 | 30 | 31 | 32 | NSPrivacyCollectedDataTypes 33 | 34 | NSPrivacyTracking 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/RNVideoChatConf.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.rnconference 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConf/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 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConfTests/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 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/RNVideoChatConfTests/RNVideoChatConfTests.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 RNVideoChatConfTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation RNVideoChatConfTests 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 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/broadcast-extension/Atomic.swift: -------------------------------------------------------------------------------- 1 | 2 | import Foundation 3 | 4 | @propertyWrapper 5 | struct Atomic { 6 | 7 | private var value: Value 8 | private let lock = NSLock() 9 | 10 | init(wrappedValue value: Value) { 11 | self.value = value 12 | } 13 | 14 | var wrappedValue: Value { 15 | get { return load() } 16 | set { store(newValue: newValue) } 17 | } 18 | 19 | func load() -> Value { 20 | lock.lock() 21 | defer { lock.unlock() } 22 | return value 23 | } 24 | 25 | mutating func store(newValue: Value) { 26 | lock.lock() 27 | defer { lock.unlock() } 28 | value = newValue 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/broadcast-extension/DarwinNotificationCenter.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2021-present 8x8, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | enum DarwinNotification: String { 20 | case broadcastStarted = "iOS_BroadcastStarted" 21 | case broadcastStopped = "iOS_BroadcastStopped" 22 | } 23 | 24 | class DarwinNotificationCenter { 25 | 26 | static var shared = DarwinNotificationCenter() 27 | 28 | private var notificationCenter: CFNotificationCenter 29 | 30 | init() { 31 | notificationCenter = CFNotificationCenterGetDarwinNotifyCenter() 32 | } 33 | 34 | func postNotification(_ name: DarwinNotification) { 35 | CFNotificationCenterPostNotification(notificationCenter, CFNotificationName(rawValue: name.rawValue as CFString), nil, nil, true) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/broadcast-extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.broadcast-services-upload 9 | NSExtensionPrincipalClass 10 | $(PRODUCT_MODULE_NAME).SampleHandler 11 | RPBroadcastProcessMode 12 | RPBroadcastProcessModeSampleBuffer 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /RNVideoChatConf/ios/broadcast-extension/broadcast-extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.rnconference 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RNVideoChatConf/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /RNVideoChatConf/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 | -------------------------------------------------------------------------------- /RNVideoChatConf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RNVideoChatConf", 3 | "version": "2.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "react-native start", 7 | "restart": "yarn start --reset-cache", 8 | "android": "react-native run-android", 9 | "ios": "react-native run-ios", 10 | "xcode": "open ios/RNVideoChatConf.xcworkspace", 11 | "clean:ios": "rm -f ios/Podfile.lock && rm -rf ios/Pods && rm -rf ios/build", 12 | "clean:android": "rm -rf android/app/build && rm -rf android/.gradle", 13 | "clean:gradle": "cd android && ./gradlew --stop && ./gradlew clean && ./gradlew cleanBuild && cd ..", 14 | "clean:yarn": "rm -rf node_modules/ && rm -f yarn.lock", 15 | "lint": "eslint .", 16 | "test": "jest" 17 | }, 18 | "dependencies": { 19 | "@notifee/react-native": "^9.1.1", 20 | "@react-navigation/native": "^6.1.18", 21 | "@react-navigation/native-stack": "^6.11.0", 22 | "react": "18.3.1", 23 | "react-native": "0.75.4", 24 | "react-native-awesome-alerts": "^2.0.0", 25 | "react-native-connectycube": "^4.0.0", 26 | "react-native-incall-manager": "^4.2.0", 27 | "react-native-safe-area-context": "^4.11.0", 28 | "react-native-screens": "^3.34.0", 29 | "react-native-simple-toast": "^3.3.1", 30 | "react-native-sound": "^0.11.2", 31 | "react-native-vector-icons": "^10.2.0", 32 | "react-native-webrtc": "^124.0.4" 33 | }, 34 | "devDependencies": { 35 | "@babel/core": "^7.20.0", 36 | "@babel/preset-env": "^7.20.0", 37 | "@babel/runtime": "^7.20.0", 38 | "@react-native/babel-preset": "0.75.4", 39 | "@react-native/eslint-config": "0.75.3", 40 | "@react-native/metro-config": "0.75.4", 41 | "@react-native/typescript-config": "0.75.4", 42 | "@types/react": "^18.2.6", 43 | "@types/react-test-renderer": "^18.0.0", 44 | "babel-jest": "^29.6.3", 45 | "eslint": "^8.19.0", 46 | "jest": "^29.6.3", 47 | "prettier": "2.8.8", 48 | "react-test-renderer": "18.3.1", 49 | "typescript": "5.0.4" 50 | }, 51 | "resolutions": { 52 | "react-native": "0.75.4" 53 | }, 54 | "engines": { 55 | "node": ">=18" 56 | }, 57 | "packageManager": "yarn@4.5.0" 58 | } 59 | -------------------------------------------------------------------------------- /RNVideoChatConf/src/components/VideoScreen/CallingLoader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ActivityIndicator, View, Text, StyleSheet } from 'react-native'; 3 | 4 | export default ({ full_name }) => ( 5 | 6 | 7 | {full_name} 8 | 9 | 10 | 11 | ); 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | ...StyleSheet.absoluteFill, 16 | flex: 1, 17 | justifyContent: 'center', 18 | }, 19 | info: { 20 | flexDirection: 'row', 21 | justifyContent: 'center', 22 | }, 23 | text: { 24 | fontSize: 16, 25 | color: 'white', 26 | marginRight: 16, 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /RNVideoChatConf/src/components/VideoScreen/RTCViewFullScreenModal.js: -------------------------------------------------------------------------------- 1 | import { useNavigation, useRoute } from '@react-navigation/native'; 2 | import React from 'react'; 3 | import { Text, View, StyleSheet, TouchableOpacity } from 'react-native'; 4 | import { RTCView } from 'react-native-webrtc'; 5 | import { useSafeAreaInsets } from 'react-native-safe-area-context'; 6 | import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; 7 | 8 | const RTCViewFullScreenModal = () => { 9 | const route = useRoute(); 10 | const navigation = useNavigation(); 11 | const { top } = useSafeAreaInsets(); 12 | const stream = route?.params?.stream ?? null; 13 | const userId = route?.params?.userId ?? 0; 14 | const userName = route?.params?.userName ?? 'unknown'; 15 | 16 | const exitFullScreen = React.useCallback(() => { 17 | navigation.goBack(); 18 | }, [navigation]); 19 | 20 | React.useEffect(() => { 21 | if (!stream) { 22 | exitFullScreen(); 23 | } 24 | }, [stream, exitFullScreen]); 25 | 26 | return stream ? ( 27 | 28 | 29 | 30 | {userName} 31 | 32 | 33 | 34 | 35 | 43 | 44 | ) : null; 45 | }; 46 | 47 | const styles = StyleSheet.create({ 48 | blackView: { 49 | flex: 1, 50 | backgroundColor: 'black', 51 | }, 52 | header: (top = 0) => ({ 53 | zIndex: 2, 54 | height: 40, 55 | width: '100%', 56 | flexDirection: 'row', 57 | alignItems: 'center', 58 | justifyContent: 'space-between', 59 | position: 'absolute', 60 | left: 0, 61 | top, 62 | }), 63 | placeholder: { 64 | height: 40, 65 | width: 40, 66 | }, 67 | userName: { 68 | fontSize: 18, 69 | color: 'white', 70 | }, 71 | button: { 72 | height: 40, 73 | width: 40, 74 | alignItems: 'center', 75 | justifyContent: 'center', 76 | }, 77 | }); 78 | 79 | export default RTCViewFullScreenModal; 80 | -------------------------------------------------------------------------------- /RNVideoChatConf/src/components/VideoScreen/UsersSelect.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; 3 | import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; 4 | import { CallService } from '../../services'; 5 | 6 | export default ({ 7 | isActiveSelect, 8 | opponentsIds, 9 | selectedUsersIds, 10 | selectUser, 11 | unselectUser, 12 | }) => { 13 | if (!isActiveSelect) { 14 | return null; 15 | } 16 | 17 | return ( 18 | 19 | Select users to start a call 20 | {opponentsIds.map(id => { 21 | const user = CallService.getUserById(id); 22 | const selected = selectedUsersIds.some(userId => id === userId); 23 | const type = selected 24 | ? 'radio-button-checked' 25 | : 'radio-button-unchecked'; 26 | const onPress = selected ? unselectUser : selectUser; 27 | 28 | return ( 29 | onPress(id)}> 33 | {user.full_name} 34 | 35 | 36 | ); 37 | })} 38 | 39 | ); 40 | }; 41 | 42 | const styles = StyleSheet.create({ 43 | container: { 44 | flex: 1, 45 | ...StyleSheet.absoluteFill, 46 | justifyContent: 'center', 47 | alignItems: 'center', 48 | }, 49 | title: { 50 | fontSize: 20, 51 | color: '#1198d4', 52 | padding: 20, 53 | }, 54 | userLabel: backgroundColor => ({ 55 | backgroundColor, 56 | height: 50, 57 | borderRadius: 25, 58 | paddingHorizontal: 10, 59 | flexDirection: 'row', 60 | justifyContent: 'space-between', 61 | alignItems: 'center', 62 | marginVertical: 5, 63 | marginHorizontal: 20, 64 | }), 65 | userName: { 66 | color: 'white', 67 | fontSize: 20, 68 | marginRight: 10, 69 | }, 70 | }); 71 | -------------------------------------------------------------------------------- /RNVideoChatConf/src/config.js: -------------------------------------------------------------------------------- 1 | export const NO_ANSWER_TIMER = 30000; // 30 sec 2 | 3 | export const credentials = { 4 | appId: REPLACE_APP_ID, 5 | authKey: 'REPLACE_APP_AUTH_KEY', 6 | }; 7 | 8 | export const appConfig = { 9 | debug: { mode: 1 }, 10 | }; 11 | 12 | export const users = [ 13 | { 14 | id: REPLACE_USER_1_ID, 15 | full_name: 'REPLACE_USER_1_FULL_NAME', 16 | login: 'REPLACE_USER_1_LOGIN', 17 | password: 'REPLACE_USER_1_PASSWORD', 18 | color: '#34ad86', 19 | }, 20 | { 21 | id: REPLACE_USER_2_ID, 22 | full_name: 'REPLACE_USER_2_FULL_NAME', 23 | login: 'REPLACE_USER_2_LOGIN', 24 | password: 'REPLACE_USER_2_PASSWORD', 25 | color: '#077988', 26 | }, 27 | { 28 | id: REPLACE_USER_3_ID, 29 | full_name: 'REPLACE_USER_3_FULL_NAME', 30 | login: 'REPLACE_USER_3_LOGIN', 31 | password: 'REPLACE_USER_3_PASSWORD', 32 | color: '#13aaae', 33 | }, 34 | { 35 | id: REPLACE_USER_4_ID, 36 | full_name: 'REPLACE_USER_4_FULL_NAME', 37 | login: 'REPLACE_USER_4_LOGIN', 38 | password: 'REPLACE_USER_4_PASSWORD', 39 | color: '#056a96', 40 | }, 41 | ]; 42 | -------------------------------------------------------------------------------- /RNVideoChatConf/src/navigator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { NavigationContainer } from '@react-navigation/native'; 3 | import { createNativeStackNavigator } from '@react-navigation/native-stack'; 4 | import AuthScreen from './components/AuthScreen'; 5 | import VideoScreen from './components/VideoScreen'; 6 | import RTCViewFullScreenModal from './components/VideoScreen/RTCViewFullScreenModal'; 7 | 8 | const Stack = createNativeStackNavigator(); 9 | 10 | const AppNavigator = () => { 11 | return ( 12 | 13 | 17 | 18 | 19 | 26 | 27 | 28 | ); 29 | }; 30 | 31 | export default AppNavigator; 32 | -------------------------------------------------------------------------------- /RNVideoChatConf/src/services/auth-service.js: -------------------------------------------------------------------------------- 1 | import ConnectyCube from 'react-native-connectycube'; 2 | import { credentials, appConfig } from '../config'; 3 | import CallService from './call-service'; 4 | 5 | export default class AuthService { 6 | init = (janusServerEndpoint = null) => { 7 | if (janusServerEndpoint) { 8 | appConfig.conference.server = janusServerEndpoint; 9 | } 10 | ConnectyCube.init(credentials, appConfig); 11 | }; 12 | 13 | createSession(user) { 14 | return ConnectyCube.createSession(user); 15 | } 16 | 17 | login = (user) => { 18 | return new Promise((resolve, reject) => { 19 | this.createSession(user) 20 | .then(() => { 21 | CallService.CURRENT_USER = { full_name: user.full_name, id: user.id }; 22 | return ConnectyCube.chat.connect({ 23 | userId: user.id, 24 | password: user.password, 25 | }); 26 | }) 27 | .then(resolve) 28 | .catch(reject); 29 | }); 30 | }; 31 | 32 | logout = () => { 33 | ConnectyCube.chat.disconnect(); 34 | ConnectyCube.destroySession(); 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /RNVideoChatConf/src/services/customEvents.js: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'events'; 2 | 3 | const CUSTOM_EVENTS = { 4 | STOP_CALL_UI_RESET: 'STOP_CALL_UI_RESET', 5 | }; 6 | 7 | const customEventEmitter = new EventEmitter(); 8 | 9 | export { CUSTOM_EVENTS }; 10 | 11 | export default customEventEmitter; 12 | -------------------------------------------------------------------------------- /RNVideoChatConf/src/services/index.js: -------------------------------------------------------------------------------- 1 | import Auth from './auth-service'; 2 | import Call from './call-service'; 3 | 4 | export const AuthService = new Auth(); 5 | export const CallService = new Call(); 6 | -------------------------------------------------------------------------------- /RNVideoChatConf/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json" 3 | } 4 | --------------------------------------------------------------------------------