├── .watchmanconfig ├── .node-version ├── .ruby-version ├── .vscode └── settings.json ├── .bundle └── config ├── tsconfig.json ├── app.json ├── android ├── app │ ├── debug.keystore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ └── styles.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 │ │ │ │ └── drawable │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── facebookmessenger │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── facebookmessenger │ │ │ │ └── ReactNativeFlipper.java │ │ └── release │ │ │ └── java │ │ │ └── com │ │ │ └── facebookmessenger │ │ │ └── ReactNativeFlipper.java │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── build.gradle ├── settings.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── env.d.ts ├── src ├── screens │ ├── chat │ │ ├── models │ │ │ ├── Conversation.ts │ │ │ └── Message.ts │ │ └── index.tsx │ ├── people │ │ ├── index.tsx │ │ ├── models │ │ │ └── index.ts │ │ └── requests │ │ │ └── index.ts │ ├── call │ │ ├── components │ │ │ ├── ParticipantList.tsx │ │ │ ├── ParticipantView.tsx │ │ │ ├── MeetingView.tsx │ │ │ └── Controls.tsx │ │ ├── requests │ │ │ └── index.ts │ │ └── index.tsx │ ├── chats │ │ └── index.tsx │ ├── receiveCall │ │ └── index.tsx │ ├── index.tsx │ ├── login │ │ └── index.tsx │ └── register │ │ └── index.tsx └── shared │ ├── constants │ ├── colors.ts │ └── navRoutes.ts │ ├── components │ ├── Loader.tsx │ └── Input.tsx │ ├── auth │ ├── models │ │ └── index.ts │ ├── requests │ │ └── index.ts │ └── contexts │ │ └── auth.context.tsx │ ├── friends │ ├── models │ │ └── index.ts │ ├── helpers │ │ └── friends.ts │ ├── components │ │ ├── Friends.tsx │ │ └── Friend.tsx │ └── contexts │ │ └── friends.context.tsx │ └── request.ts ├── ios ├── FacebookMessenger │ ├── Images.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.h │ ├── main.m │ ├── FacebookMessenger.entitlements │ ├── Info.plist │ ├── AppDelegate.mm │ └── LaunchScreen.storyboard ├── FacebookMessenger.xcworkspace │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── contents.xcworkspacedata ├── .xcode.env ├── FacebookMessengerTests │ ├── Info.plist │ └── FacebookMessengerTests.m ├── Podfile ├── FacebookMessenger.xcodeproj │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── FacebookMessenger.xcscheme │ └── project.pbxproj └── Podfile.lock ├── .prettierrc.js ├── babel.config.js ├── Gemfile ├── .eslintrc.js ├── __tests__ └── App-test.tsx ├── metro.config.js ├── App.tsx ├── index.js ├── .gitignore └── package.json /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.5 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/react-native/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FacebookMessenger", 3 | "displayName": "FacebookMessenger" 4 | } -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/debug.keystore -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@env' { 2 | export const VIDEO_SDK_TOKEN: string; 3 | export const IP_ADDRESS: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/screens/chat/models/Conversation.ts: -------------------------------------------------------------------------------- 1 | export interface Conversation { 2 | id: number; 3 | userIds: number[]; 4 | } 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | FacebookMessenger 3 | 4 | -------------------------------------------------------------------------------- /ios/FacebookMessenger/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/screens/chat/models/Message.ts: -------------------------------------------------------------------------------- 1 | export interface Message { 2 | id?: number; 3 | message: string; 4 | creatorId: number; 5 | conversationId?: number; 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jon-Peppinck/facebook-messenger-clone/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | endOfLine: 'auto', 8 | }; 9 | -------------------------------------------------------------------------------- /src/screens/people/index.tsx: -------------------------------------------------------------------------------- 1 | import Friends from '../../shared/friends/components/Friends'; 2 | 3 | const PeopleScreen = () => { 4 | return ; 5 | }; 6 | 7 | export default PeopleScreen; 8 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ['module:metro-react-native-babel-preset'], 5 | plugins: ['module:react-native-dotenv'], 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /src/screens/people/models/index.ts: -------------------------------------------------------------------------------- 1 | import {UserDetails} from './../../../shared/auth/models'; 2 | 3 | export interface FriendRequest { 4 | id: number; 5 | creator: UserDetails; 6 | receiver: UserDetails; 7 | } 8 | -------------------------------------------------------------------------------- /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 File.read(File.join(__dir__, '.ruby-version')).strip 5 | 6 | gem 'cocoapods', '~> 1.11', '>= 1.11.3' 7 | -------------------------------------------------------------------------------- /ios/FacebookMessenger/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | @interface AppDelegate : RCTAppDelegate 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ios/FacebookMessenger/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 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #FFF 3 | 4 | 5 | #FC0303 6 | 7 | 8 | @color/red 9 | 10 | -------------------------------------------------------------------------------- /src/screens/call/components/ParticipantList.tsx: -------------------------------------------------------------------------------- 1 | import ParticipantView from './ParticipantView'; 2 | 3 | const ParticipantList = ({participants}: any) => { 4 | return participants.map((p: any) => ( 5 | 6 | )); 7 | }; 8 | 9 | export default ParticipantList; 10 | -------------------------------------------------------------------------------- /ios/FacebookMessenger/FacebookMessenger.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/FacebookMessenger.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | rules: { 5 | curly: 'off', 6 | 'react/jsx-uses-react': 'off', 7 | 'react/react-in-jsx-scope': 'off', 8 | 'react/no-unstable-nested-components': 'off', 9 | 'react-native/no-inline-styles': 'off', 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /ios/FacebookMessenger.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/screens/people/requests/index.ts: -------------------------------------------------------------------------------- 1 | import {baseUrl, get} from '../../../shared/request'; 2 | import {FriendRequest} from '../models'; 3 | 4 | export const getFriendRequests = async () => { 5 | const {data: friendRequests} = await get( 6 | `${baseUrl}/get-friends`, 7 | ); 8 | 9 | return friendRequests; 10 | }; 11 | -------------------------------------------------------------------------------- /__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: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /src/shared/constants/colors.ts: -------------------------------------------------------------------------------- 1 | export const COLOR_FB_PRIMARY = '#4267B2'; 2 | export const COLOR_FB_SECONDARY = '#8B9DC3'; 3 | 4 | export const COLOR_ONLINE_GREEN = '#0FFF50'; 5 | export const COLOR_RED = '#FF0000'; 6 | 7 | export const COLOR_LIGHT_GRAY = '#EEEEEE'; 8 | export const COLOR_WHITE = '#FFFFFF'; 9 | export const COLOR_BLACK = '#000000'; 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: true, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /src/shared/components/Loader.tsx: -------------------------------------------------------------------------------- 1 | import {ActivityIndicator, MD2Colors} from 'react-native-paper'; 2 | 3 | type Props = { 4 | dark?: boolean; 5 | }; 6 | 7 | const Loader = ({dark = false}: Props) => { 8 | return ( 9 | 13 | ); 14 | }; 15 | 16 | export default Loader; 17 | -------------------------------------------------------------------------------- /src/shared/constants/navRoutes.ts: -------------------------------------------------------------------------------- 1 | interface NavRoutes { 2 | key: string; 3 | title: string; 4 | focusedIcon: string; 5 | } 6 | 7 | export const navRoutes: NavRoutes[] = [ 8 | { 9 | key: 'chats', 10 | title: 'Chats', 11 | focusedIcon: 'chat', 12 | }, 13 | {key: 'calls', title: 'Calls', focusedIcon: 'video'}, 14 | {key: 'people', title: 'People', focusedIcon: 'account'}, 15 | {key: 'stories', title: 'Stories', focusedIcon: 'book'}, 16 | ]; 17 | -------------------------------------------------------------------------------- /src/screens/call/requests/index.ts: -------------------------------------------------------------------------------- 1 | import {VIDEO_SDK_TOKEN} from '@env'; 2 | 3 | export const createMeeting = async (): Promise => { 4 | const res = await fetch('https://api.videosdk.live/v2/rooms', { 5 | method: 'POST', 6 | headers: { 7 | authorization: `${VIDEO_SDK_TOKEN}`, 8 | 'Content-Type': 'application/json', 9 | }, 10 | body: JSON.stringify({}), 11 | }); 12 | 13 | const {roomId} = await res.json(); 14 | 15 | return roomId; 16 | }; 17 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/shared/auth/models/index.ts: -------------------------------------------------------------------------------- 1 | export interface UserDetails { 2 | id: number; 3 | firstName: string; 4 | lastName: string; 5 | email: string; 6 | } 7 | 8 | export interface NewUser { 9 | firstName: string; 10 | lastName: string; 11 | email: string; 12 | password: string; 13 | } 14 | 15 | export interface LoginUser { 16 | email: string; 17 | password: string; 18 | } 19 | 20 | export interface Jwt { 21 | token: string; 22 | } 23 | 24 | export interface Credentials extends Jwt { 25 | user: UserDetails; 26 | } 27 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/shared/friends/models/index.ts: -------------------------------------------------------------------------------- 1 | import {UserDetails} from './../../auth/models/index'; 2 | 3 | export interface ActiveFriend extends UserDetails { 4 | isActive: boolean; 5 | } 6 | 7 | export interface CallDetails { 8 | meetingId: string; 9 | friendId: number; 10 | } 11 | 12 | export enum CallResponse { 13 | Accepted = 'ACCEPTED', 14 | Declined = 'DECLINED', 15 | } 16 | 17 | export interface ICallResponse { 18 | status: CallResponse; 19 | } 20 | 21 | export enum CallActivity { 22 | None = 'NONE', 23 | Receiving = 'RECEIVING', 24 | Requesting = 'REQUESTING', 25 | Accepted = 'ACCEPTED', 26 | } 27 | -------------------------------------------------------------------------------- /App.tsx: -------------------------------------------------------------------------------- 1 | import {QueryClient, QueryClientProvider} from 'react-query'; 2 | import {Provider as PaperProvider} from 'react-native-paper'; 3 | 4 | import {AuthProvider} from './src/shared/auth/contexts/auth.context'; 5 | import {FriendsProvider} from './src/shared/friends/contexts/friends.context'; 6 | import Screens from './src/screens'; 7 | 8 | function App(): JSX.Element { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | } 21 | 22 | export default App; 23 | -------------------------------------------------------------------------------- /src/screens/chats/index.tsx: -------------------------------------------------------------------------------- 1 | import {useContext, useEffect} from 'react'; 2 | 3 | import {useNavigate} from 'react-router-native'; 4 | 5 | import Friends from '../../shared/friends/components/Friends'; 6 | import {FriendsContext} from '../../shared/friends/contexts/friends.context'; 7 | import {CallActivity} from '../../shared/friends/models'; 8 | 9 | const ChatsScreen = () => { 10 | const {callActivity} = useContext(FriendsContext); 11 | const navigate = useNavigate(); 12 | 13 | useEffect(() => { 14 | if (callActivity === CallActivity.Receiving) { 15 | navigate('/receive-call'); 16 | } 17 | }, [callActivity, navigate]); 18 | 19 | return ; 20 | }; 21 | 22 | export default ChatsScreen; 23 | -------------------------------------------------------------------------------- /src/shared/friends/helpers/friends.ts: -------------------------------------------------------------------------------- 1 | import {FriendRequest} from '../../../screens/people/models'; 2 | import {UserDetails} from '../../auth/models'; 3 | 4 | const getFriends = (friendRequests: FriendRequest[], userId: number) => { 5 | const friends = friendRequests.map(friendRequest => { 6 | const isUserCreator = userId === friendRequest.creator.id; 7 | const friendDetails = isUserCreator 8 | ? friendRequest.receiver 9 | : friendRequest.creator; 10 | 11 | const {id, firstName, lastName, email} = friendDetails; 12 | 13 | return { 14 | id, 15 | email, 16 | firstName, 17 | lastName, 18 | } as UserDetails; 19 | }); 20 | 21 | return friends; 22 | }; 23 | 24 | export default getFriends; 25 | -------------------------------------------------------------------------------- /src/shared/auth/requests/index.ts: -------------------------------------------------------------------------------- 1 | import {baseUrl, get, post} from '../../request'; 2 | 3 | import {Credentials, LoginUser, NewUser, UserDetails} from '../models'; 4 | 5 | export const getUsers = async () => { 6 | const {data: users} = await get(`${baseUrl}/auth`); 7 | 8 | return users; 9 | }; 10 | 11 | export const register = async (newUser: NewUser) => { 12 | const {data: user} = await post( 13 | `${baseUrl}/auth/register`, 14 | newUser, 15 | ); 16 | 17 | return user; 18 | }; 19 | 20 | export const login = async (loginUser: LoginUser) => { 21 | const {data: credentials} = await post( 22 | `${baseUrl}/auth/login`, 23 | loginUser, 24 | ); 25 | 26 | return credentials; 27 | }; 28 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | googlePlayServicesVersion = "+" 6 | firebaseMessagingVersion = "21.1.0" 7 | 8 | buildToolsVersion = "33.0.0" 9 | minSdkVersion = 23 10 | compileSdkVersion = 33 11 | targetSdkVersion = 33 12 | 13 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 14 | ndkVersion = "23.1.7779620" 15 | } 16 | repositories { 17 | google() 18 | mavenCentral() 19 | } 20 | dependencies { 21 | classpath("com.android.tools.build:gradle:7.3.1") 22 | classpath("com.facebook.react:react-native-gradle-plugin") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'FacebookMessenger' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/react-native-gradle-plugin') 5 | 6 | include ':rnwebrtc' 7 | project(':rnwebrtc').projectDir = new File(rootProject.projectDir, '../node_modules/@videosdk.live/react-native-webrtc/android') 8 | 9 | include ':rnincallmanager' 10 | project(':rnincallmanager').projectDir = new File(rootProject.projectDir, '../node_modules/@videosdk.live/react-native-incallmanager/android') 11 | 12 | include ':rnfgservice' 13 | project(':rnfgservice').projectDir = new File(rootProject.projectDir, '../node_modules/@videosdk.live/react-native-foreground-service/android') -------------------------------------------------------------------------------- /android/app/src/release/java/com/facebookmessenger/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.facebookmessenger; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ios/FacebookMessengerTests/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 | -------------------------------------------------------------------------------- /src/screens/call/components/ParticipantView.tsx: -------------------------------------------------------------------------------- 1 | import {Text, View} from 'react-native'; 2 | 3 | import { 4 | useParticipant, 5 | MediaStream, 6 | RTCView, 7 | } from '@videosdk.live/react-native-sdk'; 8 | 9 | const ParticipantView = ({participantId}: any) => { 10 | const {displayName, webcamStream, webcamOn} = useParticipant(participantId); 11 | 12 | return webcamOn && webcamStream ? ( 13 | 21 | ) : ( 22 | 29 | {displayName} 30 | 31 | ); 32 | }; 33 | 34 | export default ParticipantView; 35 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import {AppRegistry, Platform} from 'react-native'; 2 | 3 | import PushNotification from 'react-native-push-notification'; 4 | import PushNotificationIOS from '@react-native-community/push-notification-ios'; 5 | import {register} from '@videosdk.live/react-native-sdk'; 6 | 7 | import App from './App'; 8 | import {name as appName} from './app.json'; 9 | 10 | // if (Platform.OS === 'android') { 11 | register(); 12 | // } 13 | AppRegistry.registerComponent(appName, () => App); 14 | 15 | PushNotification.configure({ 16 | onRegister: function (token) { 17 | console.log('TOKEN:', token); 18 | }, 19 | 20 | onNotification: function (notification) { 21 | console.log('NOTIFICATION:', notification); 22 | notification.finish(PushNotificationIOS.FetchResult.NoData); 23 | }, 24 | 25 | channelId: '1', 26 | 27 | permissions: { 28 | alert: true, 29 | badge: true, 30 | sound: true, 31 | }, 32 | 33 | popInitialNotification: true, 34 | 35 | requestPermissions: Platform.OS === 'ios', 36 | }); 37 | -------------------------------------------------------------------------------- /ios/FacebookMessenger/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/screens/call/index.tsx: -------------------------------------------------------------------------------- 1 | import {useContext} from 'react'; 2 | import {SafeAreaView} from 'react-native'; 3 | 4 | import {MeetingProvider} from '@videosdk.live/react-native-sdk'; 5 | 6 | import {VIDEO_SDK_TOKEN} from '@env'; 7 | 8 | import {FriendsContext} from '../../shared/friends/contexts/friends.context'; 9 | import MeetingView from './components/MeetingView'; 10 | import {AuthContext} from '../../shared/auth/contexts/auth.context'; 11 | 12 | const CallScreen = () => { 13 | const {userDetails} = useContext(AuthContext); 14 | const {callDetails} = useContext(FriendsContext); 15 | 16 | return ( 17 | 18 | {callDetails && userDetails && ( 19 | 27 | 28 | 29 | )} 30 | 31 | ); 32 | }; 33 | 34 | export default CallScreen; 35 | -------------------------------------------------------------------------------- /src/shared/components/Input.tsx: -------------------------------------------------------------------------------- 1 | import {Dispatch, SetStateAction} from 'react'; 2 | 3 | import {TextInput} from 'react-native-paper'; 4 | 5 | import { 6 | COLOR_FB_SECONDARY, 7 | COLOR_LIGHT_GRAY, 8 | COLOR_WHITE, 9 | } from '../constants/colors'; 10 | 11 | type Props = { 12 | mode?: 'flat' | 'outlined'; 13 | placeholder?: string; 14 | secure?: boolean; 15 | value: string; 16 | onChangeText: Dispatch>; 17 | }; 18 | 19 | const Input = ({ 20 | mode = 'flat', 21 | placeholder = '', 22 | secure = false, 23 | value, 24 | onChangeText, 25 | }: Props) => { 26 | return ( 27 | 44 | ); 45 | }; 46 | 47 | export default Input; 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | # OSX 3 | # 4 | .DS_Store 5 | 6 | # Xcode 7 | # 8 | build/ 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata 18 | *.xccheckout 19 | *.moved-aside 20 | DerivedData 21 | *.hmap 22 | *.ipa 23 | *.xcuserstate 24 | ios/.xcode.env.local 25 | 26 | # Android/IntelliJ 27 | # 28 | build/ 29 | .idea 30 | .gradle 31 | local.properties 32 | *.iml 33 | *.hprof 34 | .cxx/ 35 | *.keystore 36 | !debug.keystore 37 | 38 | # node.js 39 | # 40 | node_modules/ 41 | npm-debug.log 42 | yarn-error.log 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | **/fastlane/report.xml 52 | **/fastlane/Preview.html 53 | **/fastlane/screenshots 54 | **/fastlane/test_output 55 | 56 | # Bundle artifact 57 | *.jsbundle 58 | 59 | # Ruby / CocoaPods 60 | /ios/Pods/ 61 | /vendor/bundle/ 62 | 63 | # Temporary files created by Metro to check the health of the file watcher 64 | .metro-health-check* 65 | -------------------------------------------------------------------------------- /src/shared/friends/components/Friends.tsx: -------------------------------------------------------------------------------- 1 | import {useContext} from 'react'; 2 | import {View, StyleSheet, Text} from 'react-native'; 3 | 4 | import {Button} from 'react-native-paper'; 5 | 6 | import {AuthContext} from '../../auth/contexts/auth.context'; 7 | import {FriendsContext} from '../contexts/friends.context'; 8 | import Friend from './Friend'; 9 | import Loader from '../../components/Loader'; 10 | 11 | type Props = { 12 | showMessage?: boolean; 13 | }; 14 | 15 | const Friends = ({showMessage = false}: Props) => { 16 | const {onLogout} = useContext(AuthContext); 17 | const {friends, isLoading} = useContext(FriendsContext); 18 | 19 | if (isLoading) { 20 | return ; 21 | } 22 | 23 | return ( 24 | 25 | {friends.length > 0 ? ( 26 | friends.map(friend => ( 27 | 28 | )) 29 | ) : ( 30 | No friends 31 | )} 32 | 33 | {/* TEMP */} 34 | {showMessage && } 35 | 36 | ); 37 | }; 38 | 39 | const styles = StyleSheet.create({ 40 | container: { 41 | flex: 1, 42 | padding: 16, 43 | }, 44 | }); 45 | 46 | export default Friends; 47 | -------------------------------------------------------------------------------- /src/shared/request.ts: -------------------------------------------------------------------------------- 1 | import AsyncStorage from '@react-native-async-storage/async-storage'; 2 | import axios, {InternalAxiosRequestConfig} from 'axios'; 3 | 4 | import {IP_ADDRESS} from '@env'; 5 | 6 | import {Credentials} from './auth/models'; 7 | 8 | export const baseUrl = `http://${IP_ADDRESS ?? '10.0.2.2'}:4000`; 9 | 10 | const _retrieveConfigCredentials = async ( 11 | config: InternalAxiosRequestConfig, 12 | ) => { 13 | try { 14 | const credentials = await AsyncStorage.getItem('credentials'); 15 | 16 | if (credentials !== null) { 17 | const {token} = JSON.parse(credentials) as Credentials; 18 | config.headers.Authorization = `Bearer ${token}`; 19 | } 20 | } catch (error) { 21 | console.log(error); 22 | } 23 | 24 | return config; 25 | }; 26 | 27 | const getConfigWithHeaders = async ( 28 | config: InternalAxiosRequestConfig, 29 | ) => { 30 | config.headers['content-type'] = 'application/json'; 31 | // config.headers['Content-Type'] = 'application/json'; 32 | return _retrieveConfigCredentials(config); 33 | }; 34 | 35 | axios.interceptors.request.use( 36 | config => getConfigWithHeaders(config), 37 | error => { 38 | return Promise.reject(error); 39 | }, 40 | ); 41 | 42 | export const {get, post, put, delete: del} = axios; 43 | -------------------------------------------------------------------------------- /src/screens/call/components/MeetingView.tsx: -------------------------------------------------------------------------------- 1 | import {View} from 'react-native'; 2 | 3 | import {useMeeting} from '@videosdk.live/react-native-sdk'; 4 | 5 | import ParticipantList from './ParticipantList'; 6 | import Controls from './Controls'; 7 | import {useEffect, useState} from 'react'; 8 | 9 | const MeetingView = () => { 10 | const {join, leave, toggleWebcam, toggleMic, participants} = useMeeting({}); 11 | 12 | const [hasJoined, setHasJoined] = useState(false); 13 | 14 | useEffect(() => { 15 | if (hasJoined) return; 16 | 17 | setHasJoined(true); 18 | 19 | const joinCall = async () => { 20 | await join(); 21 | console.log(participants); 22 | }; 23 | 24 | joinCall().catch(e => console.log(e)); 25 | 26 | return () => { 27 | if (hasJoined) { 28 | const leaveCall = async () => { 29 | await leave(); 30 | }; 31 | 32 | leaveCall().catch(e => console.log(e)); 33 | } 34 | }; 35 | }, []); 36 | 37 | const participantsArrId = [...participants.keys()]; 38 | 39 | return ( 40 | 41 | 42 | 47 | 48 | ); 49 | }; 50 | 51 | export default MeetingView; 52 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/facebookmessenger/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.facebookmessenger; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 7 | 8 | public class MainActivity extends 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 15 | protected String getMainComponentName() { 16 | return "FacebookMessenger"; 17 | } 18 | 19 | /** 20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 22 | * (aka React 18) with two boolean flags. 23 | */ 24 | @Override 25 | protected ReactActivityDelegate createReactActivityDelegate() { 26 | return new DefaultReactActivityDelegate( 27 | this, 28 | getMainComponentName(), 29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 30 | DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled 31 | // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18). 32 | DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Facebook-Messenger", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "lint": "eslint .", 9 | "start": "react-native start", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "@react-native-async-storage/async-storage": "^1.17.11", 14 | "@react-native-community/push-notification-ios": "^1.10.1", 15 | "@videosdk.live/react-native-incallmanager": "^0.0.9", 16 | "@videosdk.live/react-native-sdk": "^0.0.44", 17 | "axios": "^1.3.2", 18 | "react": "18.2.0", 19 | "react-native": "0.71.0", 20 | "react-native-background-timer": "^2.4.1", 21 | "react-native-paper": "^5.1.3", 22 | "react-native-push-notification": "^8.1.1", 23 | "react-native-safe-area-context": "^4.4.1", 24 | "react-native-vector-icons": "^9.2.0", 25 | "react-query": "^3.39.3", 26 | "react-router-native": "^6.6.2", 27 | "socket.io-client": "^4.6.1" 28 | }, 29 | "devDependencies": { 30 | "@babel/core": "^7.12.9", 31 | "@babel/preset-env": "^7.14.0", 32 | "@babel/runtime": "^7.12.5", 33 | "@react-native-community/eslint-config": "^3.0.0", 34 | "@tsconfig/react-native": "^2.0.2", 35 | "@types/jest": "^29.2.1", 36 | "@types/react": "^18.0.24", 37 | "@types/react-native-background-timer": "^2.0.0", 38 | "@types/react-native-push-notification": "^8.1.1", 39 | "@types/react-test-renderer": "^18.0.0", 40 | "babel-jest": "^29.2.1", 41 | "eslint": "^8.19.0", 42 | "jest": "^29.2.1", 43 | "metro-react-native-babel-preset": "0.73.5", 44 | "prettier": "^2.4.1", 45 | "react-native-dotenv": "^3.4.8", 46 | "react-test-renderer": "18.2.0", 47 | "typescript": "4.8.4" 48 | }, 49 | "jest": { 50 | "preset": "react-native" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/screens/call/components/Controls.tsx: -------------------------------------------------------------------------------- 1 | import {useContext} from 'react'; 2 | import {View} from 'react-native'; 3 | 4 | import {IconButton} from 'react-native-paper'; 5 | import {useNavigate} from 'react-router-native'; 6 | import {COLOR_BLACK, COLOR_WHITE} from '../../../shared/constants/colors'; 7 | import {FriendsContext} from '../../../shared/friends/contexts/friends.context'; 8 | import {CallActivity} from '../../../shared/friends/models'; 9 | 10 | const Controls = ({leave, toggleWebcam, toggleMic}: any) => { 11 | const {friend, setCallDetails, setCallActivity} = useContext(FriendsContext); 12 | 13 | const navigate = useNavigate(); 14 | 15 | return ( 16 | 25 | toggleWebcam()} 31 | accessibilityLabelledBy={undefined} 32 | accessibilityLanguage={undefined} 33 | /> 34 | toggleMic()} 40 | accessibilityLabelledBy={undefined} 41 | accessibilityLanguage={undefined} 42 | /> 43 | { 50 | leave(); 51 | setCallActivity(CallActivity.None); 52 | setCallDetails(null); 53 | navigate(`/chat/${friend.id}`); 54 | }} 55 | accessibilityLabelledBy={undefined} 56 | accessibilityLanguage={undefined} 57 | /> 58 | 59 | ); 60 | }; 61 | 62 | export default Controls; 63 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | pod ‘react-native-webrtc’, :path => ‘../node_modules/@videosdk.live/react-native-webrtc’ 5 | 6 | platform :ios, min_ios_version_supported 7 | prepare_react_native_project! 8 | 9 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 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 'FacebookMessenger' do 18 | config = use_native_modules! 19 | 20 | # Flags change depending on the env values. 21 | flags = get_default_flags() 22 | 23 | use_react_native!( 24 | :path => config[:reactNativePath], 25 | # Hermes is now enabled by default. Disable by setting this flag to false. 26 | # Upcoming versions of React Native may rely on get_default_flags(), but 27 | # we make it explicit here to aid in the React Native upgrade process. 28 | :hermes_enabled => flags[:hermes_enabled], 29 | :fabric_enabled => flags[:fabric_enabled], 30 | # Enables Flipper. 31 | # 32 | # Note that if you have use_frameworks! enabled, Flipper will not work and 33 | # you should disable the next line. 34 | :flipper_configuration => flipper_config, 35 | # An absolute path to your application root. 36 | :app_path => "#{Pod::Config.instance.installation_root}/.." 37 | ) 38 | 39 | target 'FacebookMessengerTests' do 40 | inherit! :complete 41 | # Pods for testing 42 | end 43 | 44 | post_install do |installer| 45 | react_native_post_install( 46 | installer, 47 | # Set `mac_catalyst_enabled` to `true` in order to apply patches 48 | # necessary for Mac Catalyst builds 49 | :mac_catalyst_enabled => false 50 | ) 51 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # This one fixes a weird WebRTC runtime problem on some devices. 28 | android.enableDexingArtifactTransform.desugaring=false 29 | 30 | # Version of flipper SDK to use with React Native 31 | FLIPPER_VERSION=0.125.0 32 | 33 | # Use this property to specify which architecture you want to build. 34 | # You can also override it from the CLI using 35 | # ./gradlew -PreactNativeArchitectures=x86_64 36 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 37 | 38 | # Use this property to enable support to the new architecture. 39 | # This will allow you to use TurboModules and the Fabric render in 40 | # your application. You should enable this flag either if you want 41 | # to write custom TurboModules/Fabric components OR use libraries that 42 | # are providing them. 43 | newArchEnabled=false 44 | 45 | # Use this property to enable or disable the Hermes JS engine. 46 | # If set to false, you will be using JSC instead. 47 | hermesEnabled=true 48 | -------------------------------------------------------------------------------- /src/shared/friends/components/Friend.tsx: -------------------------------------------------------------------------------- 1 | import {useContext, useEffect} from 'react'; 2 | import {View, Text, StyleSheet, Pressable} from 'react-native'; 3 | 4 | import {useNavigate} from 'react-router-native'; 5 | import {Avatar} from 'react-native-paper'; 6 | 7 | import {ActiveFriend} from '../models'; 8 | import {COLOR_ONLINE_GREEN} from '../../constants/colors'; 9 | 10 | import {FriendsContext} from '../contexts/friends.context'; 11 | 12 | type Props = { 13 | friend: ActiveFriend; 14 | showMessage?: boolean; 15 | }; 16 | 17 | const Friend = ({friend, showMessage = false}: Props) => { 18 | const {setFriend} = useContext(FriendsContext); 19 | const navigate = useNavigate(); 20 | 21 | const {id, firstName, lastName, isActive} = friend; 22 | 23 | useEffect(() => { 24 | setFriend(friend); 25 | }, [friend, isActive, setFriend]); 26 | 27 | return ( 28 | { 31 | navigate(`/chat/${id}`); 32 | }}> 33 | 34 | 41 | {isActive && ( 42 | 53 | )} 54 | 55 | 56 | {firstName} {lastName} 57 | 58 | {showMessage && This was the last message | Sun} 59 | 60 | 61 | 62 | ); 63 | }; 64 | 65 | const styles = StyleSheet.create({ 66 | container: { 67 | flex: 1, 68 | padding: 16, 69 | }, 70 | friend: { 71 | flexDirection: 'row', 72 | alignItems: 'center', 73 | marginBottom: 8, 74 | }, 75 | profilePicture: { 76 | marginRight: 8, 77 | }, 78 | }); 79 | 80 | export default Friend; 81 | -------------------------------------------------------------------------------- /ios/FacebookMessengerTests/FacebookMessengerTests.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 FacebookMessengerTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation FacebookMessengerTests 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 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/facebookmessenger/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.facebookmessenger; 2 | 3 | import android.app.Application; 4 | import com.facebook.react.PackageList; 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 9 | import com.facebook.react.defaults.DefaultReactNativeHost; 10 | import com.facebook.soloader.SoLoader; 11 | import java.util.List; 12 | 13 | import live.videosdk.rnfgservice.ForegroundServicePackage; 14 | import live.videosdk.rnincallmanager.InCallManagerPackage; 15 | import live.videosdk.rnwebrtc.WebRTCModulePackage; 16 | 17 | public class MainApplication extends Application implements ReactApplication { 18 | 19 | private final ReactNativeHost mReactNativeHost = 20 | new DefaultReactNativeHost(this) { 21 | @Override 22 | public boolean getUseDeveloperSupport() { 23 | return BuildConfig.DEBUG; 24 | } 25 | 26 | @Override 27 | protected List getPackages() { 28 | @SuppressWarnings("UnnecessaryLocalVariable") 29 | List packages = new PackageList(this).getPackages(); 30 | // Packages that cannot be autolinked yet can be added manually here, for example: 31 | // packages.add(new MyReactNativePackage()); 32 | packages.add(new ForegroundServicePackage()); 33 | packages.add(new InCallManagerPackage()); 34 | packages.add(new WebRTCModulePackage()); 35 | 36 | return packages; 37 | } 38 | 39 | @Override 40 | protected String getJSMainModuleName() { 41 | return "index"; 42 | } 43 | 44 | @Override 45 | protected boolean isNewArchEnabled() { 46 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 47 | } 48 | 49 | @Override 50 | protected Boolean isHermesEnabled() { 51 | return BuildConfig.IS_HERMES_ENABLED; 52 | } 53 | }; 54 | 55 | @Override 56 | public ReactNativeHost getReactNativeHost() { 57 | return mReactNativeHost; 58 | } 59 | 60 | @Override 61 | public void onCreate() { 62 | super.onCreate(); 63 | SoLoader.init(this, /* native exopackage */ false); 64 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 65 | // If you opted-in for the New Architecture, we load the native entry point for this app. 66 | DefaultNewArchitectureEntryPoint.load(); 67 | } 68 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/screens/receiveCall/index.tsx: -------------------------------------------------------------------------------- 1 | import {useContext} from 'react'; 2 | import {View, StyleSheet, Text} from 'react-native'; 3 | 4 | import {Avatar, IconButton} from 'react-native-paper'; 5 | import {useNavigate} from 'react-router-native'; 6 | 7 | import { 8 | COLOR_ONLINE_GREEN, 9 | COLOR_RED, 10 | COLOR_WHITE, 11 | } from '../../shared/constants/colors'; 12 | import {FriendsContext} from '../../shared/friends/contexts/friends.context'; 13 | import {CallDetails, CallResponse} from '../../shared/friends/models'; 14 | 15 | const ReceiveCallScreen = () => { 16 | const {friends, callDetails, respondToCall} = useContext(FriendsContext); 17 | 18 | const navigate = useNavigate(); 19 | 20 | const foundFriend = friends.find(f => f.id === callDetails?.friendId); 21 | 22 | return ( 23 | 24 | 32 | 33 | {foundFriend?.firstName} {foundFriend?.lastName} 34 | 35 | Video calling on Messenger... 36 | 37 | { 43 | respondToCall(CallResponse.Declined); 44 | navigate('/'); 45 | }} 46 | accessibilityLabelledBy={undefined} 47 | accessibilityLanguage={undefined} 48 | /> 49 | { 55 | respondToCall(CallResponse.Accepted); 56 | navigate(`/call/${callDetails!.meetingId}`); 57 | }} 58 | accessibilityLabelledBy={undefined} 59 | accessibilityLanguage={undefined} 60 | /> 61 | 62 | 63 | ); 64 | }; 65 | 66 | const styles = StyleSheet.create({ 67 | container: { 68 | flex: 1, 69 | justifyContent: 'center', 70 | alignItems: 'center', 71 | }, 72 | nameText: { 73 | fontSize: 40, 74 | fontWeight: '500', 75 | }, 76 | responseToCallContainer: { 77 | flexDirection: 'row', 78 | justifyContent: 'space-around', 79 | alignItems: 'flex-end', 80 | width: '100%', 81 | padding: 32, 82 | }, 83 | }); 84 | 85 | export default ReceiveCallScreen; 86 | -------------------------------------------------------------------------------- /src/screens/index.tsx: -------------------------------------------------------------------------------- 1 | import {useContext, useState} from 'react'; 2 | import {View} from 'react-native'; 3 | 4 | import {NativeRouter, Route, Routes} from 'react-router-native'; 5 | import {BottomNavigation as NavScreens, Text} from 'react-native-paper'; 6 | 7 | import {AuthContext} from '../shared/auth/contexts/auth.context'; 8 | import {FriendsContext} from '../shared/friends/contexts/friends.context'; 9 | import {navRoutes} from '../shared/constants/navRoutes'; 10 | import {CallActivity} from '../shared/friends/models'; 11 | import ChatsScreen from './chats'; 12 | import RegisterScreen from './register'; 13 | import LoginScreen from './login'; 14 | import ChatScreen from './chat'; 15 | import PeopleScreen from './people'; 16 | import CallScreen from './call'; 17 | import ReceiveCallScreen from './receiveCall'; 18 | 19 | const Screens = () => { 20 | const {isLoggedIn} = useContext(AuthContext); 21 | const {callActivity} = useContext(FriendsContext); 22 | 23 | const [index, setIndex] = useState(0); 24 | const [routes] = useState(navRoutes); 25 | 26 | const isReceivingCall = callActivity === CallActivity.Receiving; 27 | 28 | const inCall = [CallActivity.Accepted, CallActivity.Requesting].includes( 29 | callActivity, 30 | ); 31 | 32 | const renderScene = NavScreens.SceneMap({ 33 | chats: () => , 34 | calls: () => Calls, 35 | people: () => , 36 | stories: () => Stories, 37 | }); 38 | 39 | const renderNavScreensRoute = () => { 40 | const paths = ['/', '/login']; 41 | 42 | return paths.map(path => ( 43 | 48 | 53 | 54 | } 55 | /> 56 | )); 57 | }; 58 | 59 | return ( 60 | 61 | {isLoggedIn ? ( 62 | 63 | {(!inCall || !isReceivingCall) && renderNavScreensRoute()} 64 | 65 | {} />} 66 | 67 | } /> 68 | 69 | } /> 70 | 71 | ) : ( 72 | 73 | } /> 74 | } /> 75 | } /> 76 | 77 | )} 78 | 79 | ); 80 | }; 81 | 82 | export default Screens; 83 | -------------------------------------------------------------------------------- /ios/FacebookMessenger/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSCameraUsageDescription 6 | Camera permission description 7 | NSMicrophoneUsageDescription 8 | Microphone permission description 9 | CFBundleDevelopmentRegion 10 | en 11 | CFBundleDisplayName 12 | FacebookMessenger 13 | CFBundleExecutable 14 | $(EXECUTABLE_NAME) 15 | CFBundleIdentifier 16 | $(PRODUCT_BUNDLE_IDENTIFIER) 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | $(PRODUCT_NAME) 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | $(MARKETING_VERSION) 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | $(CURRENT_PROJECT_VERSION) 29 | LSRequiresIPhoneOS 30 | 31 | NSAppTransportSecurity 32 | 33 | NSExceptionDomains 34 | 35 | localhost 36 | 37 | NSExceptionAllowsInsecureHTTPLoads 38 | 39 | 40 | 41 | 42 | NSLocationWhenInUseUsageDescription 43 | 44 | UIAppFonts 45 | 46 | AntDesign.ttf 47 | Entypo.ttf 48 | EvilIcons.ttf 49 | Feather.ttf 50 | FontAwesome.ttf 51 | FontAwesome5_Brands.ttf 52 | FontAwesome5_Regular.ttf 53 | FontAwesome5_Solid.ttf 54 | Foundation.ttf 55 | Ionicons.ttf 56 | MaterialIcons.ttf 57 | MaterialCommunityIcons.ttf 58 | SimpleLineIcons.ttf 59 | Octicons.ttf 60 | Zocial.ttf 61 | 62 | UIBackgroundModes 63 | 64 | remote-notification 65 | 66 | UILaunchStoryboardName 67 | LaunchScreen 68 | UIRequiredDeviceCapabilities 69 | 70 | armv7 71 | 72 | UISupportedInterfaceOrientations 73 | 74 | UIInterfaceOrientationPortrait 75 | UIInterfaceOrientationLandscapeLeft 76 | UIInterfaceOrientationLandscapeRight 77 | 78 | UIViewControllerBasedStatusBarAppearance 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/screens/login/index.tsx: -------------------------------------------------------------------------------- 1 | import {useContext, useState} from 'react'; 2 | import {View, StyleSheet, Text} from 'react-native'; 3 | 4 | import {Button} from 'react-native-paper'; 5 | import {useNavigate} from 'react-router-native'; 6 | 7 | import {AuthContext} from '../../shared/auth/contexts/auth.context'; 8 | import { 9 | COLOR_FB_PRIMARY, 10 | COLOR_FB_SECONDARY, 11 | COLOR_WHITE, 12 | } from '../../shared/constants/colors'; 13 | import Input from '../../shared/components/Input'; 14 | import Loader from '../../shared/components/Loader'; 15 | 16 | const LoginScreen = () => { 17 | const {isLoggingIn, onLogin} = useContext(AuthContext); 18 | 19 | const navigate = useNavigate(); 20 | 21 | const [email, setEmail] = useState(''); 22 | const [password, setPassword] = useState(''); 23 | 24 | const resetForm = () => { 25 | setEmail(''); 26 | setPassword(''); 27 | }; 28 | 29 | return ( 30 | 31 | 32 | facebook 33 | 34 | 35 | 36 | 42 | 43 | 44 | {isLoggingIn ? ( 45 | 46 | ) : ( 47 | 57 | )} 58 | 59 | 60 | 61 | 66 | 67 | ); 68 | }; 69 | 70 | const styles = StyleSheet.create({ 71 | container: { 72 | flex: 1, 73 | padding: 24, 74 | backgroundColor: COLOR_FB_PRIMARY, 75 | alignItems: 'center', 76 | justifyContent: 'space-around', 77 | }, 78 | formContainer: { 79 | width: '100%', 80 | alignItems: 'center', 81 | }, 82 | facebookText: { 83 | fontSize: 56, 84 | fontWeight: '700', 85 | color: COLOR_WHITE, 86 | marginBottom: 32, 87 | }, 88 | loginButtonContainer: { 89 | marginTop: 16, 90 | width: '100%', 91 | }, 92 | loginButton: { 93 | backgroundColor: COLOR_FB_SECONDARY, 94 | height: 48, 95 | borderRadius: 0, 96 | }, 97 | loginButtonText: { 98 | paddingTop: 8, 99 | fontSize: 24, 100 | }, 101 | signUpText: { 102 | color: COLOR_WHITE, 103 | fontSize: 16, 104 | }, 105 | }); 106 | 107 | export default LoginScreen; 108 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /ios/FacebookMessenger/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import "AppDelegate.h" 5 | 6 | #import 7 | 8 | @implementation AppDelegate 9 | 10 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 11 | { 12 | 13 | UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; 14 | center.delegate = self; 15 | 16 | self.moduleName = @"FacebookMessenger"; 17 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 18 | } 19 | 20 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 21 | { 22 | #if DEBUG 23 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 24 | #else 25 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 26 | #endif 27 | } 28 | 29 | // Required for the register event. 30 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 31 | { 32 | [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; 33 | } 34 | // Required for the notification event. You must call the completion handler after handling the remote notification. 35 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 36 | fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 37 | { 38 | [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; 39 | } 40 | // Required for the registrationError event. 41 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 42 | { 43 | [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; 44 | } 45 | // Required for localNotification event 46 | - (void)userNotificationCenter:(UNUserNotificationCenter *)center 47 | didReceiveNotificationResponse:(UNNotificationResponse *)response 48 | withCompletionHandler:(void (^)(void))completionHandler 49 | { 50 | [RNCPushNotificationIOS didReceiveNotificationResponse:response]; 51 | } 52 | 53 | //Called when a notification is delivered to a foreground app. 54 | -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler 55 | { 56 | completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge); 57 | } 58 | 59 | /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. 60 | /// 61 | /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html 62 | /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). 63 | /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`. 64 | - (BOOL)concurrentRootEnabled 65 | { 66 | return true; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /src/shared/auth/contexts/auth.context.tsx: -------------------------------------------------------------------------------- 1 | import {createContext, useState, ReactNode, useRef, useEffect} from 'react'; 2 | import {AppState} from 'react-native'; 3 | 4 | import {useMutation} from 'react-query'; 5 | import AsyncStorage from '@react-native-async-storage/async-storage'; 6 | 7 | import {Credentials, LoginUser, UserDetails} from '../models'; 8 | import {login} from '../requests'; 9 | 10 | export interface IAuthContext { 11 | userDetails?: UserDetails; 12 | jwt?: string; 13 | isLoggedIn: boolean; 14 | isLoggingIn: boolean; 15 | isActive: boolean; 16 | onLogin: (loginUser: LoginUser) => void; 17 | onLogout: () => void; 18 | } 19 | 20 | export const AuthContext = createContext({ 21 | userDetails: undefined, 22 | jwt: undefined, 23 | isLoggedIn: false, 24 | isLoggingIn: false, 25 | isActive: false, 26 | onLogin: () => null, 27 | onLogout: () => null, 28 | }); 29 | 30 | export const AuthProvider = ({children}: {children: ReactNode}) => { 31 | const [userDetails, setUserDetails] = useState(); 32 | const [jwt, setJwt] = useState(); 33 | const [isLoggedIn, setIsLoggedIn] = useState(false); 34 | const [isLoggingIn, setIsLoggingIn] = useState(false); 35 | 36 | const appState = useRef(AppState.currentState); 37 | const [appStateVisible, setAppStateVisible] = useState(appState.current); 38 | 39 | useEffect(() => { 40 | const subscription = AppState.addEventListener('change', nextAppState => { 41 | appState.current = nextAppState; 42 | setAppStateVisible(appState.current); 43 | }); 44 | 45 | return () => { 46 | subscription.remove(); 47 | }; 48 | }, []); 49 | 50 | const loginMutation = useMutation( 51 | (loginUser: LoginUser) => login(loginUser), 52 | { 53 | onSuccess: credentials => { 54 | setUserDetails(credentials.user); 55 | setJwt(credentials.token); 56 | setIsLoggedIn(true); 57 | _storeCredentials(credentials); 58 | }, 59 | 60 | onSettled: () => { 61 | setIsLoggingIn(false); 62 | }, 63 | }, 64 | ); 65 | 66 | const _storeCredentials = async (credentials: Credentials) => { 67 | try { 68 | await AsyncStorage.setItem('credentials', JSON.stringify(credentials)); 69 | } catch (error) { 70 | console.log(error); 71 | } 72 | }; 73 | 74 | const loginHandler = (loginUser: LoginUser) => { 75 | setIsLoggingIn(true); 76 | loginMutation.mutate(loginUser); 77 | }; 78 | 79 | const logoutHandler = () => { 80 | setUserDetails(undefined); 81 | setJwt(undefined); 82 | setIsLoggedIn(false); 83 | }; 84 | 85 | return ( 86 | 96 | {children} 97 | 98 | ); 99 | }; 100 | -------------------------------------------------------------------------------- /android/app/src/debug/java/com/facebookmessenger/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.facebookmessenger; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 21 | import com.facebook.react.ReactInstanceEventListener; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | /** 28 | * Class responsible of loading Flipper inside your React Native application. This is the debug 29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup. 30 | */ 31 | public class ReactNativeFlipper { 32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 33 | if (FlipperUtils.shouldEnableFlipper(context)) { 34 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 35 | 36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 37 | client.addPlugin(new DatabasesFlipperPlugin(context)); 38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 39 | client.addPlugin(CrashReporterPlugin.getInstance()); 40 | 41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 42 | NetworkingModule.setCustomClientBuilder( 43 | new NetworkingModule.CustomClientBuilder() { 44 | @Override 45 | public void apply(OkHttpClient.Builder builder) { 46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 47 | } 48 | }); 49 | client.addPlugin(networkFlipperPlugin); 50 | client.start(); 51 | 52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 53 | // Hence we run if after all native modules have been initialized 54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 55 | if (reactContext == null) { 56 | reactInstanceManager.addReactInstanceEventListener( 57 | new ReactInstanceEventListener() { 58 | @Override 59 | public void onReactContextInitialized(ReactContext reactContext) { 60 | reactInstanceManager.removeReactInstanceEventListener(this); 61 | reactContext.runOnNativeModulesQueueThread( 62 | new Runnable() { 63 | @Override 64 | public void run() { 65 | client.addPlugin(new FrescoFlipperPlugin()); 66 | } 67 | }); 68 | } 69 | }); 70 | } else { 71 | client.addPlugin(new FrescoFlipperPlugin()); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /ios/FacebookMessenger.xcodeproj/xcshareddata/xcschemes/FacebookMessenger.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/screens/register/index.tsx: -------------------------------------------------------------------------------- 1 | import {useState} from 'react'; 2 | import {View, StyleSheet, Text} from 'react-native'; 3 | 4 | import {useMutation} from 'react-query'; 5 | import {useNavigate} from 'react-router-native'; 6 | import {Button} from 'react-native-paper'; 7 | 8 | import {register} from '../../shared/auth/requests'; 9 | import { 10 | COLOR_FB_PRIMARY, 11 | COLOR_FB_SECONDARY, 12 | COLOR_WHITE, 13 | } from '../../shared/constants/colors'; 14 | import {NewUser} from '../../shared/auth/models'; 15 | import Input from '../../shared/components/Input'; 16 | import Loader from '../../shared/components/Loader'; 17 | 18 | const RegisterScreen = () => { 19 | const registerMutation = useMutation( 20 | (newUser: NewUser) => register(newUser), 21 | { 22 | onSuccess: () => { 23 | resetForm(); 24 | navigate('/login'); 25 | }, 26 | }, 27 | ); 28 | 29 | const navigate = useNavigate(); 30 | 31 | const [firstName, setFirstName] = useState(''); 32 | const [lastName, setLastName] = useState(''); 33 | const [email, setEmail] = useState(''); 34 | const [password, setPassword] = useState(''); 35 | 36 | const resetForm = () => { 37 | setFirstName(''); 38 | setLastName(''); 39 | setEmail(''); 40 | setPassword(''); 41 | }; 42 | 43 | const registerHandler = () => { 44 | if (!firstName || !lastName || !email || !password) return; 45 | 46 | registerMutation.mutate({firstName, lastName, email, password}); 47 | }; 48 | 49 | return ( 50 | 51 | 52 | facebook 53 | 54 | 59 | 60 | 65 | 66 | 67 | 68 | 74 | 75 | 76 | {registerMutation.isLoading ? ( 77 | 78 | ) : ( 79 | 86 | )} 87 | 88 | 89 | 90 | 93 | 94 | ); 95 | }; 96 | 97 | const styles = StyleSheet.create({ 98 | container: { 99 | flex: 1, 100 | padding: 24, 101 | backgroundColor: COLOR_FB_PRIMARY, 102 | alignItems: 'center', 103 | justifyContent: 'space-around', 104 | }, 105 | formContainer: { 106 | width: '100%', 107 | alignItems: 'center', 108 | }, 109 | facebookText: { 110 | fontSize: 56, 111 | fontWeight: '700', 112 | color: COLOR_WHITE, 113 | marginBottom: 32, 114 | }, 115 | registerButtonContainer: { 116 | marginTop: 16, 117 | width: '100%', 118 | }, 119 | registerButton: { 120 | backgroundColor: COLOR_FB_SECONDARY, 121 | height: 48, 122 | borderRadius: 0, 123 | }, 124 | registerButtonText: { 125 | paddingTop: 8, 126 | fontSize: 24, 127 | }, 128 | signUpText: { 129 | color: COLOR_WHITE, 130 | fontSize: 16, 131 | }, 132 | }); 133 | 134 | export default RegisterScreen; 135 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 30 | 31 | 32 | 34 | 35 | 37 | 38 | 42 | 46 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /ios/FacebookMessenger/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/screens/chat/index.tsx: -------------------------------------------------------------------------------- 1 | import {useContext, useState} from 'react'; 2 | import {ScrollView, StyleSheet, Text, View} from 'react-native'; 3 | 4 | import {Appbar, Avatar, IconButton} from 'react-native-paper'; 5 | import {useNavigate, useParams} from 'react-router-native'; 6 | 7 | import {AuthContext} from '../../shared/auth/contexts/auth.context'; 8 | import Input from '../../shared/components/Input'; 9 | import { 10 | COLOR_BLACK, 11 | COLOR_FB_PRIMARY, 12 | COLOR_LIGHT_GRAY, 13 | COLOR_WHITE, 14 | } from '../../shared/constants/colors'; 15 | import {FriendsContext} from '../../shared/friends/contexts/friends.context'; 16 | import {CallActivity} from '../../shared/friends/models'; 17 | import {createMeeting} from '../call/requests'; 18 | 19 | const ChatScreen = () => { 20 | const {userDetails} = useContext(AuthContext); 21 | const { 22 | messages, 23 | conversations, 24 | friend, 25 | sendMessage, 26 | setCallActivity, 27 | setCallDetails, 28 | startCall, 29 | } = useContext(FriendsContext); 30 | const {friendId} = useParams(); 31 | const navigate = useNavigate(); 32 | const [text, setText] = useState(''); 33 | 34 | const conversationId = conversations.find(conversation => 35 | conversation.userIds.includes(+(friendId ?? -1)), 36 | )?.id; 37 | 38 | const conversationMessages = [...messages].filter( 39 | message => message.conversationId === conversationId, 40 | ); 41 | 42 | return ( 43 | 44 | 45 | navigate('/')} /> 46 | 47 | 53 | 54 | 55 | 56 | {friend.firstName} {friend.lastName} 57 | 58 | {friend.isActive ? 'Active Now' : 'Active a moment ago'} 59 | 60 | 61 | 68 | console.log('Call')} 74 | accessibilityLabelledBy={undefined} 75 | accessibilityLanguage={undefined} 76 | /> 77 | { 83 | setCallActivity(CallActivity.Requesting); 84 | const meetingId = await createMeeting().catch(e => 85 | console.log(e), 86 | ); 87 | if (!meetingId) return; 88 | const details = {meetingId, friendId: friend.id}; 89 | setCallDetails(details); 90 | startCall(details); 91 | navigate(`/call/${meetingId}`); 92 | }} 93 | accessibilityLabelledBy={undefined} 94 | accessibilityLanguage={undefined} 95 | /> 96 | 97 | 98 | 99 | 100 | {conversationMessages.map((message, i) => ( 101 | 110 | 117 | {message.message} 118 | 119 | 120 | ))} 121 | 122 | 123 | 124 | 132 | 133 | 139 | 140 | { 146 | if (!text || !conversationId) return; 147 | sendMessage(text, conversationId); 148 | setText(() => ''); 149 | }} 150 | accessibilityLabelledBy={undefined} 151 | accessibilityLanguage={undefined} 152 | /> 153 | 154 | 155 | ); 156 | }; 157 | 158 | const styles = StyleSheet.create({ 159 | container: { 160 | flex: 1, 161 | }, 162 | chatContainer: { 163 | flex: 1, 164 | padding: 16, 165 | }, 166 | inputContainer: { 167 | flexDirection: 'row', 168 | alignItems: 'center', 169 | padding: 4, 170 | }, 171 | message: { 172 | borderRadius: 16, 173 | paddingVertical: 8, 174 | paddingHorizontal: 16, 175 | marginBottom: 8, 176 | }, 177 | userMessage: { 178 | backgroundColor: COLOR_LIGHT_GRAY, 179 | alignSelf: 'flex-start', 180 | }, 181 | friendMessage: { 182 | backgroundColor: COLOR_FB_PRIMARY, 183 | alignSelf: 'flex-end', 184 | }, 185 | }); 186 | 187 | export default ChatScreen; 188 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "com.facebook.react" 3 | apply from: "../../node_modules/react-native-vector-icons/fonts.gradle" 4 | 5 | import com.android.build.OutputFile 6 | 7 | /** 8 | * This is the configuration block to customize your React Native Android app. 9 | * By default you don't need to apply any configuration, just uncomment the lines you need. 10 | */ 11 | react { 12 | /* Folders */ 13 | // The root of your project, i.e. where "package.json" lives. Default is '..' 14 | // root = file("../") 15 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 16 | // reactNativeDir = file("../node-modules/react-native") 17 | // The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen 18 | // codegenDir = file("../node-modules/react-native-codegen") 19 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 20 | // cliFile = file("../node_modules/react-native/cli.js") 21 | 22 | /* Variants */ 23 | // The list of variants to that are debuggable. For those we're going to 24 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 25 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 26 | // debuggableVariants = ["liteDebug", "prodDebug"] 27 | 28 | /* Bundling */ 29 | // A list containing the node command and its flags. Default is just 'node'. 30 | // nodeExecutableAndArgs = ["node"] 31 | // 32 | // The command to run when bundling. By default is 'bundle' 33 | // bundleCommand = "ram-bundle" 34 | // 35 | // The path to the CLI configuration file. Default is empty. 36 | // bundleConfig = file(../rn-cli.config.js) 37 | // 38 | // The name of the generated asset file containing your JS bundle 39 | // bundleAssetName = "MyApplication.android.bundle" 40 | // 41 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 42 | // entryFile = file("../js/MyApplication.android.js") 43 | // 44 | // A list of extra flags to pass to the 'bundle' commands. 45 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 46 | // extraPackagerArgs = [] 47 | 48 | /* Hermes Commands */ 49 | // The hermes compiler command to run. By default it is 'hermesc' 50 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 51 | // 52 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 53 | // hermesFlags = ["-O", "-output-source-map"] 54 | } 55 | 56 | /** 57 | * Set this to true to create four separate APKs instead of one, 58 | * one for each native architecture. This is useful if you don't 59 | * use App Bundles (https://developer.android.com/guide/app-bundle/) 60 | * and want to have separate APKs to upload to the Play Store. 61 | */ 62 | def enableSeparateBuildPerCPUArchitecture = false 63 | 64 | /** 65 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 66 | */ 67 | def enableProguardInReleaseBuilds = false 68 | 69 | /** 70 | * The preferred build flavor of JavaScriptCore (JSC) 71 | * 72 | * For example, to use the international variant, you can use: 73 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 74 | * 75 | * The international variant includes ICU i18n library and necessary data 76 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 77 | * give correct results when using with locales other than en-US. Note that 78 | * this variant is about 6MiB larger per architecture than default. 79 | */ 80 | def jscFlavor = 'org.webkit:android-jsc:+' 81 | 82 | /** 83 | * Private function to get the list of Native Architectures you want to build. 84 | * This reads the value from reactNativeArchitectures in your gradle.properties 85 | * file and works together with the --active-arch-only flag of react-native run-android. 86 | */ 87 | def reactNativeArchitectures() { 88 | def value = project.getProperties().get("reactNativeArchitectures") 89 | return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] 90 | } 91 | 92 | android { 93 | ndkVersion rootProject.ext.ndkVersion 94 | 95 | compileSdkVersion rootProject.ext.compileSdkVersion 96 | 97 | namespace "com.facebookmessenger" 98 | defaultConfig { 99 | applicationId "com.facebookmessenger" 100 | minSdkVersion rootProject.ext.minSdkVersion 101 | targetSdkVersion rootProject.ext.targetSdkVersion 102 | versionCode 1 103 | versionName "1.0" 104 | } 105 | 106 | splits { 107 | abi { 108 | reset() 109 | enable enableSeparateBuildPerCPUArchitecture 110 | universalApk false // If true, also generate a universal APK 111 | include (*reactNativeArchitectures()) 112 | } 113 | } 114 | signingConfigs { 115 | debug { 116 | storeFile file('debug.keystore') 117 | storePassword 'android' 118 | keyAlias 'androiddebugkey' 119 | keyPassword 'android' 120 | } 121 | } 122 | buildTypes { 123 | debug { 124 | signingConfig signingConfigs.debug 125 | } 126 | release { 127 | // Caution! In production, you need to generate your own keystore file. 128 | // see https://reactnative.dev/docs/signed-apk-android. 129 | signingConfig signingConfigs.debug 130 | minifyEnabled enableProguardInReleaseBuilds 131 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 132 | } 133 | } 134 | 135 | // applicationVariants are e.g. debug, release 136 | applicationVariants.all { variant -> 137 | variant.outputs.each { output -> 138 | // For each separate APK per architecture, set a unique version code as described here: 139 | // https://developer.android.com/studio/build/configure-apk-splits.html 140 | // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc. 141 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] 142 | def abi = output.getFilter(OutputFile.ABI) 143 | if (abi != null) { // null for the universal-debug, universal-release variants 144 | output.versionCodeOverride = 145 | defaultConfig.versionCode * 1000 + versionCodes.get(abi) 146 | } 147 | 148 | } 149 | } 150 | } 151 | 152 | dependencies { 153 | // The version of react-native is set by the React Native Gradle Plugin 154 | implementation("com.facebook.react:react-android") 155 | 156 | implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0") 157 | 158 | implementation project(':rnfgservice') 159 | implementation project(':rnwebrtc') 160 | implementation project(':rnincallmanager') 161 | 162 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") 163 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 164 | exclude group:'com.squareup.okhttp3', module:'okhttp' 165 | } 166 | 167 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") 168 | if (hermesEnabled.toBoolean()) { 169 | implementation("com.facebook.react:hermes-android") 170 | } else { 171 | implementation jscFlavor 172 | } 173 | } 174 | 175 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 176 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /src/shared/friends/contexts/friends.context.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | createContext, 3 | useState, 4 | ReactNode, 5 | useEffect, 6 | useContext, 7 | useMemo, 8 | } from 'react'; 9 | import {Platform} from 'react-native'; 10 | 11 | import {useQuery} from 'react-query'; 12 | import {useParams} from 'react-router-native'; 13 | import SocketIOClient from 'socket.io-client'; 14 | import PushNotification from 'react-native-push-notification'; 15 | import PushNotificationIOS from '@react-native-community/push-notification-ios'; 16 | import BackgroundTimer from 'react-native-background-timer'; 17 | 18 | import {IP_ADDRESS} from '@env'; 19 | 20 | import getFriends from '../helpers/friends'; 21 | import {getFriendRequests} from '../../../screens/people/requests'; 22 | import {AuthContext} from '../../auth/contexts/auth.context'; 23 | import {UserDetails} from '../../auth/models'; 24 | import { 25 | ActiveFriend, 26 | CallActivity, 27 | CallDetails, 28 | CallResponse, 29 | ICallResponse, 30 | } from '../models'; 31 | import {Conversation} from '../../../screens/chat/models/Conversation'; 32 | import {Message} from '../../../screens/chat/models/Message'; 33 | 34 | export interface IFriendsContext { 35 | friends: ActiveFriend[]; 36 | friend: ActiveFriend; 37 | isLoading: boolean; 38 | conversations: Conversation[]; 39 | messages: Message[]; 40 | callDetails: CallDetails | null; 41 | callActivity: CallActivity; 42 | sendMessage: (text: string, conversationId: number) => void; 43 | setFriend: (friend: ActiveFriend) => void; 44 | setCallDetails: (callDetails: CallDetails | null) => void; 45 | setCallActivity: (callActivity: CallActivity) => void; 46 | startCall: (details: CallDetails) => void; 47 | respondToCall: (response: CallResponse) => void; 48 | } 49 | 50 | export const FriendsContext = createContext({ 51 | friends: [], 52 | friend: {} as ActiveFriend, 53 | isLoading: false, 54 | conversations: [], 55 | messages: [], 56 | callDetails: null, 57 | callActivity: CallActivity.None, 58 | sendMessage: () => null, 59 | setFriend: () => null, 60 | setCallDetails: () => null, 61 | setCallActivity: () => null, 62 | startCall: () => null, 63 | respondToCall: () => null, 64 | }); 65 | 66 | export const FriendsProvider = ({children}: {children: ReactNode}) => { 67 | const {isActive, jwt, isLoggedIn, userDetails} = useContext(AuthContext); 68 | const {friendId} = useParams(); 69 | 70 | const [friends, setFriends] = useState([]); 71 | const [friend, setFriend] = useState({} as ActiveFriend); 72 | const [isLoading, setIsLoading] = useState(false); 73 | const [conversations, setConversations] = useState([]); 74 | const [messages, setMessages] = useState([]); 75 | const [callDetails, setCallDetails] = useState(null); 76 | const [callActivity, setCallActivity] = useState( 77 | CallActivity.None, 78 | ); 79 | 80 | const chatBaseUrl = `http://${IP_ADDRESS ?? '10.0.2.2'}:7000`; 81 | 82 | const chatSocket = useMemo( 83 | () => 84 | SocketIOClient(chatBaseUrl, { 85 | transportOptions: { 86 | polling: { 87 | extraHeaders: { 88 | Authorization: jwt, 89 | }, 90 | }, 91 | }, 92 | }), 93 | [jwt, chatBaseUrl], 94 | ); 95 | 96 | useEffect(() => { 97 | if (conversations.length > 0) return; 98 | 99 | chatSocket.on('getAllConversations', (allConversations: Conversation[]) => { 100 | setConversations(() => allConversations); 101 | }); 102 | 103 | return () => { 104 | chatSocket.off('getAllConversations'); 105 | }; 106 | }, [chatSocket, conversations]); 107 | 108 | const startCall = (details: CallDetails) => { 109 | chatSocket.emit('startCall', details); 110 | }; 111 | 112 | useEffect(() => { 113 | chatSocket.on('newMessage', (message: Message) => { 114 | setMessages(prevMessages => [...prevMessages, message]); 115 | 116 | if (Platform.OS === 'android') { 117 | PushNotification.createChannel( 118 | { 119 | channelId: '1', 120 | channelName: 'name', 121 | }, 122 | created => console.log(`createChannel returned '${created}'`), 123 | ); 124 | 125 | PushNotification.localNotification({ 126 | title: 'NEW Message - ANDROID', 127 | message: message.message, 128 | channelId: '1', 129 | }); 130 | } else if (Platform.OS === 'ios') { 131 | PushNotificationIOS.addNotificationRequest({ 132 | id: '1', 133 | title: 'NEW Message - IOS', 134 | body: message.message, 135 | }); 136 | } 137 | }); 138 | 139 | chatSocket.on('receiveCall', (friendsCallDetails: CallDetails) => { 140 | setCallDetails(friendsCallDetails); 141 | setCallActivity(CallActivity.Receiving); 142 | }); 143 | 144 | chatSocket.on('callResponse', (callResponse: ICallResponse) => { 145 | const hasFriendAccepted = callResponse.status === CallResponse.Accepted; 146 | 147 | setCallActivity( 148 | hasFriendAccepted ? CallActivity.Accepted : CallActivity.None, 149 | ); 150 | }); 151 | 152 | return () => { 153 | chatSocket.off('newMessage'); 154 | chatSocket.off('receiveCall'); 155 | chatSocket.off('callResponse'); 156 | }; 157 | }, [chatSocket, friends]); 158 | 159 | useEffect(() => { 160 | if (!isLoggedIn || isActive) return; 161 | 162 | BackgroundTimer.runBackgroundTimer(() => { 163 | // ping server to keep ws alive in background 164 | chatSocket.emit('ping'); 165 | }, 3000); 166 | 167 | return () => { 168 | BackgroundTimer.stopBackgroundTimer(); 169 | }; 170 | }, [chatSocket, isActive, isLoggedIn]); 171 | 172 | useQuery( 173 | 'friendRequests', 174 | async () => { 175 | setIsLoading(true); 176 | 177 | const friendRequests = await getFriendRequests(); 178 | 179 | const _friends = getFriends( 180 | friendRequests, 181 | (userDetails as UserDetails).id, 182 | ); 183 | 184 | const activeFriends: ActiveFriend[] = _friends.map(f => ({ 185 | ...f, 186 | isActive: false, 187 | })); 188 | 189 | setFriends(activeFriends); 190 | 191 | return _friends; 192 | }, 193 | { 194 | enabled: isLoggedIn, 195 | onSettled: () => { 196 | setIsLoading(false); 197 | }, 198 | }, 199 | ); 200 | 201 | const presenceBaseUrl = `http://${IP_ADDRESS ?? '10.0.2.2'}:6000`; 202 | 203 | const presenceSocket = useMemo( 204 | () => 205 | SocketIOClient(presenceBaseUrl, { 206 | transportOptions: { 207 | polling: { 208 | extraHeaders: { 209 | Authorization: jwt, 210 | }, 211 | }, 212 | }, 213 | }), 214 | [jwt, presenceBaseUrl], 215 | ); 216 | 217 | useEffect(() => { 218 | presenceSocket.emit('updateActiveStatus', isActive); 219 | 220 | presenceSocket.on( 221 | 'friendActive', 222 | ({id, isActive: isFriendActive}: {id: number; isActive: boolean}) => { 223 | setFriends(prevFriends => { 224 | if (userDetails?.id === id) return prevFriends; 225 | 226 | const updatedFriends = [...prevFriends]; 227 | const activeFriend = updatedFriends.find(f => f.id === id); 228 | 229 | if (!activeFriend) return prevFriends; 230 | 231 | activeFriend.isActive = isFriendActive; 232 | 233 | return updatedFriends; 234 | }); 235 | }, 236 | ); 237 | 238 | return () => { 239 | presenceSocket.emit('updateActiveStatus', false); 240 | presenceSocket.off('friendActive'); 241 | }; 242 | }, [presenceSocket, isActive, userDetails]); 243 | 244 | const sendMessageHandler = (text: string, conversationId: number) => { 245 | if (!userDetails) return; 246 | 247 | const newMessage: Message = { 248 | message: text, 249 | creatorId: userDetails.id, 250 | conversationId, 251 | }; 252 | 253 | setMessages(prevMessages => [...prevMessages, newMessage]); 254 | 255 | chatSocket.emit('sendMessage', { 256 | message: text, 257 | friendId, 258 | conversationId, 259 | }); 260 | }; 261 | 262 | const respondToCall = (response: CallResponse) => { 263 | if (!callDetails) return; 264 | 265 | if (response === CallResponse.Accepted) { 266 | chatSocket.emit('acceptCall', callDetails.friendId); 267 | } else { 268 | chatSocket.emit('declineCall', callDetails.friendId); 269 | } 270 | }; 271 | 272 | return ( 273 | 283 | sendMessageHandler(text, conversationId), 284 | setFriend, 285 | setCallDetails, 286 | setCallActivity, 287 | startCall, 288 | respondToCall, 289 | }}> 290 | {children} 291 | 292 | ); 293 | }; 294 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - boost (1.76.0) 3 | - CocoaAsyncSocket (7.6.5) 4 | - DoubleConversion (1.1.6) 5 | - FBLazyVector (0.71.0) 6 | - FBReactNativeSpec (0.71.0): 7 | - RCT-Folly (= 2021.07.22.00) 8 | - RCTRequired (= 0.71.0) 9 | - RCTTypeSafety (= 0.71.0) 10 | - React-Core (= 0.71.0) 11 | - React-jsi (= 0.71.0) 12 | - ReactCommon/turbomodule/core (= 0.71.0) 13 | - Flipper (0.125.0): 14 | - Flipper-Folly (~> 2.6) 15 | - Flipper-RSocket (~> 1.4) 16 | - Flipper-Boost-iOSX (1.76.0.1.11) 17 | - Flipper-DoubleConversion (3.2.0.1) 18 | - Flipper-Fmt (7.1.7) 19 | - Flipper-Folly (2.6.10): 20 | - Flipper-Boost-iOSX 21 | - Flipper-DoubleConversion 22 | - Flipper-Fmt (= 7.1.7) 23 | - Flipper-Glog 24 | - libevent (~> 2.1.12) 25 | - OpenSSL-Universal (= 1.1.1100) 26 | - Flipper-Glog (0.5.0.5) 27 | - Flipper-PeerTalk (0.0.4) 28 | - Flipper-RSocket (1.4.3): 29 | - Flipper-Folly (~> 2.6) 30 | - FlipperKit (0.125.0): 31 | - FlipperKit/Core (= 0.125.0) 32 | - FlipperKit/Core (0.125.0): 33 | - Flipper (~> 0.125.0) 34 | - FlipperKit/CppBridge 35 | - FlipperKit/FBCxxFollyDynamicConvert 36 | - FlipperKit/FBDefines 37 | - FlipperKit/FKPortForwarding 38 | - SocketRocket (~> 0.6.0) 39 | - FlipperKit/CppBridge (0.125.0): 40 | - Flipper (~> 0.125.0) 41 | - FlipperKit/FBCxxFollyDynamicConvert (0.125.0): 42 | - Flipper-Folly (~> 2.6) 43 | - FlipperKit/FBDefines (0.125.0) 44 | - FlipperKit/FKPortForwarding (0.125.0): 45 | - CocoaAsyncSocket (~> 7.6) 46 | - Flipper-PeerTalk (~> 0.0.4) 47 | - FlipperKit/FlipperKitHighlightOverlay (0.125.0) 48 | - FlipperKit/FlipperKitLayoutHelpers (0.125.0): 49 | - FlipperKit/Core 50 | - FlipperKit/FlipperKitHighlightOverlay 51 | - FlipperKit/FlipperKitLayoutTextSearchable 52 | - FlipperKit/FlipperKitLayoutIOSDescriptors (0.125.0): 53 | - FlipperKit/Core 54 | - FlipperKit/FlipperKitHighlightOverlay 55 | - FlipperKit/FlipperKitLayoutHelpers 56 | - YogaKit (~> 1.18) 57 | - FlipperKit/FlipperKitLayoutPlugin (0.125.0): 58 | - FlipperKit/Core 59 | - FlipperKit/FlipperKitHighlightOverlay 60 | - FlipperKit/FlipperKitLayoutHelpers 61 | - FlipperKit/FlipperKitLayoutIOSDescriptors 62 | - FlipperKit/FlipperKitLayoutTextSearchable 63 | - YogaKit (~> 1.18) 64 | - FlipperKit/FlipperKitLayoutTextSearchable (0.125.0) 65 | - FlipperKit/FlipperKitNetworkPlugin (0.125.0): 66 | - FlipperKit/Core 67 | - FlipperKit/FlipperKitReactPlugin (0.125.0): 68 | - FlipperKit/Core 69 | - FlipperKit/FlipperKitUserDefaultsPlugin (0.125.0): 70 | - FlipperKit/Core 71 | - FlipperKit/SKIOSNetworkPlugin (0.125.0): 72 | - FlipperKit/Core 73 | - FlipperKit/FlipperKitNetworkPlugin 74 | - fmt (6.2.1) 75 | - glog (0.3.5) 76 | - hermes-engine (0.71.0): 77 | - hermes-engine/Pre-built (= 0.71.0) 78 | - hermes-engine/Pre-built (0.71.0) 79 | - JitsiWebRTC (106.0.0) 80 | - libevent (2.1.12) 81 | - OpenSSL-Universal (1.1.1100) 82 | - RCT-Folly (2021.07.22.00): 83 | - boost 84 | - DoubleConversion 85 | - fmt (~> 6.2.1) 86 | - glog 87 | - RCT-Folly/Default (= 2021.07.22.00) 88 | - RCT-Folly/Default (2021.07.22.00): 89 | - boost 90 | - DoubleConversion 91 | - fmt (~> 6.2.1) 92 | - glog 93 | - RCT-Folly/Futures (2021.07.22.00): 94 | - boost 95 | - DoubleConversion 96 | - fmt (~> 6.2.1) 97 | - glog 98 | - libevent 99 | - RCTRequired (0.71.0) 100 | - RCTTypeSafety (0.71.0): 101 | - FBLazyVector (= 0.71.0) 102 | - RCTRequired (= 0.71.0) 103 | - React-Core (= 0.71.0) 104 | - React (0.71.0): 105 | - React-Core (= 0.71.0) 106 | - React-Core/DevSupport (= 0.71.0) 107 | - React-Core/RCTWebSocket (= 0.71.0) 108 | - React-RCTActionSheet (= 0.71.0) 109 | - React-RCTAnimation (= 0.71.0) 110 | - React-RCTBlob (= 0.71.0) 111 | - React-RCTImage (= 0.71.0) 112 | - React-RCTLinking (= 0.71.0) 113 | - React-RCTNetwork (= 0.71.0) 114 | - React-RCTSettings (= 0.71.0) 115 | - React-RCTText (= 0.71.0) 116 | - React-RCTVibration (= 0.71.0) 117 | - React-callinvoker (0.71.0) 118 | - React-Codegen (0.71.0): 119 | - FBReactNativeSpec 120 | - hermes-engine 121 | - RCT-Folly 122 | - RCTRequired 123 | - RCTTypeSafety 124 | - React-Core 125 | - React-jsi 126 | - React-jsiexecutor 127 | - ReactCommon/turbomodule/bridging 128 | - ReactCommon/turbomodule/core 129 | - React-Core (0.71.0): 130 | - glog 131 | - RCT-Folly (= 2021.07.22.00) 132 | - React-Core/Default (= 0.71.0) 133 | - React-cxxreact (= 0.71.0) 134 | - React-jsi (= 0.71.0) 135 | - React-jsiexecutor (= 0.71.0) 136 | - React-perflogger (= 0.71.0) 137 | - Yoga 138 | - React-Core/CoreModulesHeaders (0.71.0): 139 | - glog 140 | - RCT-Folly (= 2021.07.22.00) 141 | - React-Core/Default 142 | - React-cxxreact (= 0.71.0) 143 | - React-jsi (= 0.71.0) 144 | - React-jsiexecutor (= 0.71.0) 145 | - React-perflogger (= 0.71.0) 146 | - Yoga 147 | - React-Core/Default (0.71.0): 148 | - glog 149 | - RCT-Folly (= 2021.07.22.00) 150 | - React-cxxreact (= 0.71.0) 151 | - React-jsi (= 0.71.0) 152 | - React-jsiexecutor (= 0.71.0) 153 | - React-perflogger (= 0.71.0) 154 | - Yoga 155 | - React-Core/DevSupport (0.71.0): 156 | - glog 157 | - RCT-Folly (= 2021.07.22.00) 158 | - React-Core/Default (= 0.71.0) 159 | - React-Core/RCTWebSocket (= 0.71.0) 160 | - React-cxxreact (= 0.71.0) 161 | - React-jsi (= 0.71.0) 162 | - React-jsiexecutor (= 0.71.0) 163 | - React-jsinspector (= 0.71.0) 164 | - React-perflogger (= 0.71.0) 165 | - Yoga 166 | - React-Core/RCTActionSheetHeaders (0.71.0): 167 | - glog 168 | - RCT-Folly (= 2021.07.22.00) 169 | - React-Core/Default 170 | - React-cxxreact (= 0.71.0) 171 | - React-jsi (= 0.71.0) 172 | - React-jsiexecutor (= 0.71.0) 173 | - React-perflogger (= 0.71.0) 174 | - Yoga 175 | - React-Core/RCTAnimationHeaders (0.71.0): 176 | - glog 177 | - RCT-Folly (= 2021.07.22.00) 178 | - React-Core/Default 179 | - React-cxxreact (= 0.71.0) 180 | - React-jsi (= 0.71.0) 181 | - React-jsiexecutor (= 0.71.0) 182 | - React-perflogger (= 0.71.0) 183 | - Yoga 184 | - React-Core/RCTBlobHeaders (0.71.0): 185 | - glog 186 | - RCT-Folly (= 2021.07.22.00) 187 | - React-Core/Default 188 | - React-cxxreact (= 0.71.0) 189 | - React-jsi (= 0.71.0) 190 | - React-jsiexecutor (= 0.71.0) 191 | - React-perflogger (= 0.71.0) 192 | - Yoga 193 | - React-Core/RCTImageHeaders (0.71.0): 194 | - glog 195 | - RCT-Folly (= 2021.07.22.00) 196 | - React-Core/Default 197 | - React-cxxreact (= 0.71.0) 198 | - React-jsi (= 0.71.0) 199 | - React-jsiexecutor (= 0.71.0) 200 | - React-perflogger (= 0.71.0) 201 | - Yoga 202 | - React-Core/RCTLinkingHeaders (0.71.0): 203 | - glog 204 | - RCT-Folly (= 2021.07.22.00) 205 | - React-Core/Default 206 | - React-cxxreact (= 0.71.0) 207 | - React-jsi (= 0.71.0) 208 | - React-jsiexecutor (= 0.71.0) 209 | - React-perflogger (= 0.71.0) 210 | - Yoga 211 | - React-Core/RCTNetworkHeaders (0.71.0): 212 | - glog 213 | - RCT-Folly (= 2021.07.22.00) 214 | - React-Core/Default 215 | - React-cxxreact (= 0.71.0) 216 | - React-jsi (= 0.71.0) 217 | - React-jsiexecutor (= 0.71.0) 218 | - React-perflogger (= 0.71.0) 219 | - Yoga 220 | - React-Core/RCTSettingsHeaders (0.71.0): 221 | - glog 222 | - RCT-Folly (= 2021.07.22.00) 223 | - React-Core/Default 224 | - React-cxxreact (= 0.71.0) 225 | - React-jsi (= 0.71.0) 226 | - React-jsiexecutor (= 0.71.0) 227 | - React-perflogger (= 0.71.0) 228 | - Yoga 229 | - React-Core/RCTTextHeaders (0.71.0): 230 | - glog 231 | - RCT-Folly (= 2021.07.22.00) 232 | - React-Core/Default 233 | - React-cxxreact (= 0.71.0) 234 | - React-jsi (= 0.71.0) 235 | - React-jsiexecutor (= 0.71.0) 236 | - React-perflogger (= 0.71.0) 237 | - Yoga 238 | - React-Core/RCTVibrationHeaders (0.71.0): 239 | - glog 240 | - RCT-Folly (= 2021.07.22.00) 241 | - React-Core/Default 242 | - React-cxxreact (= 0.71.0) 243 | - React-jsi (= 0.71.0) 244 | - React-jsiexecutor (= 0.71.0) 245 | - React-perflogger (= 0.71.0) 246 | - Yoga 247 | - React-Core/RCTWebSocket (0.71.0): 248 | - glog 249 | - RCT-Folly (= 2021.07.22.00) 250 | - React-Core/Default (= 0.71.0) 251 | - React-cxxreact (= 0.71.0) 252 | - React-jsi (= 0.71.0) 253 | - React-jsiexecutor (= 0.71.0) 254 | - React-perflogger (= 0.71.0) 255 | - Yoga 256 | - React-CoreModules (0.71.0): 257 | - RCT-Folly (= 2021.07.22.00) 258 | - RCTTypeSafety (= 0.71.0) 259 | - React-Codegen (= 0.71.0) 260 | - React-Core/CoreModulesHeaders (= 0.71.0) 261 | - React-jsi (= 0.71.0) 262 | - React-RCTImage (= 0.71.0) 263 | - ReactCommon/turbomodule/core (= 0.71.0) 264 | - React-cxxreact (0.71.0): 265 | - boost (= 1.76.0) 266 | - DoubleConversion 267 | - glog 268 | - RCT-Folly (= 2021.07.22.00) 269 | - React-callinvoker (= 0.71.0) 270 | - React-jsi (= 0.71.0) 271 | - React-jsinspector (= 0.71.0) 272 | - React-logger (= 0.71.0) 273 | - React-perflogger (= 0.71.0) 274 | - React-runtimeexecutor (= 0.71.0) 275 | - React-hermes (0.71.0): 276 | - DoubleConversion 277 | - glog 278 | - hermes-engine 279 | - RCT-Folly (= 2021.07.22.00) 280 | - RCT-Folly/Futures (= 2021.07.22.00) 281 | - React-cxxreact (= 0.71.0) 282 | - React-jsiexecutor (= 0.71.0) 283 | - React-jsinspector (= 0.71.0) 284 | - React-perflogger (= 0.71.0) 285 | - React-jsi (0.71.0): 286 | - boost (= 1.76.0) 287 | - DoubleConversion 288 | - glog 289 | - hermes-engine 290 | - RCT-Folly (= 2021.07.22.00) 291 | - React-jsiexecutor (0.71.0): 292 | - DoubleConversion 293 | - glog 294 | - RCT-Folly (= 2021.07.22.00) 295 | - React-cxxreact (= 0.71.0) 296 | - React-jsi (= 0.71.0) 297 | - React-perflogger (= 0.71.0) 298 | - React-jsinspector (0.71.0) 299 | - React-logger (0.71.0): 300 | - glog 301 | - react-native-background-timer (2.4.1): 302 | - React-Core 303 | - react-native-safe-area-context (4.4.1): 304 | - RCT-Folly 305 | - RCTRequired 306 | - RCTTypeSafety 307 | - React-Core 308 | - ReactCommon/turbomodule/core 309 | - react-native-webrtc (0.0.6): 310 | - JitsiWebRTC (~> 106.0.0) 311 | - React-Core 312 | - React-perflogger (0.71.0) 313 | - React-RCTActionSheet (0.71.0): 314 | - React-Core/RCTActionSheetHeaders (= 0.71.0) 315 | - React-RCTAnimation (0.71.0): 316 | - RCT-Folly (= 2021.07.22.00) 317 | - RCTTypeSafety (= 0.71.0) 318 | - React-Codegen (= 0.71.0) 319 | - React-Core/RCTAnimationHeaders (= 0.71.0) 320 | - React-jsi (= 0.71.0) 321 | - ReactCommon/turbomodule/core (= 0.71.0) 322 | - React-RCTAppDelegate (0.71.0): 323 | - RCT-Folly 324 | - RCTRequired 325 | - RCTTypeSafety 326 | - React-Core 327 | - ReactCommon/turbomodule/core 328 | - React-RCTBlob (0.71.0): 329 | - RCT-Folly (= 2021.07.22.00) 330 | - React-Codegen (= 0.71.0) 331 | - React-Core/RCTBlobHeaders (= 0.71.0) 332 | - React-Core/RCTWebSocket (= 0.71.0) 333 | - React-jsi (= 0.71.0) 334 | - React-RCTNetwork (= 0.71.0) 335 | - ReactCommon/turbomodule/core (= 0.71.0) 336 | - React-RCTImage (0.71.0): 337 | - RCT-Folly (= 2021.07.22.00) 338 | - RCTTypeSafety (= 0.71.0) 339 | - React-Codegen (= 0.71.0) 340 | - React-Core/RCTImageHeaders (= 0.71.0) 341 | - React-jsi (= 0.71.0) 342 | - React-RCTNetwork (= 0.71.0) 343 | - ReactCommon/turbomodule/core (= 0.71.0) 344 | - React-RCTLinking (0.71.0): 345 | - React-Codegen (= 0.71.0) 346 | - React-Core/RCTLinkingHeaders (= 0.71.0) 347 | - React-jsi (= 0.71.0) 348 | - ReactCommon/turbomodule/core (= 0.71.0) 349 | - React-RCTNetwork (0.71.0): 350 | - RCT-Folly (= 2021.07.22.00) 351 | - RCTTypeSafety (= 0.71.0) 352 | - React-Codegen (= 0.71.0) 353 | - React-Core/RCTNetworkHeaders (= 0.71.0) 354 | - React-jsi (= 0.71.0) 355 | - ReactCommon/turbomodule/core (= 0.71.0) 356 | - React-RCTSettings (0.71.0): 357 | - RCT-Folly (= 2021.07.22.00) 358 | - RCTTypeSafety (= 0.71.0) 359 | - React-Codegen (= 0.71.0) 360 | - React-Core/RCTSettingsHeaders (= 0.71.0) 361 | - React-jsi (= 0.71.0) 362 | - ReactCommon/turbomodule/core (= 0.71.0) 363 | - React-RCTText (0.71.0): 364 | - React-Core/RCTTextHeaders (= 0.71.0) 365 | - React-RCTVibration (0.71.0): 366 | - RCT-Folly (= 2021.07.22.00) 367 | - React-Codegen (= 0.71.0) 368 | - React-Core/RCTVibrationHeaders (= 0.71.0) 369 | - React-jsi (= 0.71.0) 370 | - ReactCommon/turbomodule/core (= 0.71.0) 371 | - React-runtimeexecutor (0.71.0): 372 | - React-jsi (= 0.71.0) 373 | - ReactCommon/turbomodule/bridging (0.71.0): 374 | - DoubleConversion 375 | - glog 376 | - RCT-Folly (= 2021.07.22.00) 377 | - React-callinvoker (= 0.71.0) 378 | - React-Core (= 0.71.0) 379 | - React-cxxreact (= 0.71.0) 380 | - React-jsi (= 0.71.0) 381 | - React-logger (= 0.71.0) 382 | - React-perflogger (= 0.71.0) 383 | - ReactCommon/turbomodule/core (0.71.0): 384 | - DoubleConversion 385 | - glog 386 | - RCT-Folly (= 2021.07.22.00) 387 | - React-callinvoker (= 0.71.0) 388 | - React-Core (= 0.71.0) 389 | - React-cxxreact (= 0.71.0) 390 | - React-jsi (= 0.71.0) 391 | - React-logger (= 0.71.0) 392 | - React-perflogger (= 0.71.0) 393 | - ReactNativeIncallManager (0.0.9): 394 | - React 395 | - RNCAsyncStorage (1.17.11): 396 | - React-Core 397 | - RNCPushNotificationIOS (1.10.1): 398 | - React-Core 399 | - RNVectorIcons (9.2.0): 400 | - React-Core 401 | - SocketRocket (0.6.0) 402 | - Yoga (1.14.0) 403 | - YogaKit (1.18.1): 404 | - Yoga (~> 1.14) 405 | 406 | DEPENDENCIES: 407 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) 408 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 409 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 410 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) 411 | - Flipper (= 0.125.0) 412 | - Flipper-Boost-iOSX (= 1.76.0.1.11) 413 | - Flipper-DoubleConversion (= 3.2.0.1) 414 | - Flipper-Fmt (= 7.1.7) 415 | - Flipper-Folly (= 2.6.10) 416 | - Flipper-Glog (= 0.5.0.5) 417 | - Flipper-PeerTalk (= 0.0.4) 418 | - Flipper-RSocket (= 1.4.3) 419 | - FlipperKit (= 0.125.0) 420 | - FlipperKit/Core (= 0.125.0) 421 | - FlipperKit/CppBridge (= 0.125.0) 422 | - FlipperKit/FBCxxFollyDynamicConvert (= 0.125.0) 423 | - FlipperKit/FBDefines (= 0.125.0) 424 | - FlipperKit/FKPortForwarding (= 0.125.0) 425 | - FlipperKit/FlipperKitHighlightOverlay (= 0.125.0) 426 | - FlipperKit/FlipperKitLayoutPlugin (= 0.125.0) 427 | - FlipperKit/FlipperKitLayoutTextSearchable (= 0.125.0) 428 | - FlipperKit/FlipperKitNetworkPlugin (= 0.125.0) 429 | - FlipperKit/FlipperKitReactPlugin (= 0.125.0) 430 | - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.125.0) 431 | - FlipperKit/SKIOSNetworkPlugin (= 0.125.0) 432 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 433 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) 434 | - libevent (~> 2.1.12) 435 | - OpenSSL-Universal (= 1.1.1100) 436 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) 437 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 438 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 439 | - React (from `../node_modules/react-native/`) 440 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) 441 | - React-Codegen (from `build/generated/ios`) 442 | - React-Core (from `../node_modules/react-native/`) 443 | - React-Core/DevSupport (from `../node_modules/react-native/`) 444 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 445 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 446 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 447 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) 448 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 449 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 450 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) 451 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`) 452 | - react-native-background-timer (from `../node_modules/react-native-background-timer`) 453 | - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) 454 | - "react-native-webrtc (from `../node_modules/@videosdk.live/react-native-webrtc`)" 455 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) 456 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 457 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 458 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) 459 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 460 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 461 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 462 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 463 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 464 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 465 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 466 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) 467 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 468 | - "ReactNativeIncallManager (from `../node_modules/@videosdk.live/react-native-incallmanager`)" 469 | - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" 470 | - "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)" 471 | - RNVectorIcons (from `../node_modules/react-native-vector-icons`) 472 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 473 | 474 | SPEC REPOS: 475 | trunk: 476 | - CocoaAsyncSocket 477 | - Flipper 478 | - Flipper-Boost-iOSX 479 | - Flipper-DoubleConversion 480 | - Flipper-Fmt 481 | - Flipper-Folly 482 | - Flipper-Glog 483 | - Flipper-PeerTalk 484 | - Flipper-RSocket 485 | - FlipperKit 486 | - fmt 487 | - JitsiWebRTC 488 | - libevent 489 | - OpenSSL-Universal 490 | - SocketRocket 491 | - YogaKit 492 | 493 | EXTERNAL SOURCES: 494 | boost: 495 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" 496 | DoubleConversion: 497 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 498 | FBLazyVector: 499 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 500 | FBReactNativeSpec: 501 | :path: "../node_modules/react-native/React/FBReactNativeSpec" 502 | glog: 503 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 504 | hermes-engine: 505 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" 506 | RCT-Folly: 507 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" 508 | RCTRequired: 509 | :path: "../node_modules/react-native/Libraries/RCTRequired" 510 | RCTTypeSafety: 511 | :path: "../node_modules/react-native/Libraries/TypeSafety" 512 | React: 513 | :path: "../node_modules/react-native/" 514 | React-callinvoker: 515 | :path: "../node_modules/react-native/ReactCommon/callinvoker" 516 | React-Codegen: 517 | :path: build/generated/ios 518 | React-Core: 519 | :path: "../node_modules/react-native/" 520 | React-CoreModules: 521 | :path: "../node_modules/react-native/React/CoreModules" 522 | React-cxxreact: 523 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 524 | React-hermes: 525 | :path: "../node_modules/react-native/ReactCommon/hermes" 526 | React-jsi: 527 | :path: "../node_modules/react-native/ReactCommon/jsi" 528 | React-jsiexecutor: 529 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 530 | React-jsinspector: 531 | :path: "../node_modules/react-native/ReactCommon/jsinspector" 532 | React-logger: 533 | :path: "../node_modules/react-native/ReactCommon/logger" 534 | react-native-background-timer: 535 | :path: "../node_modules/react-native-background-timer" 536 | react-native-safe-area-context: 537 | :path: "../node_modules/react-native-safe-area-context" 538 | react-native-webrtc: 539 | :path: "../node_modules/@videosdk.live/react-native-webrtc" 540 | React-perflogger: 541 | :path: "../node_modules/react-native/ReactCommon/reactperflogger" 542 | React-RCTActionSheet: 543 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 544 | React-RCTAnimation: 545 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 546 | React-RCTAppDelegate: 547 | :path: "../node_modules/react-native/Libraries/AppDelegate" 548 | React-RCTBlob: 549 | :path: "../node_modules/react-native/Libraries/Blob" 550 | React-RCTImage: 551 | :path: "../node_modules/react-native/Libraries/Image" 552 | React-RCTLinking: 553 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 554 | React-RCTNetwork: 555 | :path: "../node_modules/react-native/Libraries/Network" 556 | React-RCTSettings: 557 | :path: "../node_modules/react-native/Libraries/Settings" 558 | React-RCTText: 559 | :path: "../node_modules/react-native/Libraries/Text" 560 | React-RCTVibration: 561 | :path: "../node_modules/react-native/Libraries/Vibration" 562 | React-runtimeexecutor: 563 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" 564 | ReactCommon: 565 | :path: "../node_modules/react-native/ReactCommon" 566 | ReactNativeIncallManager: 567 | :path: "../node_modules/@videosdk.live/react-native-incallmanager" 568 | RNCAsyncStorage: 569 | :path: "../node_modules/@react-native-async-storage/async-storage" 570 | RNCPushNotificationIOS: 571 | :path: "../node_modules/@react-native-community/push-notification-ios" 572 | RNVectorIcons: 573 | :path: "../node_modules/react-native-vector-icons" 574 | Yoga: 575 | :path: "../node_modules/react-native/ReactCommon/yoga" 576 | 577 | SPEC CHECKSUMS: 578 | boost: 57d2868c099736d80fcd648bf211b4431e51a558 579 | CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 580 | DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 581 | FBLazyVector: 61839cba7a48c570b7ac3e1cd8a4d0948382202f 582 | FBReactNativeSpec: 5a14398ccf5e27c1ca2d7109eb920594ce93c10d 583 | Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0 584 | Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c 585 | Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 586 | Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b 587 | Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 588 | Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 589 | Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 590 | Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541 591 | FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86 592 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 593 | glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b 594 | hermes-engine: f6e715aa6c8bd38de6c13bc85e07b0a337edaa89 595 | JitsiWebRTC: f441eb0e2d67f0588bf24e21c5162e97342714fb 596 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 597 | OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c 598 | RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 599 | RCTRequired: dea3e4163184ea57c50288c15c32c1529265c58f 600 | RCTTypeSafety: a0834ab89159a346731e8aae55ad6e2cce61c327 601 | React: d877d055ff2137ca0325a4babdef3411e11f3cb7 602 | React-callinvoker: 77bd2701eee3acac154b11ec219e68d5a1f780ad 603 | React-Codegen: bccc516adc1551ccfe04b0de27e345d38829b204 604 | React-Core: 4035f59e5bec8f3053583c6108d99c7516deb760 605 | React-CoreModules: b6a1f76423fea57a03e0d7a2f79d3b55cf193f2c 606 | React-cxxreact: fe5f6ec8ae875bebc71309d1e8ef89bb966d61a6 607 | React-hermes: 3c8ea5e8f402db2a08b57051206d7f2ba9c75565 608 | React-jsi: dbf0f82c93bfd828fa05c50f2ee74dc81f711050 609 | React-jsiexecutor: 060dd495f1e2af3d87216f7ca8a94c55ec885b4f 610 | React-jsinspector: 5061fcbec93fd672183dfb39cc2f65e55a0835db 611 | React-logger: a6c0b3a807a8e81f6d7fea2e72660766f55daa50 612 | react-native-background-timer: 17ea5e06803401a379ebf1f20505b793ac44d0fe 613 | react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a 614 | react-native-webrtc: a73f914349f7779785332823ca7b2de038ad7c69 615 | React-perflogger: e5fc4149e9bbb972b8520277f3b23141faa47a36 616 | React-RCTActionSheet: 991de88216bf03ab9bb1d213d73c62ecbe64ade7 617 | React-RCTAnimation: b74e3d1bf5280891a573e447b487fa1db0713b5b 618 | React-RCTAppDelegate: f52667f2dbc510f87b7988c5204e8764d50bf0c1 619 | React-RCTBlob: 6762787c01d5d8d18efed03764b0d58d3b79595a 620 | React-RCTImage: 9ed7eba8dd192a49def2cad2ecaedee7e7e315b4 621 | React-RCTLinking: 0b58eed9af0645a161b80bf412b6b721e4585c66 622 | React-RCTNetwork: dc075b0eea00d8a98c928f011d9bc2458acc7092 623 | React-RCTSettings: 30fb3f498cfaf8a4bb47334ff9ffbe318ef78766 624 | React-RCTText: a631564e84a227fe24bae7c04446f36faea7fcf5 625 | React-RCTVibration: 55c91eccdbd435d7634efbe847086944389475b0 626 | React-runtimeexecutor: ac80782d9d76ba2b0f709f4de0c427fe33c352dc 627 | ReactCommon: 20e38a9be5fe1341b5e422220877cc94034776ba 628 | ReactNativeIncallManager: 4bd3287cd449bdd88de93309b462f96ba9f5e64a 629 | RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60 630 | RNCPushNotificationIOS: 87b8d16d3ede4532745e05b03c42cff33a36cc45 631 | RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8 632 | SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 633 | Yoga: c618b544ff8bd8865cdca602f00cbcdb92fd6d31 634 | YogaKit: f782866e155069a2cca2517aafea43200b01fd5a 635 | 636 | PODFILE CHECKSUM: fd2f37e07f0cdd05ce4c8e78e8ef6893cc7dc8c0 637 | 638 | COCOAPODS: 1.11.3 639 | -------------------------------------------------------------------------------- /ios/FacebookMessenger.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 00E356F31AD99517003FC87E /* FacebookMessengerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* FacebookMessengerTests.m */; }; 11 | 0C80B921A6F3F58F76C31292 /* libPods-FacebookMessenger.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-FacebookMessenger.a */; }; 12 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 14 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 15 | 7699B88040F8A987B510C191 /* libPods-FacebookMessenger-FacebookMessengerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-FacebookMessenger-FacebookMessengerTests.a */; }; 16 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A; 25 | remoteInfo = FacebookMessenger; 26 | }; 27 | /* End PBXContainerItemProxy section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 00E356EE1AD99517003FC87E /* FacebookMessengerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FacebookMessengerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 00E356F21AD99517003FC87E /* FacebookMessengerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FacebookMessengerTests.m; sourceTree = ""; }; 33 | 13B07F961A680F5B00A75B9A /* FacebookMessenger.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FacebookMessenger.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = FacebookMessenger/AppDelegate.h; sourceTree = ""; }; 35 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = FacebookMessenger/AppDelegate.mm; sourceTree = ""; }; 36 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = FacebookMessenger/Images.xcassets; sourceTree = ""; }; 37 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = FacebookMessenger/Info.plist; sourceTree = ""; }; 38 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = FacebookMessenger/main.m; sourceTree = ""; }; 39 | 19F6CBCC0A4E27FBF8BF4A61 /* libPods-FacebookMessenger-FacebookMessengerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FacebookMessenger-FacebookMessengerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 3B4392A12AC88292D35C810B /* Pods-FacebookMessenger.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FacebookMessenger.debug.xcconfig"; path = "Target Support Files/Pods-FacebookMessenger/Pods-FacebookMessenger.debug.xcconfig"; sourceTree = ""; }; 41 | 5709B34CF0A7D63546082F79 /* Pods-FacebookMessenger.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FacebookMessenger.release.xcconfig"; path = "Target Support Files/Pods-FacebookMessenger/Pods-FacebookMessenger.release.xcconfig"; sourceTree = ""; }; 42 | 5B7EB9410499542E8C5724F5 /* Pods-FacebookMessenger-FacebookMessengerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FacebookMessenger-FacebookMessengerTests.debug.xcconfig"; path = "Target Support Files/Pods-FacebookMessenger-FacebookMessengerTests/Pods-FacebookMessenger-FacebookMessengerTests.debug.xcconfig"; sourceTree = ""; }; 43 | 5DCACB8F33CDC322A6C60F78 /* libPods-FacebookMessenger.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FacebookMessenger.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = FacebookMessenger/LaunchScreen.storyboard; sourceTree = ""; }; 45 | 89C6BE57DB24E9ADA2F236DE /* Pods-FacebookMessenger-FacebookMessengerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FacebookMessenger-FacebookMessengerTests.release.xcconfig"; path = "Target Support Files/Pods-FacebookMessenger-FacebookMessengerTests/Pods-FacebookMessenger-FacebookMessengerTests.release.xcconfig"; sourceTree = ""; }; 46 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 47 | FC83DDA029BEF914009F68DB /* FacebookMessenger.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = FacebookMessenger.entitlements; path = FacebookMessenger/FacebookMessenger.entitlements; sourceTree = ""; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | 00E356EB1AD99517003FC87E /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | 7699B88040F8A987B510C191 /* libPods-FacebookMessenger-FacebookMessengerTests.a in Frameworks */, 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | 0C80B921A6F3F58F76C31292 /* libPods-FacebookMessenger.a in Frameworks */, 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | /* End PBXFrameworksBuildPhase section */ 68 | 69 | /* Begin PBXGroup section */ 70 | 00E356EF1AD99517003FC87E /* FacebookMessengerTests */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 00E356F21AD99517003FC87E /* FacebookMessengerTests.m */, 74 | 00E356F01AD99517003FC87E /* Supporting Files */, 75 | ); 76 | path = FacebookMessengerTests; 77 | sourceTree = ""; 78 | }; 79 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 00E356F11AD99517003FC87E /* Info.plist */, 83 | ); 84 | name = "Supporting Files"; 85 | sourceTree = ""; 86 | }; 87 | 13B07FAE1A68108700A75B9A /* FacebookMessenger */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | FC83DDA029BEF914009F68DB /* FacebookMessenger.entitlements */, 91 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 92 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */, 93 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 94 | 13B07FB61A68108700A75B9A /* Info.plist */, 95 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 96 | 13B07FB71A68108700A75B9A /* main.m */, 97 | ); 98 | name = FacebookMessenger; 99 | sourceTree = ""; 100 | }; 101 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 105 | 5DCACB8F33CDC322A6C60F78 /* libPods-FacebookMessenger.a */, 106 | 19F6CBCC0A4E27FBF8BF4A61 /* libPods-FacebookMessenger-FacebookMessengerTests.a */, 107 | ); 108 | name = Frameworks; 109 | sourceTree = ""; 110 | }; 111 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | ); 115 | name = Libraries; 116 | sourceTree = ""; 117 | }; 118 | 83CBB9F61A601CBA00E9B192 = { 119 | isa = PBXGroup; 120 | children = ( 121 | 13B07FAE1A68108700A75B9A /* FacebookMessenger */, 122 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 123 | 00E356EF1AD99517003FC87E /* FacebookMessengerTests */, 124 | 83CBBA001A601CBA00E9B192 /* Products */, 125 | 2D16E6871FA4F8E400B85C8A /* Frameworks */, 126 | BBD78D7AC51CEA395F1C20DB /* Pods */, 127 | ); 128 | indentWidth = 2; 129 | sourceTree = ""; 130 | tabWidth = 2; 131 | usesTabs = 0; 132 | }; 133 | 83CBBA001A601CBA00E9B192 /* Products */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 13B07F961A680F5B00A75B9A /* FacebookMessenger.app */, 137 | 00E356EE1AD99517003FC87E /* FacebookMessengerTests.xctest */, 138 | ); 139 | name = Products; 140 | sourceTree = ""; 141 | }; 142 | BBD78D7AC51CEA395F1C20DB /* Pods */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 3B4392A12AC88292D35C810B /* Pods-FacebookMessenger.debug.xcconfig */, 146 | 5709B34CF0A7D63546082F79 /* Pods-FacebookMessenger.release.xcconfig */, 147 | 5B7EB9410499542E8C5724F5 /* Pods-FacebookMessenger-FacebookMessengerTests.debug.xcconfig */, 148 | 89C6BE57DB24E9ADA2F236DE /* Pods-FacebookMessenger-FacebookMessengerTests.release.xcconfig */, 149 | ); 150 | path = Pods; 151 | sourceTree = ""; 152 | }; 153 | /* End PBXGroup section */ 154 | 155 | /* Begin PBXNativeTarget section */ 156 | 00E356ED1AD99517003FC87E /* FacebookMessengerTests */ = { 157 | isa = PBXNativeTarget; 158 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "FacebookMessengerTests" */; 159 | buildPhases = ( 160 | A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */, 161 | 00E356EA1AD99517003FC87E /* Sources */, 162 | 00E356EB1AD99517003FC87E /* Frameworks */, 163 | 00E356EC1AD99517003FC87E /* Resources */, 164 | C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */, 165 | F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */, 166 | ); 167 | buildRules = ( 168 | ); 169 | dependencies = ( 170 | 00E356F51AD99517003FC87E /* PBXTargetDependency */, 171 | ); 172 | name = FacebookMessengerTests; 173 | productName = FacebookMessengerTests; 174 | productReference = 00E356EE1AD99517003FC87E /* FacebookMessengerTests.xctest */; 175 | productType = "com.apple.product-type.bundle.unit-test"; 176 | }; 177 | 13B07F861A680F5B00A75B9A /* FacebookMessenger */ = { 178 | isa = PBXNativeTarget; 179 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "FacebookMessenger" */; 180 | buildPhases = ( 181 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, 182 | FD10A7F022414F080027D42C /* Start Packager */, 183 | 13B07F871A680F5B00A75B9A /* Sources */, 184 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 185 | 13B07F8E1A680F5B00A75B9A /* Resources */, 186 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 187 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */, 188 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */, 189 | ); 190 | buildRules = ( 191 | ); 192 | dependencies = ( 193 | ); 194 | name = FacebookMessenger; 195 | productName = FacebookMessenger; 196 | productReference = 13B07F961A680F5B00A75B9A /* FacebookMessenger.app */; 197 | productType = "com.apple.product-type.application"; 198 | }; 199 | /* End PBXNativeTarget section */ 200 | 201 | /* Begin PBXProject section */ 202 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 203 | isa = PBXProject; 204 | attributes = { 205 | LastUpgradeCheck = 1210; 206 | TargetAttributes = { 207 | 00E356ED1AD99517003FC87E = { 208 | CreatedOnToolsVersion = 6.2; 209 | TestTargetID = 13B07F861A680F5B00A75B9A; 210 | }; 211 | 13B07F861A680F5B00A75B9A = { 212 | LastSwiftMigration = 1120; 213 | }; 214 | }; 215 | }; 216 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "FacebookMessenger" */; 217 | compatibilityVersion = "Xcode 12.0"; 218 | developmentRegion = en; 219 | hasScannedForEncodings = 0; 220 | knownRegions = ( 221 | en, 222 | Base, 223 | ); 224 | mainGroup = 83CBB9F61A601CBA00E9B192; 225 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 226 | projectDirPath = ""; 227 | projectRoot = ""; 228 | targets = ( 229 | 13B07F861A680F5B00A75B9A /* FacebookMessenger */, 230 | 00E356ED1AD99517003FC87E /* FacebookMessengerTests */, 231 | ); 232 | }; 233 | /* End PBXProject section */ 234 | 235 | /* Begin PBXResourcesBuildPhase section */ 236 | 00E356EC1AD99517003FC87E /* Resources */ = { 237 | isa = PBXResourcesBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 248 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | /* End PBXResourcesBuildPhase section */ 253 | 254 | /* Begin PBXShellScriptBuildPhase section */ 255 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 256 | isa = PBXShellScriptBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | ); 260 | inputPaths = ( 261 | "$(SRCROOT)/.xcode.env.local", 262 | "$(SRCROOT)/.xcode.env", 263 | ); 264 | name = "Bundle React Native code and images"; 265 | outputPaths = ( 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | shellPath = /bin/sh; 269 | shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; 270 | }; 271 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { 272 | isa = PBXShellScriptBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | ); 276 | inputFileListPaths = ( 277 | "${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger/Pods-FacebookMessenger-frameworks-${CONFIGURATION}-input-files.xcfilelist", 278 | ); 279 | name = "[CP] Embed Pods Frameworks"; 280 | outputFileListPaths = ( 281 | "${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger/Pods-FacebookMessenger-frameworks-${CONFIGURATION}-output-files.xcfilelist", 282 | ); 283 | runOnlyForDeploymentPostprocessing = 0; 284 | shellPath = /bin/sh; 285 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger/Pods-FacebookMessenger-frameworks.sh\"\n"; 286 | showEnvVarsInLog = 0; 287 | }; 288 | A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = { 289 | isa = PBXShellScriptBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | ); 293 | inputFileListPaths = ( 294 | ); 295 | inputPaths = ( 296 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 297 | "${PODS_ROOT}/Manifest.lock", 298 | ); 299 | name = "[CP] Check Pods Manifest.lock"; 300 | outputFileListPaths = ( 301 | ); 302 | outputPaths = ( 303 | "$(DERIVED_FILE_DIR)/Pods-FacebookMessenger-FacebookMessengerTests-checkManifestLockResult.txt", 304 | ); 305 | runOnlyForDeploymentPostprocessing = 0; 306 | shellPath = /bin/sh; 307 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 308 | showEnvVarsInLog = 0; 309 | }; 310 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = { 311 | isa = PBXShellScriptBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | ); 315 | inputFileListPaths = ( 316 | ); 317 | inputPaths = ( 318 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 319 | "${PODS_ROOT}/Manifest.lock", 320 | ); 321 | name = "[CP] Check Pods Manifest.lock"; 322 | outputFileListPaths = ( 323 | ); 324 | outputPaths = ( 325 | "$(DERIVED_FILE_DIR)/Pods-FacebookMessenger-checkManifestLockResult.txt", 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | shellPath = /bin/sh; 329 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 330 | showEnvVarsInLog = 0; 331 | }; 332 | C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = { 333 | isa = PBXShellScriptBuildPhase; 334 | buildActionMask = 2147483647; 335 | files = ( 336 | ); 337 | inputFileListPaths = ( 338 | "${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger-FacebookMessengerTests/Pods-FacebookMessenger-FacebookMessengerTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", 339 | ); 340 | name = "[CP] Embed Pods Frameworks"; 341 | outputFileListPaths = ( 342 | "${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger-FacebookMessengerTests/Pods-FacebookMessenger-FacebookMessengerTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", 343 | ); 344 | runOnlyForDeploymentPostprocessing = 0; 345 | shellPath = /bin/sh; 346 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger-FacebookMessengerTests/Pods-FacebookMessenger-FacebookMessengerTests-frameworks.sh\"\n"; 347 | showEnvVarsInLog = 0; 348 | }; 349 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = { 350 | isa = PBXShellScriptBuildPhase; 351 | buildActionMask = 2147483647; 352 | files = ( 353 | ); 354 | inputFileListPaths = ( 355 | "${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger/Pods-FacebookMessenger-resources-${CONFIGURATION}-input-files.xcfilelist", 356 | ); 357 | name = "[CP] Copy Pods Resources"; 358 | outputFileListPaths = ( 359 | "${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger/Pods-FacebookMessenger-resources-${CONFIGURATION}-output-files.xcfilelist", 360 | ); 361 | runOnlyForDeploymentPostprocessing = 0; 362 | shellPath = /bin/sh; 363 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger/Pods-FacebookMessenger-resources.sh\"\n"; 364 | showEnvVarsInLog = 0; 365 | }; 366 | F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = { 367 | isa = PBXShellScriptBuildPhase; 368 | buildActionMask = 2147483647; 369 | files = ( 370 | ); 371 | inputFileListPaths = ( 372 | "${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger-FacebookMessengerTests/Pods-FacebookMessenger-FacebookMessengerTests-resources-${CONFIGURATION}-input-files.xcfilelist", 373 | ); 374 | name = "[CP] Copy Pods Resources"; 375 | outputFileListPaths = ( 376 | "${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger-FacebookMessengerTests/Pods-FacebookMessenger-FacebookMessengerTests-resources-${CONFIGURATION}-output-files.xcfilelist", 377 | ); 378 | runOnlyForDeploymentPostprocessing = 0; 379 | shellPath = /bin/sh; 380 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FacebookMessenger-FacebookMessengerTests/Pods-FacebookMessenger-FacebookMessengerTests-resources.sh\"\n"; 381 | showEnvVarsInLog = 0; 382 | }; 383 | FD10A7F022414F080027D42C /* Start Packager */ = { 384 | isa = PBXShellScriptBuildPhase; 385 | buildActionMask = 2147483647; 386 | files = ( 387 | ); 388 | inputFileListPaths = ( 389 | ); 390 | inputPaths = ( 391 | ); 392 | name = "Start Packager"; 393 | outputFileListPaths = ( 394 | ); 395 | outputPaths = ( 396 | ); 397 | runOnlyForDeploymentPostprocessing = 0; 398 | shellPath = /bin/sh; 399 | shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; 400 | showEnvVarsInLog = 0; 401 | }; 402 | /* End PBXShellScriptBuildPhase section */ 403 | 404 | /* Begin PBXSourcesBuildPhase section */ 405 | 00E356EA1AD99517003FC87E /* Sources */ = { 406 | isa = PBXSourcesBuildPhase; 407 | buildActionMask = 2147483647; 408 | files = ( 409 | 00E356F31AD99517003FC87E /* FacebookMessengerTests.m in Sources */, 410 | ); 411 | runOnlyForDeploymentPostprocessing = 0; 412 | }; 413 | 13B07F871A680F5B00A75B9A /* Sources */ = { 414 | isa = PBXSourcesBuildPhase; 415 | buildActionMask = 2147483647; 416 | files = ( 417 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 418 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 419 | ); 420 | runOnlyForDeploymentPostprocessing = 0; 421 | }; 422 | /* End PBXSourcesBuildPhase section */ 423 | 424 | /* Begin PBXTargetDependency section */ 425 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 426 | isa = PBXTargetDependency; 427 | target = 13B07F861A680F5B00A75B9A /* FacebookMessenger */; 428 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; 429 | }; 430 | /* End PBXTargetDependency section */ 431 | 432 | /* Begin XCBuildConfiguration section */ 433 | 00E356F61AD99517003FC87E /* Debug */ = { 434 | isa = XCBuildConfiguration; 435 | baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-FacebookMessenger-FacebookMessengerTests.debug.xcconfig */; 436 | buildSettings = { 437 | BUNDLE_LOADER = "$(TEST_HOST)"; 438 | GCC_PREPROCESSOR_DEFINITIONS = ( 439 | "DEBUG=1", 440 | "$(inherited)", 441 | ); 442 | INFOPLIST_FILE = FacebookMessengerTests/Info.plist; 443 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 444 | LD_RUNPATH_SEARCH_PATHS = ( 445 | "$(inherited)", 446 | "@executable_path/Frameworks", 447 | "@loader_path/Frameworks", 448 | ); 449 | OTHER_LDFLAGS = ( 450 | "-ObjC", 451 | "-lc++", 452 | "$(inherited)", 453 | ); 454 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FacebookMessenger.app/FacebookMessenger"; 457 | }; 458 | name = Debug; 459 | }; 460 | 00E356F71AD99517003FC87E /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-FacebookMessenger-FacebookMessengerTests.release.xcconfig */; 463 | buildSettings = { 464 | BUNDLE_LOADER = "$(TEST_HOST)"; 465 | COPY_PHASE_STRIP = NO; 466 | INFOPLIST_FILE = FacebookMessengerTests/Info.plist; 467 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 468 | LD_RUNPATH_SEARCH_PATHS = ( 469 | "$(inherited)", 470 | "@executable_path/Frameworks", 471 | "@loader_path/Frameworks", 472 | ); 473 | OTHER_LDFLAGS = ( 474 | "-ObjC", 475 | "-lc++", 476 | "$(inherited)", 477 | ); 478 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FacebookMessenger.app/FacebookMessenger"; 481 | }; 482 | name = Release; 483 | }; 484 | 13B07F941A680F5B00A75B9A /* Debug */ = { 485 | isa = XCBuildConfiguration; 486 | baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-FacebookMessenger.debug.xcconfig */; 487 | buildSettings = { 488 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 489 | CLANG_ENABLE_MODULES = YES; 490 | CODE_SIGN_ENTITLEMENTS = FacebookMessenger/FacebookMessenger.entitlements; 491 | CURRENT_PROJECT_VERSION = 1; 492 | ENABLE_BITCODE = NO; 493 | INFOPLIST_FILE = FacebookMessenger/Info.plist; 494 | LD_RUNPATH_SEARCH_PATHS = ( 495 | "$(inherited)", 496 | "@executable_path/Frameworks", 497 | ); 498 | MARKETING_VERSION = 1.0; 499 | OTHER_LDFLAGS = ( 500 | "$(inherited)", 501 | "-ObjC", 502 | "-lc++", 503 | ); 504 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 505 | PRODUCT_NAME = FacebookMessenger; 506 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 507 | SWIFT_VERSION = 5.0; 508 | VERSIONING_SYSTEM = "apple-generic"; 509 | }; 510 | name = Debug; 511 | }; 512 | 13B07F951A680F5B00A75B9A /* Release */ = { 513 | isa = XCBuildConfiguration; 514 | baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-FacebookMessenger.release.xcconfig */; 515 | buildSettings = { 516 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 517 | CLANG_ENABLE_MODULES = YES; 518 | CODE_SIGN_ENTITLEMENTS = FacebookMessenger/FacebookMessenger.entitlements; 519 | CURRENT_PROJECT_VERSION = 1; 520 | INFOPLIST_FILE = FacebookMessenger/Info.plist; 521 | LD_RUNPATH_SEARCH_PATHS = ( 522 | "$(inherited)", 523 | "@executable_path/Frameworks", 524 | ); 525 | MARKETING_VERSION = 1.0; 526 | OTHER_LDFLAGS = ( 527 | "$(inherited)", 528 | "-ObjC", 529 | "-lc++", 530 | ); 531 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 532 | PRODUCT_NAME = FacebookMessenger; 533 | SWIFT_VERSION = 5.0; 534 | VERSIONING_SYSTEM = "apple-generic"; 535 | }; 536 | name = Release; 537 | }; 538 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 539 | isa = XCBuildConfiguration; 540 | buildSettings = { 541 | ALWAYS_SEARCH_USER_PATHS = NO; 542 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 543 | CLANG_CXX_LANGUAGE_STANDARD = "c++17"; 544 | CLANG_CXX_LIBRARY = "libc++"; 545 | CLANG_ENABLE_MODULES = YES; 546 | CLANG_ENABLE_OBJC_ARC = YES; 547 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 548 | CLANG_WARN_BOOL_CONVERSION = YES; 549 | CLANG_WARN_COMMA = YES; 550 | CLANG_WARN_CONSTANT_CONVERSION = YES; 551 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 552 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 553 | CLANG_WARN_EMPTY_BODY = YES; 554 | CLANG_WARN_ENUM_CONVERSION = YES; 555 | CLANG_WARN_INFINITE_RECURSION = YES; 556 | CLANG_WARN_INT_CONVERSION = YES; 557 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 558 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 559 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 560 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 561 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 562 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 563 | CLANG_WARN_STRICT_PROTOTYPES = YES; 564 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 565 | CLANG_WARN_UNREACHABLE_CODE = YES; 566 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 567 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 568 | COPY_PHASE_STRIP = NO; 569 | ENABLE_STRICT_OBJC_MSGSEND = YES; 570 | ENABLE_TESTABILITY = YES; 571 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 572 | GCC_C_LANGUAGE_STANDARD = gnu99; 573 | GCC_DYNAMIC_NO_PIC = NO; 574 | GCC_NO_COMMON_BLOCKS = YES; 575 | GCC_OPTIMIZATION_LEVEL = 0; 576 | GCC_PREPROCESSOR_DEFINITIONS = ( 577 | "DEBUG=1", 578 | "$(inherited)", 579 | ); 580 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 581 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 582 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 583 | GCC_WARN_UNDECLARED_SELECTOR = YES; 584 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 585 | GCC_WARN_UNUSED_FUNCTION = YES; 586 | GCC_WARN_UNUSED_VARIABLE = YES; 587 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 588 | LD_RUNPATH_SEARCH_PATHS = ( 589 | /usr/lib/swift, 590 | "$(inherited)", 591 | ); 592 | LIBRARY_SEARCH_PATHS = ( 593 | "\"$(SDKROOT)/usr/lib/swift\"", 594 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 595 | "\"$(inherited)\"", 596 | ); 597 | MTL_ENABLE_DEBUG_INFO = YES; 598 | ONLY_ACTIVE_ARCH = YES; 599 | OTHER_CPLUSPLUSFLAGS = ( 600 | "$(OTHER_CFLAGS)", 601 | "-DFOLLY_NO_CONFIG", 602 | "-DFOLLY_MOBILE=1", 603 | "-DFOLLY_USE_LIBCPP=1", 604 | ); 605 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 606 | SDKROOT = iphoneos; 607 | }; 608 | name = Debug; 609 | }; 610 | 83CBBA211A601CBA00E9B192 /* Release */ = { 611 | isa = XCBuildConfiguration; 612 | buildSettings = { 613 | ALWAYS_SEARCH_USER_PATHS = NO; 614 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 615 | CLANG_CXX_LANGUAGE_STANDARD = "c++17"; 616 | CLANG_CXX_LIBRARY = "libc++"; 617 | CLANG_ENABLE_MODULES = YES; 618 | CLANG_ENABLE_OBJC_ARC = YES; 619 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 620 | CLANG_WARN_BOOL_CONVERSION = YES; 621 | CLANG_WARN_COMMA = YES; 622 | CLANG_WARN_CONSTANT_CONVERSION = YES; 623 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 624 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 625 | CLANG_WARN_EMPTY_BODY = YES; 626 | CLANG_WARN_ENUM_CONVERSION = YES; 627 | CLANG_WARN_INFINITE_RECURSION = YES; 628 | CLANG_WARN_INT_CONVERSION = YES; 629 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 630 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 631 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 632 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 633 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 634 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 635 | CLANG_WARN_STRICT_PROTOTYPES = YES; 636 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 637 | CLANG_WARN_UNREACHABLE_CODE = YES; 638 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 639 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 640 | COPY_PHASE_STRIP = YES; 641 | ENABLE_NS_ASSERTIONS = NO; 642 | ENABLE_STRICT_OBJC_MSGSEND = YES; 643 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 644 | GCC_C_LANGUAGE_STANDARD = gnu99; 645 | GCC_NO_COMMON_BLOCKS = YES; 646 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 647 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 648 | GCC_WARN_UNDECLARED_SELECTOR = YES; 649 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 650 | GCC_WARN_UNUSED_FUNCTION = YES; 651 | GCC_WARN_UNUSED_VARIABLE = YES; 652 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 653 | LD_RUNPATH_SEARCH_PATHS = ( 654 | /usr/lib/swift, 655 | "$(inherited)", 656 | ); 657 | LIBRARY_SEARCH_PATHS = ( 658 | "\"$(SDKROOT)/usr/lib/swift\"", 659 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 660 | "\"$(inherited)\"", 661 | ); 662 | MTL_ENABLE_DEBUG_INFO = NO; 663 | OTHER_CPLUSPLUSFLAGS = ( 664 | "$(OTHER_CFLAGS)", 665 | "-DFOLLY_NO_CONFIG", 666 | "-DFOLLY_MOBILE=1", 667 | "-DFOLLY_USE_LIBCPP=1", 668 | ); 669 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 670 | SDKROOT = iphoneos; 671 | VALIDATE_PRODUCT = YES; 672 | }; 673 | name = Release; 674 | }; 675 | /* End XCBuildConfiguration section */ 676 | 677 | /* Begin XCConfigurationList section */ 678 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "FacebookMessengerTests" */ = { 679 | isa = XCConfigurationList; 680 | buildConfigurations = ( 681 | 00E356F61AD99517003FC87E /* Debug */, 682 | 00E356F71AD99517003FC87E /* Release */, 683 | ); 684 | defaultConfigurationIsVisible = 0; 685 | defaultConfigurationName = Release; 686 | }; 687 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "FacebookMessenger" */ = { 688 | isa = XCConfigurationList; 689 | buildConfigurations = ( 690 | 13B07F941A680F5B00A75B9A /* Debug */, 691 | 13B07F951A680F5B00A75B9A /* Release */, 692 | ); 693 | defaultConfigurationIsVisible = 0; 694 | defaultConfigurationName = Release; 695 | }; 696 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "FacebookMessenger" */ = { 697 | isa = XCConfigurationList; 698 | buildConfigurations = ( 699 | 83CBBA201A601CBA00E9B192 /* Debug */, 700 | 83CBBA211A601CBA00E9B192 /* Release */, 701 | ); 702 | defaultConfigurationIsVisible = 0; 703 | defaultConfigurationName = Release; 704 | }; 705 | /* End XCConfigurationList section */ 706 | }; 707 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 708 | } 709 | --------------------------------------------------------------------------------