Compare commits
No commits in common. 'dev-home' and 'simplesip' have entirely different histories.
@ -1,2 +0,0 @@
|
||||
BUNDLE_PATH: "vendor/bundle" |
||||
BUNDLE_FORCE_RUBY_PLATFORM: 1 |
@ -1,4 +0,0 @@
|
||||
module.exports = { |
||||
root: true, |
||||
extends: '@react-native', |
||||
}; |
@ -1,76 +0,0 @@
|
||||
import ConfigScreen from './asset/screens/ConfigScreen/ConfigScreen'; |
||||
import JoinScreen from './asset/screens/JoinScreen/JoinScreen'; |
||||
import IncomingCallScreen from './asset/screens/IncomingScreen/IncomingScreen'; |
||||
import OutgoingCallScreen from './asset/screens/OutgoingScreen/OutgoingScreen'; |
||||
import ConferenceScreen from './asset/screens/ConferenceScreen/ConferenceScreen'; |
||||
import {NavigationContainer} from '@react-navigation/native'; |
||||
import { |
||||
createStackNavigator, |
||||
CardStyleInterpolators, |
||||
} from '@react-navigation/stack'; |
||||
import * as TextEncodingPolyfill from 'text-encoding'; |
||||
import BigInt from 'big-integer'; |
||||
import CombinedProvider from './asset/context/CombinedProvider'; |
||||
import React from 'react'; |
||||
|
||||
Object.assign(global, { |
||||
TextEncoder: TextEncodingPolyfill.TextEncoder, |
||||
TextDecoder: TextEncodingPolyfill.TextDecoder, |
||||
BigInt: BigInt, |
||||
}); |
||||
|
||||
export default function App() { |
||||
const Stack = createStackNavigator(); |
||||
|
||||
return ( |
||||
<NavigationContainer> |
||||
<CombinedProvider> |
||||
<Stack.Navigator initialRouteName="home"> |
||||
<Stack.Screen |
||||
name="home" |
||||
options={{ |
||||
headerShown: false, |
||||
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, |
||||
}} |
||||
component={JoinScreen} |
||||
/> |
||||
<Stack.Screen |
||||
name="configuracoes" |
||||
options={{ |
||||
headerShown: false, |
||||
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, |
||||
}} |
||||
component={ConfigScreen} |
||||
/> |
||||
<Stack.Screen |
||||
name="incomingCall" |
||||
options={{ |
||||
headerShown: false, |
||||
cardStyleInterpolator: |
||||
CardStyleInterpolators.forModalPresentationIOS, |
||||
}} |
||||
component={IncomingCallScreen} |
||||
/> |
||||
<Stack.Screen |
||||
name="outgoingCall" |
||||
options={{ |
||||
headerShown: false, |
||||
cardStyleInterpolator: |
||||
CardStyleInterpolators.forModalPresentationIOS, |
||||
}} |
||||
component={OutgoingCallScreen} |
||||
/> |
||||
<Stack.Screen |
||||
name="roomConference" |
||||
options={{ |
||||
headerShown: false, |
||||
cardStyleInterpolator: |
||||
CardStyleInterpolators.forModalPresentationIOS, |
||||
}} |
||||
component={ConferenceScreen} |
||||
/> |
||||
</Stack.Navigator> |
||||
</CombinedProvider> |
||||
</NavigationContainer> |
||||
); |
||||
} |
@ -1,79 +1,11 @@
|
||||
This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). |
||||
#Aplicativo em react native usando a api WebRTC para poder realizar a conexão p2p entre dois dispositivos e assim simular uma chamada que transmite áudio e vídeo. |
||||
|
||||
# Getting Started |
||||
|
||||
>**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. |
||||
Aqui está sendo implementado o WebRTC em uma aplicação mobile. Dentro do projeto estão as pastas client, public e server. |
||||
Na pasta do client, está presente o layout em React Native, está presente as configurações de socket para se comunicar com o servidor WebSocket e outras configurações para estabelecer uma conexão peer-to-peer com o outro usuário. |
||||
|
||||
## Step 1: Start the Metro Server |
||||
Já na parte 'server', está presente o servidor em NodeJS. O servidor irá utilizar a tecnologia do WebSocket para realizar a comunicação com o client. |
||||
|
||||
First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. |
||||
|
||||
To start Metro, run the following command from the _root_ of your React Native project: |
||||
|
||||
```bash |
||||
# using npm |
||||
npm start |
||||
|
||||
# OR using Yarn |
||||
yarn start |
||||
``` |
||||
|
||||
## Step 2: Start your Application |
||||
|
||||
Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app: |
||||
|
||||
### For Android |
||||
|
||||
```bash |
||||
# using npm |
||||
npm run android |
||||
|
||||
# OR using Yarn |
||||
yarn android |
||||
``` |
||||
|
||||
### For iOS |
||||
|
||||
```bash |
||||
# using npm |
||||
npm run ios |
||||
|
||||
# OR using Yarn |
||||
yarn ios |
||||
``` |
||||
|
||||
If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly. |
||||
|
||||
This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively. |
||||
|
||||
## Step 3: Modifying your App |
||||
|
||||
Now that you have successfully run the app, let's modify it. |
||||
|
||||
1. Open `App.tsx` in your text editor of choice and edit some lines. |
||||
2. For **Android**: Press the <kbd>R</kbd> key twice or select **"Reload"** from the **Developer Menu** (<kbd>Ctrl</kbd> + <kbd>M</kbd> (on Window and Linux) or <kbd>Cmd ⌘</kbd> + <kbd>M</kbd> (on macOS)) to see your changes! |
||||
|
||||
For **iOS**: Hit <kbd>Cmd ⌘</kbd> + <kbd>R</kbd> in your iOS Simulator to reload the app and see your changes! |
||||
|
||||
## Congratulations! :tada: |
||||
|
||||
You've successfully run and modified your React Native App. :partying_face: |
||||
|
||||
### Now what? |
||||
|
||||
- If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps). |
||||
- If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). |
||||
|
||||
# Troubleshooting |
||||
|
||||
If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. |
||||
|
||||
# Learn More |
||||
|
||||
To learn more about React Native, take a look at the following resources: |
||||
|
||||
- [React Native Website](https://reactnative.dev) - learn more about React Native. |
||||
- [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment. |
||||
- [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**. |
||||
- [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts. |
||||
- [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native. |
||||
O servidor utiliza a porta por padrão 3500; |
||||
O servidor possui listeners e emite listeners fundamentes para receber, fazer, aceitar e recusar chamadas; |
||||
O servidor possui listeners também para procurar ICE Candidates que serão responsáveis por furar as barreiras de NAT e Firewall e assim estabelecer a conexão p2p com o outro usuário da ponta. |
@ -1,129 +0,0 @@
|
||||
apply plugin: "com.android.application" |
||||
apply plugin: "org.jetbrains.kotlin.android" |
||||
apply plugin: "com.facebook.react" |
||||
|
||||
/** |
||||
* This is the configuration block to customize your React Native Android app. |
||||
* By default you don't need to apply any configuration, just uncomment the lines you need. |
||||
*/ |
||||
react { |
||||
/* Folders */ |
||||
// The root of your project, i.e. where "package.json" lives. Default is '..' |
||||
// root = file("../") |
||||
// The folder where the react-native NPM package is. Default is ../node_modules/react-native |
||||
// reactNativeDir = file("../node_modules/react-native") |
||||
// The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen |
||||
// codegenDir = file("../node_modules/@react-native/codegen") |
||||
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js |
||||
// cliFile = file("../node_modules/react-native/cli.js") |
||||
|
||||
/* Variants */ |
||||
// The list of variants to that are debuggable. For those we're going to |
||||
// skip the bundling of the JS bundle and the assets. By default is just 'debug'. |
||||
// If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. |
||||
// debuggableVariants = ["liteDebug", "prodDebug"] |
||||
|
||||
/* Bundling */ |
||||
// A list containing the node command and its flags. Default is just 'node'. |
||||
// nodeExecutableAndArgs = ["node"] |
||||
// |
||||
// The command to run when bundling. By default is 'bundle' |
||||
// bundleCommand = "ram-bundle" |
||||
// |
||||
// The path to the CLI configuration file. Default is empty. |
||||
// bundleConfig = file(../rn-cli.config.js) |
||||
// |
||||
// The name of the generated asset file containing your JS bundle |
||||
// bundleAssetName = "MyApplication.android.bundle" |
||||
// |
||||
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js' |
||||
// entryFile = file("../js/MyApplication.android.js") |
||||
// |
||||
// A list of extra flags to pass to the 'bundle' commands. |
||||
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle |
||||
// extraPackagerArgs = [] |
||||
|
||||
/* Hermes Commands */ |
||||
// The hermes compiler command to run. By default it is 'hermesc' |
||||
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" |
||||
// |
||||
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" |
||||
// hermesFlags = ["-O", "-output-source-map"] |
||||
} |
||||
|
||||
/** |
||||
* Set this to true to Run Proguard on Release builds to minify the Java bytecode. |
||||
*/ |
||||
def enableProguardInReleaseBuilds = false |
||||
|
||||
/** |
||||
* The preferred build flavor of JavaScriptCore (JSC) |
||||
* |
||||
* For example, to use the international variant, you can use: |
||||
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'` |
||||
* |
||||
* The international variant includes ICU i18n library and necessary data |
||||
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that |
||||
* give correct results when using with locales other than en-US. Note that |
||||
* this variant is about 6MiB larger per architecture than default. |
||||
*/ |
||||
def jscFlavor = 'org.webkit:android-jsc:+' |
||||
|
||||
android { |
||||
ndkVersion rootProject.ext.ndkVersion |
||||
buildToolsVersion rootProject.ext.buildToolsVersion |
||||
compileSdk rootProject.ext.compileSdkVersion |
||||
|
||||
namespace "com.sip" |
||||
defaultConfig { |
||||
applicationId "com.sip" |
||||
minSdkVersion rootProject.ext.minSdkVersion |
||||
targetSdkVersion rootProject.ext.targetSdkVersion |
||||
versionCode 1 |
||||
versionName "1.0" |
||||
} |
||||
signingConfigs { |
||||
release { |
||||
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { |
||||
storeFile file(MYAPP_UPLOAD_STORE_FILE) |
||||
storePassword MYAPP_UPLOAD_STORE_PASSWORD |
||||
keyAlias MYAPP_UPLOAD_KEY_ALIAS |
||||
keyPassword MYAPP_UPLOAD_KEY_PASSWORD |
||||
} |
||||
} |
||||
debug { |
||||
storeFile file('debug.keystore') |
||||
storePassword 'android' |
||||
keyAlias 'androiddebugkey' |
||||
keyPassword 'android' |
||||
} |
||||
} |
||||
buildTypes { |
||||
debug { |
||||
signingConfig signingConfigs.debug |
||||
} |
||||
release { |
||||
// Caution! In production, you need to generate your own keystore file. |
||||
// see https://reactnative.dev/docs/signed-apk-android. |
||||
signingConfig signingConfigs.release |
||||
minifyEnabled enableProguardInReleaseBuilds |
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" |
||||
} |
||||
} |
||||
} |
||||
|
||||
dependencies { |
||||
// The version of react-native is set by the React Native Gradle Plugin |
||||
implementation("com.facebook.react:react-android") |
||||
implementation("com.facebook.react:flipper-integration") |
||||
implementation project(':react-native-fs') |
||||
|
||||
if (hermesEnabled.toBoolean()) { |
||||
implementation("com.facebook.react:hermes-android") |
||||
} else { |
||||
implementation jscFlavor |
||||
} |
||||
} |
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) |
||||
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle") |
@ -1,29 +0,0 @@
|
||||
package com.sip |
||||
|
||||
import com.facebook.react.ReactActivity |
||||
import com.facebook.react.ReactActivityDelegate |
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled |
||||
import com.facebook.react.defaults.DefaultReactActivityDelegate |
||||
import android.os.Bundle; |
||||
|
||||
class MainActivity : ReactActivity() { |
||||
|
||||
/** |
||||
* Returns the name of the main component registered from JavaScript. This is used to schedule |
||||
* rendering of the component. |
||||
*/ |
||||
override fun getMainComponentName(): String = "sip" |
||||
|
||||
|
||||
//react-native-screens override |
||||
override fun onCreate(savedInstanceState: Bundle?) { |
||||
super.onCreate(null); |
||||
} |
||||
|
||||
/** |
||||
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] |
||||
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled] |
||||
*/ |
||||
override fun createReactActivityDelegate(): ReactActivityDelegate = |
||||
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) |
||||
} |
@ -1,45 +0,0 @@
|
||||
package com.sip |
||||
|
||||
import android.app.Application |
||||
import com.facebook.react.PackageList |
||||
import com.facebook.react.ReactApplication |
||||
import com.facebook.react.ReactHost |
||||
import com.facebook.react.ReactNativeHost |
||||
import com.facebook.react.ReactPackage |
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load |
||||
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost |
||||
import com.facebook.react.defaults.DefaultReactNativeHost |
||||
import com.facebook.react.flipper.ReactNativeFlipper |
||||
import com.facebook.soloader.SoLoader |
||||
|
||||
class MainApplication : Application(), ReactApplication { |
||||
|
||||
override val reactNativeHost: ReactNativeHost = |
||||
object : DefaultReactNativeHost(this) { |
||||
override fun getPackages(): List<ReactPackage> { |
||||
// Packages that cannot be autolinked yet can be added manually here, for example: |
||||
// packages.add(new MyReactNativePackage()); |
||||
return PackageList(this).packages |
||||
} |
||||
|
||||
override fun getJSMainModuleName(): String = "index" |
||||
|
||||
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG |
||||
|
||||
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED |
||||
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED |
||||
} |
||||
|
||||
override val reactHost: ReactHost |
||||
get() = getDefaultReactHost(this.applicationContext, reactNativeHost) |
||||
|
||||
override fun onCreate() { |
||||
super.onCreate() |
||||
SoLoader.init(this, false) |
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { |
||||
// If you opted-in for the New Architecture, we load the native entry point for this app. |
||||
load() |
||||
} |
||||
ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager) |
||||
} |
||||
} |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB |
@ -1,3 +0,0 @@
|
||||
<resources> |
||||
<string name="app_name">SSimples</string> |
||||
</resources> |
@ -1,21 +0,0 @@
|
||||
buildscript { |
||||
ext { |
||||
buildToolsVersion = "34.0.0" |
||||
minSdkVersion = 21 |
||||
compileSdkVersion = 34 |
||||
targetSdkVersion = 34 |
||||
ndkVersion = "25.1.8937393" |
||||
kotlinVersion = "1.8.0" |
||||
} |
||||
repositories { |
||||
google() |
||||
mavenCentral() |
||||
} |
||||
dependencies { |
||||
classpath("com.android.tools.build:gradle") |
||||
classpath("com.facebook.react:react-native-gradle-plugin") |
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") |
||||
} |
||||
} |
||||
|
||||
apply plugin: "com.facebook.react.rootproject" |
@ -1,7 +0,0 @@
|
||||
rootProject.name = 'sip' |
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) |
||||
include ':app' |
||||
includeBuild('../node_modules/@react-native/gradle-plugin') |
||||
|
||||
include ':react-native-fs' |
||||
project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android') |
@ -1,70 +0,0 @@
|
||||
import React, {createContext, useState, useEffect, useMemo} from 'react'; |
||||
import EncryptedStorage from 'react-native-encrypted-storage'; |
||||
|
||||
export const AuthContext = createContext(); |
||||
|
||||
export const AuthProvider = ({children}) => { |
||||
const [sendAuth, setSendAuth] = useState(false); |
||||
const [authData, setAuthData] = useState({ |
||||
protocolo: '', |
||||
servidor: '', |
||||
porta: '', |
||||
ramal: '', |
||||
username: '', |
||||
senha: '', |
||||
}); |
||||
|
||||
const save = async (key, value) => { |
||||
try { |
||||
await EncryptedStorage.setItem(key, JSON.stringify(value)); |
||||
console.log(`Dados salvos com sucesso para a chave ${key}`); |
||||
} catch (error) { |
||||
console.error('Erro ao salvar os dados:', error); |
||||
} |
||||
}; |
||||
|
||||
useEffect(() => { |
||||
const fetchData = async () => { |
||||
try { |
||||
const savedAuthData = await EncryptedStorage.getItem('authData'); |
||||
if (savedAuthData) { |
||||
setAuthData(JSON.parse(savedAuthData)); |
||||
// Caso tenha dados salvos ele já tenta logar
|
||||
setSendAuth(prevState => !prevState); |
||||
} |
||||
} catch (error) { |
||||
console.error('Erro ao recuperar os dados salvos:', error); |
||||
} |
||||
}; |
||||
|
||||
fetchData(); |
||||
}, []); |
||||
|
||||
const handleInputChange = (field, value) => { |
||||
setAuthData(prevAuthData => ({ |
||||
...prevAuthData, |
||||
[field]: value, |
||||
})); |
||||
}; |
||||
|
||||
const handleSubmit = () => { |
||||
save('authData', authData); |
||||
setSendAuth(prevState => !prevState); |
||||
}; |
||||
|
||||
const contextValues = useMemo( |
||||
() => ({ |
||||
authData, |
||||
handleInputChange, |
||||
handleSubmit, |
||||
sendAuth, |
||||
}), |
||||
[authData, sendAuth], |
||||
); |
||||
|
||||
return ( |
||||
<AuthContext.Provider value={contextValues}> |
||||
{children} |
||||
</AuthContext.Provider> |
||||
); |
||||
}; |
@ -1,495 +0,0 @@
|
||||
import React, { |
||||
createContext, |
||||
useState, |
||||
useEffect, |
||||
useRef, |
||||
useMemo, |
||||
useContext, |
||||
} from 'react'; |
||||
import {StackActions, useNavigation} from '@react-navigation/native'; |
||||
import InCallManager from 'react-native-incall-manager'; |
||||
import JsSIP from 'react-native-jssip'; |
||||
import {Alert, Platform} from 'react-native'; |
||||
import {AuthContext} from './AuthContext'; |
||||
|
||||
export const CallContext = createContext(); |
||||
|
||||
export const CallProvider = ({children}) => { |
||||
const {authData, sendAuth} = useContext(AuthContext); |
||||
const navigation = useNavigation(); |
||||
const [session, setSession] = useState(null); |
||||
const [ua, setUa] = useState(null); |
||||
const [incommingCaller, setIncommingCaller] = useState(null); |
||||
const [calle, setCalle] = useState(null); |
||||
const [localMicOn, setLocalMicOn] = useState(true); |
||||
const [localWebcamOn, setLocalWebcamOn] = useState(true); |
||||
const [localStream, setLocalStream] = useState(null); |
||||
const [remoteStream, setRemoteStream] = useState(null); |
||||
const peerConnectionRef = useRef(null); |
||||
const [status, setStatus] = useState('disconectado'); |
||||
const [statusColor, setStatusColor] = useState('black'); |
||||
const [currentAlert, setCurrentAlert] = useState(null); |
||||
|
||||
JsSIP.debug.enable('JsSIP:*'); |
||||
|
||||
const controlStatus = status => { |
||||
switch (status) { |
||||
case 'registrado': |
||||
return 'green'; |
||||
case 'naoRegistrado': |
||||
return 'gray'; |
||||
case 'falhaRegistro': |
||||
return 'red'; |
||||
default: |
||||
return 'gray'; |
||||
} |
||||
}; |
||||
|
||||
useEffect(() => { |
||||
console.log(status); |
||||
setStatusColor(controlStatus(status)); |
||||
}, [status]); |
||||
|
||||
useEffect(() => { |
||||
console.log('Verificando authData:', authData); |
||||
if ( |
||||
authData.servidor && |
||||
authData.porta && |
||||
authData.ramal && |
||||
authData.senha && |
||||
authData.username |
||||
) { |
||||
console.log('SetupPhone iniciado'); |
||||
setupPhone(authData); |
||||
} |
||||
return () => { |
||||
console.log('Cleanup iniciado'); |
||||
cleanup(); |
||||
}; |
||||
}, [sendAuth]); |
||||
|
||||
const setupPhone = authData => { |
||||
const {protocolo, servidor, porta, ramal, senha, username} = authData; |
||||
|
||||
const socket = new JsSIP.WebSocketInterface( |
||||
`${protocolo}://${servidor}:${porta}/ws`, |
||||
); |
||||
|
||||
const configuration = { |
||||
uri: `sip:${ramal}@${servidor}`, |
||||
password: senha, |
||||
sockets: [socket], |
||||
session_timers: false, |
||||
no_answer_timeout: 180, |
||||
hack_via_tcp: false, |
||||
hack_via_ws: true, |
||||
display_name: username !== null ? username : ramal, |
||||
user_agent: 'Softphone React Native', |
||||
contact_uri: `sip:${ramal}@${servidor};transport=${protocolo}`, |
||||
pcConfig: { |
||||
iceServers: [ |
||||
{urls: 'stun:stun.l.google.com:19302'}, |
||||
{urls: 'stun:stun1.l.google.com:19302'}, |
||||
{urls: 'stun:stun2.l.google.com:19302'}, |
||||
{ |
||||
urls: 'turn:relay1.expressturn.com:3478', |
||||
username: 'efBWA92I6LHKOAISP4', |
||||
credential: 'WrVpk6pHeaKzMkAa', |
||||
}, |
||||
], |
||||
}, |
||||
}; |
||||
|
||||
const phone = new JsSIP.UA(configuration); |
||||
|
||||
phone.on('connecting', () => { |
||||
console.log('JsSIP: Conectando ao servidor...'); |
||||
}); |
||||
|
||||
phone.on('connected', () => { |
||||
console.log('JsSIP: Conexão estabelecida com sucesso.'); |
||||
}); |
||||
|
||||
phone.on('disconnected', data => { |
||||
console.warn('JsSIP: Desconectado do servidor.', data); |
||||
}); |
||||
|
||||
phone.on('newMessage', data => { |
||||
console.log('JsSIP: Nova mensagem recebida.', data); |
||||
}); |
||||
|
||||
phone.on('newRTCSession', data => { |
||||
console.log('JsSIP: Nova sessão RTC estabelecida.', data); |
||||
}); |
||||
|
||||
phone.on('registrationFailed', data => { |
||||
console.error('JsSIP: Falha no registro.', data); |
||||
}); |
||||
|
||||
phone.on('error', data => { |
||||
console.error('JsSIP: Erro ocorrido.', data); |
||||
}); |
||||
|
||||
phone.on('registrationFailed', function (ev) { |
||||
console.log('Registering on SIP server failed with error: ' + ev.cause); |
||||
configuration.uri = null; |
||||
configuration.password = null; |
||||
}); |
||||
|
||||
phone.on('newRTCSession', ev => { |
||||
const newSession = ev.session; |
||||
//Para quando estou criando uma conexao, ou seja, estou realizando uma ligacao
|
||||
if (newSession.connection) { |
||||
peerConnectionRef.current = newSession.connection; |
||||
console.log('criou peerConnection', peerConnectionRef.current); |
||||
} |
||||
//Para quando estou recebendo uma conexao
|
||||
newSession.on('peerconnection', event => { |
||||
peerConnectionRef.current = event.peerconnection; |
||||
console.log('recebeu o peerConnection', peerConnectionRef.current); |
||||
}); |
||||
// RECEBENDO UMA CHAMADA
|
||||
if (newSession.direction === 'incoming') { |
||||
navigation.dispatch(StackActions.replace('incomingCall')); |
||||
setIncommingCaller(newSession.remote_identity.uri.user); |
||||
InCallManager.startRingtone('_BUNDLE_', [0, 1000, 500, 1000]); |
||||
// Quando finalizar a chamada
|
||||
newSession.on('ended', () => { |
||||
navigation.dispatch(StackActions.replace('home')); |
||||
setSession(null); |
||||
setRemoteStream(null); |
||||
setIncommingCaller(null); |
||||
if (peerConnectionRef.current) { |
||||
peerConnectionRef.current.close(); |
||||
peerConnectionRef.current = null; |
||||
} |
||||
// Parar o InCallManager e o ringtone quando a chamada termina
|
||||
InCallManager.stop(); |
||||
InCallManager.stopRingtone(); |
||||
}); |
||||
// QUANDO UMA CHAMADA APRESENTAR PROBLEMAS
|
||||
newSession.on('failed', () => { |
||||
setRemoteStream(null); |
||||
setSession(null); |
||||
setIncommingCaller(null); |
||||
navigation.dispatch(StackActions.replace('home')); |
||||
if (peerConnectionRef.current) { |
||||
peerConnectionRef.current.close(); |
||||
peerConnectionRef.current = null; |
||||
} |
||||
// Parar o InCallManager e o ringtone quando a chamada falha
|
||||
InCallManager.stop(); |
||||
InCallManager.stopRingtone(); |
||||
}); |
||||
} else { |
||||
// Quando finalizar a chamada
|
||||
newSession.on('ended', () => { |
||||
navigation.dispatch(StackActions.popToTop()); |
||||
setRemoteStream(null); |
||||
setSession(null); |
||||
// Parar o InCallManager quando a chamada termina
|
||||
InCallManager.stop(); |
||||
}); |
||||
// QUANDO UMA CHAMADA APRESENTAR PROBLEMAS
|
||||
newSession.on('failed', () => { |
||||
navigation.dispatch(StackActions.popToTop()); |
||||
setRemoteStream(null); |
||||
setSession(null); |
||||
// Parar o InCallManager quando a chamada falha
|
||||
InCallManager.stop(); |
||||
}); |
||||
} |
||||
newSession.on('confirmed', async () => { |
||||
if (peerConnectionRef.current) { |
||||
captureMidias(); |
||||
} |
||||
}); |
||||
newSession.on('newDTMF', function (event) { |
||||
console.log('DTMF recebido:', event.dtmf.tone); |
||||
}); |
||||
newSession.on('icecandidate', function (event) { |
||||
if ( |
||||
event.candidate.type === 'srflx' && |
||||
event.candidate.relatedAddress !== null && |
||||
event.candidate.relatedPort !== null |
||||
) { |
||||
event.ready(); |
||||
} |
||||
}); |
||||
// Atribuir uma nova sessao assim que estabelcer uma
|
||||
setSession(newSession); |
||||
}); |
||||
phone.on('registered', function (e) { |
||||
setStatus('registrado'); |
||||
if (currentAlert === null || currentAlert !== 'registrado') { |
||||
setCurrentAlert('registrado'); |
||||
Alert.alert( |
||||
'Ramal registrado!', |
||||
'Seu ramal foi registrado no servidor e está pronto para uso.', |
||||
[ |
||||
{ |
||||
text: 'Ok', |
||||
onPress: () => setCurrentAlert(null), |
||||
}, |
||||
], |
||||
); |
||||
} |
||||
}); |
||||
|
||||
phone.on('unregistered', function (e) { |
||||
setStatus('naoRegistrado'); |
||||
if (currentAlert === null || currentAlert !== 'naoRegistrado') { |
||||
setCurrentAlert('naoRegistrado'); |
||||
Alert.alert('Não foi possível conectar-se ao servidor!', '', [ |
||||
{ |
||||
text: 'Ok', |
||||
onPress: () => setCurrentAlert(null), |
||||
}, |
||||
]); |
||||
} |
||||
}); |
||||
|
||||
phone.on('registrationFailed', function (e) { |
||||
setStatus('falhaRegistro'); |
||||
if (currentAlert === null || currentAlert !== 'falhaRegistro') { |
||||
setCurrentAlert('falhaRegistro'); |
||||
Alert.alert( |
||||
'Erro ao registrar ramal!', |
||||
'Confira suas credenciais de registro e tente novamente.', |
||||
[ |
||||
{ |
||||
text: 'Ok', |
||||
onPress: () => setCurrentAlert(null), |
||||
}, |
||||
], |
||||
); |
||||
} |
||||
}); |
||||
phone.start(); |
||||
// Suprimir logs no APK release fora do modo de desenvolvimento
|
||||
if (Platform.OS === 'android' && !__DEV__) { |
||||
console.log = () => {}; |
||||
} |
||||
setUa(phone); |
||||
}; |
||||
const cleanup = () => { |
||||
if (peerConnectionRef.current) { |
||||
peerConnectionRef.current.close(); |
||||
peerConnectionRef.current = null; |
||||
} |
||||
if (localStream) { |
||||
localStream.getTracks().forEach(track => track.stop()); |
||||
} |
||||
if (remoteStream) { |
||||
remoteStream.getTracks().forEach(track => track.stop()); |
||||
} |
||||
if (ua) { |
||||
ua.stop(); |
||||
} |
||||
}; |
||||
const handleAceitarChamada = async () => { |
||||
try { |
||||
if (session) { |
||||
session.answer({ |
||||
//Defino ao JsSIP se quero que ele capture as midias de audio e video
|
||||
mediaConstraints: { |
||||
audio: true, |
||||
video: true, |
||||
}, |
||||
}); |
||||
// Parar o ringtone quando a chamada é aceita
|
||||
InCallManager.stopRingtone(); |
||||
// Iniciar o InCallManager quando uma chamada é aceita
|
||||
InCallManager.start({media: 'audio'}); |
||||
navigation.dispatch(StackActions.replace('roomConference')); |
||||
} |
||||
} catch (error) { |
||||
console.error('Failed to accept call:', error); |
||||
} |
||||
}; |
||||
|
||||
const handleEndCall = async () => { |
||||
if (session) { |
||||
session.terminate(); |
||||
setSession(null); |
||||
setIncommingCaller(null); |
||||
InCallManager.stopRingback(); |
||||
InCallManager.stopRingtone(); |
||||
InCallManager.stop(); |
||||
navigation.dispatch(StackActions.replace('home')); |
||||
} else { |
||||
navigation.dispatch(StackActions.replace('home')); |
||||
} |
||||
}; |
||||
const handleIniciarChamada = async () => { |
||||
try { |
||||
if (ua && calle) { |
||||
const eventHandlers = { |
||||
progress: () => { |
||||
console.log('Call is in progress'); |
||||
// Iniciar o ringback quando a chamada está em progresso
|
||||
InCallManager.start({media: 'audio', ringback: '_DTMF_'}); |
||||
console.log('CHAMOU INCALL START 3'); |
||||
}, |
||||
failed: e => { |
||||
console.log('Call failed with cause: ' + e.cause); |
||||
if (peerConnectionRef.current) { |
||||
peerConnectionRef.current.close(); |
||||
peerConnectionRef.current = null; |
||||
} |
||||
// Parar o InCallManager e o ringback quando a chamada falha
|
||||
InCallManager.stop(); |
||||
InCallManager.stopRingback(); |
||||
}, |
||||
ended: () => { |
||||
console.log('Call ended'); |
||||
if (peerConnectionRef.current) { |
||||
peerConnectionRef.current.close(); |
||||
peerConnectionRef.current = null; |
||||
} |
||||
// Parar o InCallManager e o ringback quando a chamada termina
|
||||
InCallManager.stop(); |
||||
InCallManager.stopRingback(); |
||||
}, |
||||
confirmed: () => { |
||||
console.log('Call confirmed'); |
||||
// Parar o ringback quando a chamada é confirmada
|
||||
InCallManager.stopRingback(); |
||||
}, |
||||
}; |
||||
const options = { |
||||
eventHandlers: eventHandlers, |
||||
//Defino ao JsSIP se quero que ele capture as midias de audio e video
|
||||
mediaConstraints: { |
||||
audio: true, |
||||
video: true, |
||||
}, |
||||
rtcOfferContraints: { |
||||
offerToReceiveAudio: 1, |
||||
offerToReceiveVideo: 1, |
||||
}, |
||||
}; |
||||
console.log(calle); |
||||
const newSession = await ua.call( |
||||
`sip:${calle}@${authData.servidor}`, |
||||
options, |
||||
); |
||||
setSession(newSession); |
||||
} |
||||
} catch (error) { |
||||
console.error('Erro ao iniciar uma chamada: ', error); |
||||
} |
||||
}; |
||||
let isMuted = false; |
||||
const toggleMic = async () => { |
||||
try { |
||||
console.log('Toggling microphone...'); |
||||
if (localStream) { |
||||
const audioTrack = await localStream.getAudioTracks()[0]; |
||||
audioTrack.enabled = !audioTrack.enabled; |
||||
localMicOn ? setLocalMicOn(false) : setLocalMicOn(true); |
||||
isMuted = !isMuted; |
||||
} |
||||
} catch (err) { |
||||
console.error('Erro ao alterar microfone: ', err); |
||||
} |
||||
}; |
||||
|
||||
let isCamOn = true; |
||||
const toggleCamera = async () => { |
||||
try { |
||||
if (localStream) { |
||||
const videoTrack = await localStream.getVideoTracks()[0]; |
||||
videoTrack.enabled = !videoTrack.enabled; |
||||
localWebcamOn ? setLocalWebcamOn(false) : setLocalWebcamOn(true); |
||||
isCamOn = !isCamOn; |
||||
} |
||||
} catch (err) { |
||||
console.error('Erro inesperado ao desativar camera! ', err); |
||||
} |
||||
}; |
||||
|
||||
const toggleSpeaker = async () => { |
||||
console.log('Toggling speaker sound'); |
||||
}; |
||||
let isFrontCam = true; |
||||
const switchCamera = async () => { |
||||
try { |
||||
if (localStream) { |
||||
const videoTrack = await localStream.getVideoTracks()[0]; |
||||
videoTrack._switchCamera(); |
||||
isFrontCam = !isFrontCam; |
||||
} |
||||
} catch (err) { |
||||
console.error('Erro ao inverter camera: ', err); |
||||
} |
||||
}; |
||||
|
||||
const captureMidias = async () => { |
||||
// Obter a local track
|
||||
const senders = await peerConnectionRef.current.getSenders(); |
||||
const localStream = new MediaStream(); |
||||
senders.forEach(sender => { |
||||
if (sender.track) { |
||||
localStream.addTrack(sender.track); |
||||
} |
||||
}); |
||||
setLocalStream(localStream); |
||||
// Obter a remote track
|
||||
const receivers = await peerConnectionRef.current.getReceivers(); |
||||
const remoteStream = new MediaStream(); |
||||
receivers.forEach(receiver => { |
||||
if (receiver.track) { |
||||
remoteStream.addTrack(receiver.track); |
||||
} |
||||
}); |
||||
setRemoteStream(remoteStream); |
||||
navigation.dispatch(StackActions.replace('roomConference')); |
||||
InCallManager.setKeepScreenOn(true); |
||||
InCallManager.setSpeakerphoneOn(true); |
||||
}; |
||||
|
||||
const contextValues = useMemo( |
||||
() => ({ |
||||
session, |
||||
incommingCaller, |
||||
setCalle, |
||||
localMicOn, |
||||
setLocalMicOn, |
||||
localWebcamOn, |
||||
setLocalWebcamOn, |
||||
localStream, |
||||
remoteStream, |
||||
handleAceitarChamada, |
||||
handleEndCall, |
||||
handleIniciarChamada, |
||||
statusColor, |
||||
toggleCamera, |
||||
toggleMic, |
||||
toggleSpeaker, |
||||
switchCamera, |
||||
calle, |
||||
}), |
||||
[ |
||||
session, |
||||
incommingCaller, |
||||
setCalle, |
||||
localMicOn, |
||||
setLocalMicOn, |
||||
localWebcamOn, |
||||
setLocalWebcamOn, |
||||
localStream, |
||||
remoteStream, |
||||
handleAceitarChamada, |
||||
handleEndCall, |
||||
handleIniciarChamada, |
||||
statusColor, |
||||
calle, |
||||
], |
||||
); |
||||
return ( |
||||
<CallContext.Provider value={contextValues}> |
||||
{children} |
||||
</CallContext.Provider> |
||||
); |
||||
}; |
@ -1,11 +0,0 @@
|
||||
import React from 'react'; |
||||
import {AuthProvider} from './AuthContext'; |
||||
import {CallProvider} from './CallContext'; |
||||
|
||||
const CombinedProvider = ({children}) => ( |
||||
<AuthProvider> |
||||
<CallProvider>{children}</CallProvider> |
||||
</AuthProvider> |
||||
); |
||||
|
||||
export default CombinedProvider; |
@ -1,145 +0,0 @@
|
||||
import {View, Text} from 'react-native'; |
||||
import {RTCView} from 'react-native-webrtc'; |
||||
import styles from './styles'; |
||||
import React, {useContext, useState} from 'react'; |
||||
import {CallContext} from '../../context/CallContext'; |
||||
import IconContainer from '../../../components/IconContainer'; |
||||
import MicOn from '../../../components/MicOn'; |
||||
import MicOff from '../../../components/MicOff'; |
||||
import CallEnd from '../../../components/CallEnd'; |
||||
import VideoOn from '../../../components/VideoOn'; |
||||
import VideoOff from '../../../components/VideoOff'; |
||||
// import VivaVozIcon from '../../../components/VivaVoz';
|
||||
import CameraSwitch from '../../../components/CameraSwitch'; |
||||
import DialpadModal from '../ModalKeyPad/ModalKeyPad'; |
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; |
||||
|
||||
const ConferenceScreen = () => { |
||||
const { |
||||
remoteStream, |
||||
localStream, |
||||
handleEndCall, |
||||
toggleMic, |
||||
toggleCamera, |
||||
// toggleSpeaker,
|
||||
switchCamera, |
||||
localWebcamOn, |
||||
localMicOn, |
||||
} = useContext(CallContext); |
||||
|
||||
const [isDialpadVisible, setDialpadVisible] = useState(false); |
||||
return ( |
||||
<View |
||||
style={{ |
||||
flex: 1, |
||||
backgroundColor: '#050A0E', |
||||
paddingHorizontal: 12, |
||||
paddingVertical: 12, |
||||
}}> |
||||
{remoteStream ? ( |
||||
<RTCView |
||||
mirror={true} |
||||
objectFit={'cover'} |
||||
style={{ |
||||
flex: 1, |
||||
backgroundColor: '#050A0E', |
||||
marginTop: 8, |
||||
}} |
||||
streamURL={remoteStream.toURL()} |
||||
/> |
||||
) : null} |
||||
{localStream ? ( |
||||
<RTCView |
||||
mirror={true} |
||||
objectFit={'cover'} |
||||
style={{flex: 1, backgroundColor: '#050A0E'}} |
||||
streamURL={localStream.toURL()} |
||||
/> |
||||
) : null} |
||||
<View |
||||
style={{ |
||||
marginVertical: 12, |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-evenly', |
||||
}}> |
||||
<IconContainer |
||||
backgroundColor={'red'} |
||||
onPress={handleEndCall} |
||||
Icon={() => { |
||||
return <CallEnd height={26} width={26} fill="#FFF" />; |
||||
}} |
||||
/> |
||||
<IconContainer |
||||
style={{ |
||||
borderWidth: 1.5, |
||||
borderColor: '#2B3034', |
||||
}} |
||||
backgroundColor={!localMicOn ? '#fff' : 'transparent'} |
||||
onPress={toggleMic} |
||||
Icon={() => { |
||||
return localMicOn ? ( |
||||
<MicOn height={24} width={24} fill="#FFF" /> |
||||
) : ( |
||||
<MicOff height={28} width={28} fill="#1D2939" /> |
||||
); |
||||
}} |
||||
/> |
||||
<IconContainer |
||||
style={{ |
||||
borderWidth: 1.5, |
||||
borderColor: '#2B3034', |
||||
}} |
||||
backgroundColor={!localWebcamOn ? '#fff' : 'transparent'} |
||||
onPress={toggleCamera} |
||||
Icon={() => { |
||||
return localWebcamOn ? ( |
||||
<VideoOn height={24} width={24} fill="#FFF" /> |
||||
) : ( |
||||
<VideoOff height={36} width={36} fill="#1D2939" /> |
||||
); |
||||
}} |
||||
/> |
||||
|
||||
{/* <IconContainer |
||||
style={{ |
||||
borderWidth: 1.5, |
||||
borderColor: '#2B3034', |
||||
}} |
||||
onPress={toggleSpeaker} |
||||
Icon={() => { |
||||
return <VivaVozIcon width={24} height={24} fill="#FFF" />; |
||||
}} |
||||
/> */} |
||||
|
||||
<IconContainer |
||||
style={{ |
||||
borderWidth: 1.5, |
||||
borderColor: '#2B3034', |
||||
}} |
||||
backgroundColor={'transparent'} |
||||
onPress={switchCamera} |
||||
Icon={() => { |
||||
return <CameraSwitch height={24} width={24} fill="#FFF" />; |
||||
}} |
||||
/> |
||||
<IconContainer |
||||
style={{ |
||||
borderWidth: 1.5, |
||||
borderColor: '#2B3034', |
||||
}} |
||||
backgroundColor={'transparent'} |
||||
onPress={() => setDialpadVisible(true)} |
||||
Icon={() => { |
||||
return <Icon name={'dialpad'} size={30} color={'white'} />; |
||||
}} |
||||
/> |
||||
</View> |
||||
<DialpadModal |
||||
visible={isDialpadVisible} |
||||
onClose={() => setDialpadVisible(false)} |
||||
/> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
export default ConferenceScreen; |
@ -1,96 +0,0 @@
|
||||
import {useNavigation} from '@react-navigation/native'; |
||||
import React, {memo, useContext} from 'react'; |
||||
import {View, Text, TouchableOpacity} from 'react-native'; |
||||
import {Appbar, IconButton, RadioButton} from 'react-native-paper'; |
||||
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context'; |
||||
import styles from './styles'; |
||||
import LabeledInput from '../../../components/LabeledInput/function'; |
||||
import {AuthContext} from '../../context/AuthContext'; |
||||
|
||||
const ConfigScreen = () => { |
||||
const navigation = useNavigation(); |
||||
const {authData, handleInputChange, handleSubmit} = useContext(AuthContext); |
||||
|
||||
function handleNavigate(destiny) { |
||||
navigation.replace(destiny); |
||||
} |
||||
|
||||
return ( |
||||
<SafeAreaProvider> |
||||
<SafeAreaView style={styles.container}> |
||||
<Appbar.Header style={styles.header}> |
||||
<IconButton |
||||
icon={'arrow-left-bold-circle'} |
||||
size={30} |
||||
onPress={() => handleNavigate('home')} |
||||
/> |
||||
</Appbar.Header> |
||||
<Text style={styles.title}>Configurações</Text> |
||||
<View style={styles.configInputs}> |
||||
<View style={styles.radioButtonGroup}> |
||||
<RadioButton.Item |
||||
label="ws" |
||||
value="ws" |
||||
status={authData.protocolo === 'ws' ? 'checked' : 'unchecked'} |
||||
onPress={() => handleInputChange('protocolo', 'ws')} |
||||
labelStyle={{fontSize: 12}} |
||||
/> |
||||
<RadioButton.Item |
||||
label="wss" |
||||
value="wss" |
||||
status={authData.protocolo === 'wss' ? 'checked' : 'unchecked'} |
||||
onPress={() => handleInputChange('protocolo', 'wss')} |
||||
labelStyle={{fontSize: 12}} |
||||
/> |
||||
</View> |
||||
<LabeledInput |
||||
label="Servidor" |
||||
value={authData.servidor || ''} |
||||
onChangeText={value => handleInputChange('servidor', value)} |
||||
placeholder="Servidor" |
||||
keyboardType="default" |
||||
/> |
||||
<LabeledInput |
||||
label="Porta" |
||||
value={authData.porta || ''} |
||||
onChangeText={value => handleInputChange('porta', value)} |
||||
placeholder="Porta" |
||||
keyboardType="number-pad" |
||||
/> |
||||
<LabeledInput |
||||
label="Ramal" |
||||
value={authData.ramal || ''} |
||||
onChangeText={value => handleInputChange('ramal', value)} |
||||
placeholder="Ramal" |
||||
keyboardType="number-pad" |
||||
/> |
||||
<LabeledInput |
||||
label="Username" |
||||
value={authData.username || ''} |
||||
onChangeText={value => handleInputChange('username', value)} |
||||
placeholder="Username" |
||||
/> |
||||
<LabeledInput |
||||
label="Senha" |
||||
value={authData.senha || ''} |
||||
secureTextEntry={true} |
||||
onChangeText={value => handleInputChange('senha', value)} |
||||
placeholder="Senha" |
||||
/> |
||||
</View> |
||||
<TouchableOpacity onPress={handleSubmit}> |
||||
<View style={styles.viewBn}> |
||||
<Text style={styles.buttonSend}>Conectar</Text> |
||||
<IconButton |
||||
icon={'account-arrow-right-outline'} |
||||
iconColor="rgba(255,255,255,1)" |
||||
size={28} |
||||
/> |
||||
</View> |
||||
</TouchableOpacity> |
||||
</SafeAreaView> |
||||
</SafeAreaProvider> |
||||
); |
||||
}; |
||||
|
||||
export default memo(ConfigScreen); |
@ -1,74 +0,0 @@
|
||||
import {StyleSheet} from 'react-native'; |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
justifyContent: 'flex-start', |
||||
backgroundColor: 'rgba(9, 10, 32, 1)', |
||||
}, |
||||
header: { |
||||
width: '100%', |
||||
height: 60, |
||||
backgroundColor: 'rgba(17, 14, 38, 1)', |
||||
borderBottomLeftRadius: 8, |
||||
borderBottomRightRadius: 8, |
||||
}, |
||||
configInputs: { |
||||
marginTop: 20, |
||||
alignContent: 'center', |
||||
alignItems: 'stretch', |
||||
}, |
||||
label: { |
||||
fontSize: 12, |
||||
marginLeft: 4, |
||||
marginBottom: 1, |
||||
fontWeight: 'bold', |
||||
letterSpacing: 1, |
||||
}, |
||||
input: { |
||||
backgroundColor: 'rgba(8,20,55,0.6)', |
||||
borderRadius: 4, |
||||
paddingHorizontal: 10, |
||||
}, |
||||
buttonSend: { |
||||
color: 'rgba(255,255,255,1)', |
||||
fontSize: 16, |
||||
letterSpacing: 1, |
||||
fontWeight: 'bold', |
||||
alignSelf: 'center', |
||||
justifyContent: 'space-evenly', |
||||
}, |
||||
viewBn: { |
||||
display: 'flex', |
||||
flexDirection: 'row', |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
marginTop: 10, |
||||
backgroundColor: 'rgba(8,20,55,0.6)', |
||||
borderColor: '#5A54CE', |
||||
borderWidth: 1, |
||||
width: '46%', |
||||
alignSelf: 'center', |
||||
borderRadius: 4, |
||||
height: 40, |
||||
}, |
||||
containerLabel: { |
||||
marginHorizontal: 16, |
||||
marginVertical: 4, |
||||
}, |
||||
title: { |
||||
color: 'rgba(255,255,255,1)', |
||||
fontSize: 18, |
||||
alignSelf: 'center', |
||||
fontWeight: 'bold', |
||||
letterSpacing: 1, |
||||
marginTop: 10, |
||||
}, |
||||
radioButtonGroup: { |
||||
flexDirection: 'row', |
||||
alignSelf: 'center', |
||||
marginTop: 5, |
||||
}, |
||||
}); |
||||
|
||||
export default styles; |
@ -1,53 +0,0 @@
|
||||
import React, {useContext} from 'react'; |
||||
import {View, Text, TouchableOpacity} from 'react-native'; |
||||
import * as Animatable from 'react-native-animatable'; |
||||
import styles from './styles'; |
||||
import {CallContext} from '../../context/CallContext'; |
||||
import CallAnswer from '../../../components/CallAnswer'; |
||||
import CallEnd from '../../../components/CallEnd'; |
||||
|
||||
const IncomingCallScreen = () => { |
||||
const {handleAceitarChamada, handleEndCall, incommingCaller} = |
||||
useContext(CallContext); |
||||
|
||||
const onPressAceitarChamada = () => { |
||||
handleAceitarChamada(); |
||||
}; |
||||
|
||||
const onPressEndCall = () => { |
||||
handleEndCall(); |
||||
}; |
||||
|
||||
return ( |
||||
<View style={styles.container}> |
||||
<View style={styles.centerContainer}> |
||||
<Text style={styles.callerText}> |
||||
Recebendo ligação de {incommingCaller} |
||||
</Text> |
||||
</View> |
||||
<View style={styles.buttonContainer}> |
||||
<TouchableOpacity onPress={onPressAceitarChamada}> |
||||
<Animatable.View |
||||
animation="pulse" |
||||
easing="ease-out" |
||||
iterationCount="infinite" |
||||
style={styles.callButton}> |
||||
<CallAnswer height={28} fill={'#fff'} style={styles.buttonIcon} /> |
||||
</Animatable.View> |
||||
</TouchableOpacity> |
||||
|
||||
<TouchableOpacity onPress={onPressEndCall}> |
||||
<Animatable.View |
||||
animation="pulse" |
||||
easing="ease-out" |
||||
iterationCount="infinite" |
||||
style={styles.callEndButton}> |
||||
<CallEnd width={50} height={12} style={styles.endButtonIcon} /> |
||||
</Animatable.View> |
||||
</TouchableOpacity> |
||||
</View> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
export default IncomingCallScreen; |
@ -1,55 +0,0 @@
|
||||
import {StyleSheet} from 'react-native'; |
||||
|
||||
export default StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
justifyContent: 'space-around', |
||||
backgroundColor: 'rgba(9, 10, 32, 1)', |
||||
}, |
||||
centerContainer: { |
||||
padding: 35, |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
borderRadius: 14, |
||||
}, |
||||
callerText: { |
||||
fontSize: 26, |
||||
marginTop: 15, |
||||
color: '#ffff', |
||||
}, |
||||
buttonContainer: { |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-evenly', |
||||
alignItems: 'center', |
||||
}, |
||||
callButton: { |
||||
backgroundColor: 'green', |
||||
borderRadius: 30, |
||||
height: 60, |
||||
aspectRatio: 1, |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
position: 'relative', |
||||
}, |
||||
callEndButton: { |
||||
backgroundColor: '#FF5D5D', |
||||
borderRadius: 30, |
||||
height: 60, |
||||
aspectRatio: 1, |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
position: 'relative', |
||||
}, |
||||
buttonIcon: { |
||||
position: 'absolute', |
||||
top: '50%', |
||||
left: '50%', |
||||
transform: [{translateX: -33}, {translateY: -15}], |
||||
}, |
||||
endButtonIcon: { |
||||
position: 'absolute', |
||||
top: '50%', |
||||
left: '50%', |
||||
transform: [{translateX: -25}, {translateY: -6}], |
||||
}, |
||||
}); |
@ -1,127 +0,0 @@
|
||||
import { |
||||
Keyboard, |
||||
KeyboardAvoidingView, |
||||
View, |
||||
Text, |
||||
TouchableWithoutFeedback, |
||||
TouchableOpacity, |
||||
Alert, |
||||
} from 'react-native'; |
||||
import React, {memo, useContext, useState, useEffect} from 'react'; |
||||
import Logo from '../../../components/Logo'; |
||||
import TextInputContainer from '../../../components/TextInputContainer'; |
||||
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context'; |
||||
import {IconButton, MD2Colors} from 'react-native-paper'; |
||||
import Icon from 'react-native-vector-icons/FontAwesome'; |
||||
import styles from './styles'; |
||||
import Clipboard from '@react-native-clipboard/clipboard'; |
||||
import {CallContext} from '../../context/CallContext'; |
||||
import {useNavigation} from '@react-navigation/native'; |
||||
import {AuthContext} from '../../context/AuthContext'; |
||||
|
||||
const handleCopyToClipboard = text => { |
||||
Clipboard.setString(text); |
||||
Alert.alert('Ramal copiado para área de transferência!'); |
||||
}; |
||||
|
||||
const JoinScreen = () => { |
||||
const {setCalle, handleIniciarChamada, statusColor} = useContext(CallContext); |
||||
const {authData} = useContext(AuthContext); |
||||
const navigation = useNavigation(); |
||||
const [number, setNumber] = useState(''); |
||||
const [callInitiated, setCallInitiated] = useState(false); |
||||
|
||||
const handleCall = async () => { |
||||
if (!number) { |
||||
Alert.alert('Por favor, insira o ramal para realizar a ligação.'); |
||||
return; |
||||
} |
||||
|
||||
setCalle(number); |
||||
setCallInitiated(true); |
||||
}; |
||||
|
||||
function handleNavigate(destiny) { |
||||
navigation.replace(destiny); |
||||
} |
||||
|
||||
// Efeito para monitorar quando a chamada deve ser iniciada
|
||||
useEffect(() => { |
||||
if (callInitiated) { |
||||
handleIniciarChamada(); |
||||
navigation.navigate('outgoingCall'); |
||||
setCallInitiated(false); |
||||
} |
||||
}, [callInitiated]); |
||||
|
||||
return ( |
||||
<SafeAreaProvider> |
||||
<KeyboardAvoidingView |
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'} |
||||
style={styles.container}> |
||||
<SafeAreaView style={styles.header}> |
||||
<View style={styles.viewBnConfig}> |
||||
<IconButton |
||||
style={styles.settingsButton} |
||||
icon={'account-cog'} |
||||
iconColor={MD2Colors.grey300} |
||||
size={30} |
||||
onPress={() => handleNavigate('configuracoes')} |
||||
/> |
||||
</View> |
||||
<View style={styles.logoContainer}> |
||||
<Text style={styles.subtitle}>Softphone</Text> |
||||
<Logo /> |
||||
</View> |
||||
</SafeAreaView> |
||||
<View style={styles.inner}> |
||||
<View |
||||
style={{ |
||||
display: 'flex', |
||||
flexDirection: 'row', |
||||
justifyContent: 'center', |
||||
width: '100%', |
||||
}}> |
||||
<Icon |
||||
name={'circle'} |
||||
color={statusColor} |
||||
size={20} |
||||
style={{marginHorizontal: 4}} |
||||
/> |
||||
<Text style={styles.titles}>{authData.username}</Text> |
||||
</View> |
||||
<TouchableOpacity |
||||
onPress={() => handleCopyToClipboard(authData.ramal)}> |
||||
<View style={styles.box}> |
||||
<Text style={styles.idCall}>{authData.ramal || '0000'}</Text> |
||||
</View> |
||||
</TouchableOpacity> |
||||
</View> |
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}> |
||||
<View style={styles.inner}> |
||||
<Text style={{fontSize: 14, color: 'rgba(255,255,255,1)'}}> |
||||
Insira o ramal para ligação |
||||
</Text> |
||||
<TextInputContainer |
||||
style={styles.textInput} |
||||
value={number} |
||||
setValue={setNumber} |
||||
keyboardType={'number-pad'} |
||||
/> |
||||
<View> |
||||
<IconButton |
||||
icon={'phone'} |
||||
size={45} |
||||
onPress={handleCall} |
||||
iconColor={MD2Colors.lightGreen300} |
||||
backgroundColor={MD2Colors.green900} |
||||
/> |
||||
</View> |
||||
</View> |
||||
</TouchableWithoutFeedback> |
||||
</KeyboardAvoidingView> |
||||
</SafeAreaProvider> |
||||
); |
||||
}; |
||||
|
||||
export default memo(JoinScreen); |
@ -1,87 +0,0 @@
|
||||
import {StyleSheet} from 'react-native'; |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
justifyContent: 'center', |
||||
padding: 12, |
||||
backgroundColor: 'rgba(9, 10, 32, 1)', |
||||
}, |
||||
viewBnConfig: { |
||||
width: '100%', |
||||
flexDirection: 'row', |
||||
justifyContent: 'flex-end', |
||||
position: 'relative', |
||||
top: 0, |
||||
}, |
||||
settingsButton: { |
||||
justifyContent: 'center', |
||||
alignSelf: 'center', |
||||
}, |
||||
logoContainer: { |
||||
alignItems: 'center', |
||||
marginBottom: 18, |
||||
}, |
||||
subtitle: { |
||||
fontSize: 16, |
||||
textAlign: 'center', |
||||
alignSelf: 'flex-start', |
||||
marginLeft: 34, |
||||
fontWeight: 'bold', |
||||
color: 'rgba(255,255,255,1)', |
||||
}, |
||||
inner: { |
||||
marginVertical: 10, |
||||
padding: 12, |
||||
backgroundColor: 'rgba(18, 20, 55, 0.3)', |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
borderRadius: 10, |
||||
}, |
||||
titles: { |
||||
fontSize: 16, |
||||
fontWeight: 'bold', |
||||
marginBottom: 4, |
||||
letterSpacing: 1, |
||||
color: 'rgba(255,255,255,1)', |
||||
}, |
||||
box: { |
||||
padding: 16, |
||||
alignItems: 'center', |
||||
marginBottom: 16, |
||||
}, |
||||
idCall: { |
||||
fontSize: 34, |
||||
fontWeight: 'bold', |
||||
color: 'rgba(255,255,255,1)', |
||||
letterSpacing: 6, |
||||
}, |
||||
buttonCall: { |
||||
backgroundColor: 'green', |
||||
borderRadius: 100, |
||||
paddingVertical: 12, |
||||
alignItems: 'center', |
||||
width: '60%', |
||||
marginTop: 16, |
||||
}, |
||||
textInput: { |
||||
borderRadius: 10, |
||||
margin: 10, |
||||
fontSize: 30, |
||||
justifyContent: 'center', |
||||
alignSelf: 'center', |
||||
fontWeight: 'bold', |
||||
height: 60, |
||||
width: '60%', |
||||
backgroundColor: 'rgba(255,255,255,0.1)', |
||||
color: 'rgba(255,255,255,1)', |
||||
}, |
||||
header: { |
||||
position: 'relative', |
||||
alignSelf: 'center', |
||||
top: -50, |
||||
height: 140, |
||||
}, |
||||
}); |
||||
|
||||
export default styles; |
@ -1,47 +0,0 @@
|
||||
import React, {useContext} from 'react'; |
||||
import {Modal, View, Text, TouchableOpacity, Alert} from 'react-native'; |
||||
import {CallContext} from '../../context/CallContext'; |
||||
import styles from './styles'; |
||||
|
||||
const DialpadModal = ({visible, onClose}) => { |
||||
const {session} = useContext(CallContext); |
||||
|
||||
const sendDTMF = tone => { |
||||
if (session) { |
||||
session.sendDTMF(tone); |
||||
console.log(`DTMF tone ${tone} sent`); |
||||
} else { |
||||
Alert.alert('Erro', 'Nenhuma sessão ativa para enviar DTMF'); |
||||
} |
||||
}; |
||||
|
||||
const renderButton = number => ( |
||||
<TouchableOpacity |
||||
key={number} |
||||
style={styles.button} |
||||
onPress={() => sendDTMF(number)}> |
||||
<Text style={styles.buttonText}>{number}</Text> |
||||
</TouchableOpacity> |
||||
); |
||||
|
||||
return ( |
||||
<Modal |
||||
animationType="slide" |
||||
transparent={true} |
||||
visible={visible} |
||||
onRequestClose={onClose}> |
||||
<View style={styles.modalContainer}> |
||||
<View style={styles.dialpad}> |
||||
{['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#'].map( |
||||
renderButton, |
||||
)} |
||||
</View> |
||||
<TouchableOpacity style={styles.closeButton} onPress={onClose}> |
||||
<Text style={styles.closeButtonText}>Fechar</Text> |
||||
</TouchableOpacity> |
||||
</View> |
||||
</Modal> |
||||
); |
||||
}; |
||||
|
||||
export default DialpadModal; |
@ -1,47 +0,0 @@
|
||||
import {StyleSheet} from 'react-native'; |
||||
|
||||
const styles = StyleSheet.create({ |
||||
modalContainer: { |
||||
flex: 1, |
||||
justifyContent: 'flex-end', |
||||
backgroundColor: 'rgba(0, 0, 0, 0.2)', |
||||
}, |
||||
dialpad: { |
||||
backgroundColor: 'rgba(0,0,0,0.9)', |
||||
padding: 25, |
||||
borderTopLeftRadius: 10, |
||||
borderTopRightRadius: 10, |
||||
alignItems: 'center', |
||||
flexDirection: 'row', |
||||
flexWrap: 'wrap', |
||||
justifyContent: 'center', |
||||
}, |
||||
button: { |
||||
width: 65, |
||||
height: 65, |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
margin: 5, |
||||
borderRadius: 35, |
||||
backgroundColor: 'rgba(128, 128, 128, 0.5)', |
||||
}, |
||||
buttonText: { |
||||
color: 'white', |
||||
fontSize: 26, |
||||
fontWeight: 'bold', |
||||
}, |
||||
closeButton: { |
||||
backgroundColor: 'rgba(255,0,0,0.9)', |
||||
padding: 14, |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
}, |
||||
closeButtonText: { |
||||
color: 'white', |
||||
fontSize: 18, |
||||
fontWeight: 'bold', |
||||
letterSpacing: 1, |
||||
}, |
||||
}); |
||||
|
||||
export default styles; |
@ -1,65 +0,0 @@
|
||||
import {View, Text, TouchableOpacity} from 'react-native'; |
||||
import * as Animatable from 'react-native-animatable'; |
||||
import styles from './styles'; |
||||
import React, {memo, useContext} from 'react'; |
||||
import {CallContext} from '../../context/CallContext'; |
||||
import CallEnd from '../../../components/CallEnd'; |
||||
|
||||
const OutgoingCallScreen = () => { |
||||
const {handleEndCall, calle} = useContext(CallContext); |
||||
|
||||
return ( |
||||
<View |
||||
style={{ |
||||
flex: 1, |
||||
justifyContent: 'space-around', |
||||
backgroundColor: 'rgba(9, 10, 32, 1)', |
||||
}}> |
||||
<View |
||||
style={{ |
||||
padding: 35, |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
borderRadius: 14, |
||||
}}> |
||||
<Text |
||||
style={{ |
||||
fontSize: 16, |
||||
color: '#D0D4DD', |
||||
}}> |
||||
Ligando para ... |
||||
</Text> |
||||
|
||||
<Text |
||||
style={{ |
||||
fontSize: 36, |
||||
marginTop: 12, |
||||
color: '#ffff', |
||||
letterSpacing: 6, |
||||
}}> |
||||
{calle} |
||||
</Text> |
||||
</View> |
||||
<View |
||||
style={{ |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
}}> |
||||
<TouchableOpacity |
||||
onPress={handleEndCall} |
||||
style={{ |
||||
backgroundColor: '#FF5D5D', |
||||
borderRadius: 30, |
||||
height: 60, |
||||
aspectRatio: 1, |
||||
justifyContent: 'center', |
||||
alignItems: 'center', |
||||
}}> |
||||
<CallEnd width={50} height={12} /> |
||||
</TouchableOpacity> |
||||
</View> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
export default memo(OutgoingCallScreen); |
@ -1,8 +0,0 @@
|
||||
module.exports = { |
||||
presets: ['module:metro-react-native-babel-preset'], |
||||
env: { |
||||
production: { |
||||
plugins: ['react-native-paper/babel'], |
||||
}, |
||||
}, |
||||
}; |
@ -1,44 +0,0 @@
|
||||
import React, {useState} from 'react'; |
||||
import {View, Text, TextInput} from 'react-native'; |
||||
import styles from './styles'; |
||||
|
||||
const LabeledInput = ({ |
||||
label, |
||||
value, |
||||
onChangeText, |
||||
placeholder, |
||||
secureTextEntry, |
||||
keyboardType, |
||||
}) => { |
||||
const [isFocused, setIsFocused] = useState(false); |
||||
|
||||
const handleFocus = () => { |
||||
setIsFocused(true); |
||||
}; |
||||
|
||||
const handleBlur = () => { |
||||
setIsFocused(false); |
||||
}; |
||||
|
||||
return ( |
||||
<View style={styles.containerLabel}> |
||||
<Text style={styles.label}>{label}</Text> |
||||
<TextInput |
||||
style={[ |
||||
styles.input, |
||||
{borderBottomWidth: isFocused ? 3 : 0}, |
||||
{borderColor: isFocused ? '#5A54CE' : 'transparent'}, |
||||
]} |
||||
value={value} |
||||
onChangeText={onChangeText} |
||||
placeholder={placeholder} |
||||
secureTextEntry={secureTextEntry} |
||||
keyboardType={keyboardType} |
||||
onFocus={handleFocus} |
||||
onBlur={handleBlur} |
||||
/> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
export default LabeledInput; |
@ -1,23 +0,0 @@
|
||||
import {StyleSheet} from 'react-native'; |
||||
const styles = StyleSheet.create({ |
||||
label: { |
||||
fontSize: 13, |
||||
marginLeft: 4, |
||||
marginBottom: 1, |
||||
fontWeight: 'bold', |
||||
letterSpacing: 1, |
||||
color: 'rgba(255,255,255,1)', |
||||
}, |
||||
input: { |
||||
backgroundColor: 'rgba(8,20,55,0.6)', |
||||
borderRadius: 4, |
||||
paddingHorizontal: 10, |
||||
color: 'rgba(255,255,255,0.8)', |
||||
}, |
||||
containerLabel: { |
||||
marginHorizontal: 16, |
||||
marginVertical: 4, |
||||
}, |
||||
}); |
||||
|
||||
export default styles; |
@ -1,18 +0,0 @@
|
||||
import {View, Image} from 'react-native'; |
||||
import LogoSvg from '../asset/src/logo_simples_ip.svg'; |
||||
import React from 'react'; |
||||
|
||||
const Logo = () => { |
||||
return ( |
||||
<View |
||||
style={{ |
||||
alignItems: 'center', |
||||
justifyContent: 'center', |
||||
width: '100%', |
||||
}}> |
||||
<LogoSvg width={'100%'} height={85} /> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
export default Logo; |
@ -1,20 +0,0 @@
|
||||
import React from 'react'; |
||||
import {View, TextInput} from 'react-native'; |
||||
const TextInputContainer = ({value, setValue, keyboardType, style}) => { |
||||
return ( |
||||
<View style={{width: '100%'}}> |
||||
<TextInput |
||||
style={style} |
||||
multiline={true} |
||||
numberOfLines={1} |
||||
cursorColor={'#EAEAEA'} |
||||
onChangeText={setValue} |
||||
value={value} |
||||
keyboardType={keyboardType} |
||||
textAlign="center" |
||||
/> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
export default TextInputContainer; |
@ -0,0 +1,44 @@
|
||||
# Miscellaneous |
||||
*.class |
||||
*.log |
||||
*.pyc |
||||
*.swp |
||||
.DS_Store |
||||
.atom/ |
||||
.buildlog/ |
||||
.history |
||||
.svn/ |
||||
migrate_working_dir/ |
||||
|
||||
# IntelliJ related |
||||
*.iml |
||||
*.ipr |
||||
*.iws |
||||
.idea/ |
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in |
||||
# VS Code which you may wish to be included in version control, so this line |
||||
# is commented out by default. |
||||
#.vscode/ |
||||
|
||||
# Flutter/Dart/Pub related |
||||
**/doc/api/ |
||||
**/ios/Flutter/.last_build_id |
||||
.dart_tool/ |
||||
.flutter-plugins |
||||
.flutter-plugins-dependencies |
||||
.packages |
||||
.pub-cache/ |
||||
.pub/ |
||||
/build/ |
||||
|
||||
# Symbolication related |
||||
app.*.symbols |
||||
|
||||
# Obfuscation related |
||||
app.*.map.json |
||||
|
||||
# Android Studio will place build artifacts here |
||||
/android/app/debug |
||||
/android/app/profile |
||||
/android/app/release |
@ -0,0 +1,45 @@
|
||||
# This file tracks properties of this Flutter project. |
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc. |
||||
# |
||||
# This file should be version controlled. |
||||
|
||||
version: |
||||
revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
channel: stable |
||||
|
||||
project_type: app |
||||
|
||||
# Tracks metadata for the flutter migrate command |
||||
migration: |
||||
platforms: |
||||
- platform: root |
||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
- platform: android |
||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
- platform: ios |
||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
- platform: linux |
||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
- platform: macos |
||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
- platform: web |
||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
- platform: windows |
||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a |
||||
|
||||
# User provided section |
||||
|
||||
# List of Local paths (relative to this file) that should be |
||||
# ignored by the migrate tool. |
||||
# |
||||
# Files that are not part of the templates will be ignored by default. |
||||
unmanaged_files: |
||||
- 'lib/main.dart' |
||||
- 'ios/Runner.xcodeproj/project.pbxproj' |
@ -0,0 +1,67 @@
|
||||
# WebRTC Flutter App |
||||
|
||||
## Clone Repository |
||||
|
||||
Clone the repository to your local environment. |
||||
|
||||
```sh |
||||
git clone https://github.com/videosdk-live/webrtc.git |
||||
``` |
||||
|
||||
### Server Setup |
||||
|
||||
#### Step 1: Go to webrtc-signalling-server folder |
||||
|
||||
```js |
||||
|
||||
cd webrtc-signalling-server |
||||
|
||||
``` |
||||
|
||||
#### Step 2: Install Dependency |
||||
|
||||
```js |
||||
|
||||
npm install |
||||
``` |
||||
|
||||
#### Step 3: Run the project |
||||
|
||||
```js |
||||
|
||||
npm run start |
||||
``` |
||||
|
||||
--- |
||||
|
||||
### Client Setup |
||||
|
||||
#### Step 1: Go to flutter_webrtc_app folder |
||||
|
||||
```dart |
||||
|
||||
cd flutter_webrtc_app |
||||
``` |
||||
|
||||
### Step 2: Get dependencies |
||||
|
||||
```dart |
||||
flutter pub get |
||||
``` |
||||
|
||||
### Step 3: Update Signalling Server URL |
||||
|
||||
in main.dart file, update the websocket url. |
||||
|
||||
```dart |
||||
// signalling server url |
||||
final String websocketUrl = "SIGNALLING_SERVER_URL"; |
||||
``` |
||||
|
||||
### Step 4: Run the sample app |
||||
|
||||
Bingo, it's time to push the launch button. |
||||
|
||||
```dart |
||||
flutter run |
||||
``` |
@ -0,0 +1,29 @@
|
||||
# This file configures the analyzer, which statically analyzes Dart code to |
||||
# check for errors, warnings, and lints. |
||||
# |
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled |
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be |
||||
# invoked from the command line by running `flutter analyze`. |
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps, |
||||
# packages, and plugins designed to encourage good coding practices. |
||||
include: package:flutter_lints/flutter.yaml |
||||
|
||||
linter: |
||||
# The lint rules applied to this project can be customized in the |
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml` |
||||
# included above or to enable additional rules. A list of all available lints |
||||
# and their documentation is published at |
||||
# https://dart-lang.github.io/linter/lints/index.html. |
||||
# |
||||
# Instead of disabling a lint rule for the entire project in the |
||||
# section below, it can also be suppressed for a single line of code |
||||
# or a specific dart file by using the `// ignore: name_of_lint` and |
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file |
||||
# producing the lint. |
||||
rules: |
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule |
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule |
||||
|
||||
# Additional information about this file can be found at |
||||
# https://dart.dev/guides/language/analysis-options |
@ -0,0 +1,13 @@
|
||||
gradle-wrapper.jar |
||||
/.gradle |
||||
/captures/ |
||||
/gradlew |
||||
/gradlew.bat |
||||
/local.properties |
||||
GeneratedPluginRegistrant.java |
||||
|
||||
# Remember to never publicly share your keystore. |
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app |
||||
key.properties |
||||
**/*.keystore |
||||
**/*.jks |
@ -0,0 +1,71 @@
|
||||
def localProperties = new Properties() |
||||
def localPropertiesFile = rootProject.file('local.properties') |
||||
if (localPropertiesFile.exists()) { |
||||
localPropertiesFile.withReader('UTF-8') { reader -> |
||||
localProperties.load(reader) |
||||
} |
||||
} |
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk') |
||||
if (flutterRoot == null) { |
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") |
||||
} |
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode') |
||||
if (flutterVersionCode == null) { |
||||
flutterVersionCode = '1' |
||||
} |
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName') |
||||
if (flutterVersionName == null) { |
||||
flutterVersionName = '1.0' |
||||
} |
||||
|
||||
apply plugin: 'com.android.application' |
||||
apply plugin: 'kotlin-android' |
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" |
||||
|
||||
android { |
||||
compileSdkVersion flutter.compileSdkVersion |
||||
ndkVersion flutter.ndkVersion |
||||
|
||||
compileOptions { |
||||
sourceCompatibility JavaVersion.VERSION_1_8 |
||||
targetCompatibility JavaVersion.VERSION_1_8 |
||||
} |
||||
|
||||
kotlinOptions { |
||||
jvmTarget = '1.8' |
||||
} |
||||
|
||||
sourceSets { |
||||
main.java.srcDirs += 'src/main/kotlin' |
||||
} |
||||
|
||||
defaultConfig { |
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). |
||||
applicationId "com.example.flutter_webrtc_app" |
||||
// You can update the following values to match your application needs. |
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. |
||||
minSdkVersion 23 |
||||
targetSdkVersion flutter.targetSdkVersion |
||||
versionCode flutterVersionCode.toInteger() |
||||
versionName flutterVersionName |
||||
} |
||||
|
||||
buildTypes { |
||||
release { |
||||
// TODO: Add your own signing config for the release build. |
||||
// Signing with the debug keys for now, so `flutter run --release` works. |
||||
signingConfig signingConfigs.debug |
||||
} |
||||
} |
||||
} |
||||
|
||||
flutter { |
||||
source '../..' |
||||
} |
||||
|
||||
dependencies { |
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" |
||||
} |
@ -0,0 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="com.example.flutter_webrtc_app"> |
||||
<!-- The INTERNET permission is required for development. Specifically, |
||||
the Flutter tool needs it to communicate with the running application |
||||
to allow setting breakpoints, to provide hot reload, etc. |
||||
--> |
||||
<uses-permission android:name="android.permission.INTERNET"/> |
||||
</manifest> |
@ -0,0 +1,45 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="com.example.flutter_webrtc_app"> |
||||
|
||||
<uses-feature android:name="android.hardware.camera" /> |
||||
<uses-feature android:name="android.hardware.camera.autofocus" /> |
||||
<uses-permission android:name="android.permission.CAMERA" /> |
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" /> |
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> |
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> |
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> |
||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> |
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> |
||||
|
||||
<application |
||||
android:label="flutter_webrtc_app" |
||||
android:name="${applicationName}" |
||||
android:icon="@mipmap/ic_launcher"> |
||||
<activity |
||||
android:name=".MainActivity" |
||||
android:exported="true" |
||||
android:launchMode="singleTop" |
||||
android:theme="@style/LaunchTheme" |
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" |
||||
android:hardwareAccelerated="true" |
||||
android:windowSoftInputMode="adjustResize"> |
||||
<!-- Specifies an Android theme to apply to this Activity as soon as |
||||
the Android process has started. This theme is visible to the user |
||||
while the Flutter UI initializes. After that, this theme continues |
||||
to determine the Window background behind the Flutter UI. --> |
||||
<meta-data |
||||
android:name="io.flutter.embedding.android.NormalTheme" |
||||
android:resource="@style/NormalTheme" |
||||
/> |
||||
<intent-filter> |
||||
<action android:name="android.intent.action.MAIN"/> |
||||
<category android:name="android.intent.category.LAUNCHER"/> |
||||
</intent-filter> |
||||
</activity> |
||||
<!-- Don't delete the meta-data below. |
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> |
||||
<meta-data |
||||
android:name="flutterEmbedding" |
||||
android:value="2" /> |
||||
</application> |
||||
</manifest> |
@ -0,0 +1,6 @@
|
||||
package com.example.flutter_webrtc_app |
||||
|
||||
import io.flutter.embedding.android.FlutterActivity |
||||
|
||||
class MainActivity: FlutterActivity() { |
||||
} |
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- Modify this file to customize your launch splash screen --> |
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item android:drawable="?android:colorBackground" /> |
||||
|
||||
<!-- You can insert your own image assets here --> |
||||
<!-- <item> |
||||
<bitmap |
||||
android:gravity="center" |
||||
android:src="@mipmap/launch_image" /> |
||||
</item> --> |
||||
</layer-list> |
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- Modify this file to customize your launch splash screen --> |
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item android:drawable="@android:color/white" /> |
||||
|
||||
<!-- You can insert your own image assets here --> |
||||
<!-- <item> |
||||
<bitmap |
||||
android:gravity="center" |
||||
android:src="@mipmap/launch_image" /> |
||||
</item> --> |
||||
</layer-list> |
After Width: | Height: | Size: 544 B |
After Width: | Height: | Size: 442 B |
After Width: | Height: | Size: 721 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on --> |
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> |
||||
<!-- Show a splash screen on the activity. Automatically removed when |
||||
the Flutter engine draws its first frame --> |
||||
<item name="android:windowBackground">@drawable/launch_background</item> |
||||
</style> |
||||
<!-- Theme applied to the Android Window as soon as the process has started. |
||||
This theme determines the color of the Android Window while your |
||||
Flutter UI initializes, as well as behind your Flutter UI while its |
||||
running. |
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. --> |
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar"> |
||||
<item name="android:windowBackground">?android:colorBackground</item> |
||||
</style> |
||||
</resources> |
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off --> |
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar"> |
||||
<!-- Show a splash screen on the activity. Automatically removed when |
||||
the Flutter engine draws its first frame --> |
||||
<item name="android:windowBackground">@drawable/launch_background</item> |
||||
</style> |
||||
<!-- Theme applied to the Android Window as soon as the process has started. |
||||
This theme determines the color of the Android Window while your |
||||
Flutter UI initializes, as well as behind your Flutter UI while its |
||||
running. |
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. --> |
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar"> |
||||
<item name="android:windowBackground">?android:colorBackground</item> |
||||
</style> |
||||
</resources> |
@ -0,0 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="com.example.flutter_webrtc_app"> |
||||
<!-- The INTERNET permission is required for development. Specifically, |
||||
the Flutter tool needs it to communicate with the running application |
||||
to allow setting breakpoints, to provide hot reload, etc. |
||||
--> |
||||
<uses-permission android:name="android.permission.INTERNET"/> |
||||
</manifest> |
@ -0,0 +1,31 @@
|
||||
buildscript { |
||||
ext.kotlin_version = '1.7.10' |
||||
repositories { |
||||
google() |
||||
mavenCentral() |
||||
} |
||||
|
||||
dependencies { |
||||
classpath 'com.android.tools.build:gradle:7.2.0' |
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |
||||
} |
||||
} |
||||
|
||||
allprojects { |
||||
repositories { |
||||
google() |
||||
mavenCentral() |
||||
} |
||||
} |
||||
|
||||
rootProject.buildDir = '../build' |
||||
subprojects { |
||||
project.buildDir = "${rootProject.buildDir}/${project.name}" |
||||
} |
||||
subprojects { |
||||
project.evaluationDependsOn(':app') |
||||
} |
||||
|
||||
task clean(type: Delete) { |
||||
delete rootProject.buildDir |
||||
} |
@ -0,0 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx1536M |
||||
android.useAndroidX=true |
||||
android.enableJetifier=true |
@ -1,7 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME |
||||
distributionPath=wrapper/dists |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip |
||||
networkTimeout=10000 |
||||
validateDistributionUrl=true |
||||
zipStoreBase=GRADLE_USER_HOME |
||||
zipStorePath=wrapper/dists |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip |
@ -0,0 +1,11 @@
|
||||
include ':app' |
||||
|
||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties") |
||||
def properties = new Properties() |
||||
|
||||
assert localPropertiesFile.exists() |
||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } |
||||
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk") |
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties" |
||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" |
@ -0,0 +1,34 @@
|
||||
**/dgph |
||||
*.mode1v3 |
||||
*.mode2v3 |
||||
*.moved-aside |
||||
*.pbxuser |
||||
*.perspectivev3 |
||||
**/*sync/ |
||||
.sconsign.dblite |
||||
.tags* |
||||
**/.vagrant/ |
||||
**/DerivedData/ |
||||
Icon? |
||||
**/Pods/ |
||||
**/.symlinks/ |
||||
profile |
||||
xcuserdata |
||||
**/.generated/ |
||||
Flutter/App.framework |
||||
Flutter/Flutter.framework |
||||
Flutter/Flutter.podspec |
||||
Flutter/Generated.xcconfig |
||||
Flutter/ephemeral/ |
||||
Flutter/app.flx |
||||
Flutter/app.zip |
||||
Flutter/flutter_assets/ |
||||
Flutter/flutter_export_environment.sh |
||||
ServiceDefinitions.json |
||||
Runner/GeneratedPluginRegistrant.* |
||||
|
||||
# Exceptions to above rules. |
||||
!default.mode1v3 |
||||
!default.mode2v3 |
||||
!default.pbxuser |
||||
!default.perspectivev3 |
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>CFBundleDevelopmentRegion</key> |
||||
<string>en</string> |
||||
<key>CFBundleExecutable</key> |
||||
<string>App</string> |
||||
<key>CFBundleIdentifier</key> |
||||
<string>io.flutter.flutter.app</string> |
||||
<key>CFBundleInfoDictionaryVersion</key> |
||||
<string>6.0</string> |
||||
<key>CFBundleName</key> |
||||
<string>App</string> |
||||
<key>CFBundlePackageType</key> |
||||
<string>FMWK</string> |
||||
<key>CFBundleShortVersionString</key> |
||||
<string>1.0</string> |
||||
<key>CFBundleSignature</key> |
||||
<string>????</string> |
||||
<key>CFBundleVersion</key> |
||||
<string>1.0</string> |
||||
<key>MinimumOSVersion</key> |
||||
<string>11.0</string> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1 @@
|
||||
#include "Generated.xcconfig" |
@ -0,0 +1 @@
|
||||
#include "Generated.xcconfig" |
@ -0,0 +1,483 @@
|
||||
// !$*UTF8*$! |
||||
{ |
||||
archiveVersion = 1; |
||||
classes = { |
||||
}; |
||||
objectVersion = 54; |
||||
objects = { |
||||
|
||||
/* Begin PBXBuildFile section */ |
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; |
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; |
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; |
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; |
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; |
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; |
||||
/* End PBXBuildFile section */ |
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */ |
||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = { |
||||
isa = PBXCopyFilesBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
dstPath = ""; |
||||
dstSubfolderSpec = 10; |
||||
files = ( |
||||
); |
||||
name = "Embed Frameworks"; |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
}; |
||||
/* End PBXCopyFilesBuildPhase section */ |
||||
|
||||
/* Begin PBXFileReference section */ |
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; |
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; |
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; |
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; |
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; |
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; |
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; |
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; |
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; |
||||
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; |
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; |
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; |
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; |
||||
/* End PBXFileReference section */ |
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */ |
||||
97C146EB1CF9000F007C117D /* Frameworks */ = { |
||||
isa = PBXFrameworksBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
}; |
||||
/* End PBXFrameworksBuildPhase section */ |
||||
|
||||
/* Begin PBXGroup section */ |
||||
9740EEB11CF90186004384FC /* Flutter */ = { |
||||
isa = PBXGroup; |
||||
children = ( |
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, |
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */, |
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */, |
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */, |
||||
); |
||||
name = Flutter; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
97C146E51CF9000F007C117D = { |
||||
isa = PBXGroup; |
||||
children = ( |
||||
9740EEB11CF90186004384FC /* Flutter */, |
||||
97C146F01CF9000F007C117D /* Runner */, |
||||
97C146EF1CF9000F007C117D /* Products */, |
||||
); |
||||
sourceTree = "<group>"; |
||||
}; |
||||
97C146EF1CF9000F007C117D /* Products */ = { |
||||
isa = PBXGroup; |
||||
children = ( |
||||
97C146EE1CF9000F007C117D /* Runner.app */, |
||||
); |
||||
name = Products; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
97C146F01CF9000F007C117D /* Runner */ = { |
||||
isa = PBXGroup; |
||||
children = ( |
||||
97C146FA1CF9000F007C117D /* Main.storyboard */, |
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */, |
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, |
||||
97C147021CF9000F007C117D /* Info.plist */, |
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, |
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, |
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */, |
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, |
||||
); |
||||
path = Runner; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
/* End PBXGroup section */ |
||||
|
||||
/* Begin PBXNativeTarget section */ |
||||
97C146ED1CF9000F007C117D /* Runner */ = { |
||||
isa = PBXNativeTarget; |
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; |
||||
buildPhases = ( |
||||
9740EEB61CF901F6004384FC /* Run Script */, |
||||
97C146EA1CF9000F007C117D /* Sources */, |
||||
97C146EB1CF9000F007C117D /* Frameworks */, |
||||
97C146EC1CF9000F007C117D /* Resources */, |
||||
9705A1C41CF9048500538489 /* Embed Frameworks */, |
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */, |
||||
); |
||||
buildRules = ( |
||||
); |
||||
dependencies = ( |
||||
); |
||||
name = Runner; |
||||
productName = Runner; |
||||
productReference = 97C146EE1CF9000F007C117D /* Runner.app */; |
||||
productType = "com.apple.product-type.application"; |
||||
}; |
||||
/* End PBXNativeTarget section */ |
||||
|
||||
/* Begin PBXProject section */ |
||||
97C146E61CF9000F007C117D /* Project object */ = { |
||||
isa = PBXProject; |
||||
attributes = { |
||||
LastUpgradeCheck = 1300; |
||||
ORGANIZATIONNAME = ""; |
||||
TargetAttributes = { |
||||
97C146ED1CF9000F007C117D = { |
||||
CreatedOnToolsVersion = 7.3.1; |
||||
LastSwiftMigration = 1100; |
||||
}; |
||||
}; |
||||
}; |
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; |
||||
compatibilityVersion = "Xcode 9.3"; |
||||
developmentRegion = en; |
||||
hasScannedForEncodings = 0; |
||||
knownRegions = ( |
||||
en, |
||||
Base, |
||||
); |
||||
mainGroup = 97C146E51CF9000F007C117D; |
||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */; |
||||
projectDirPath = ""; |
||||
projectRoot = ""; |
||||
targets = ( |
||||
97C146ED1CF9000F007C117D /* Runner */, |
||||
); |
||||
}; |
||||
/* End PBXProject section */ |
||||
|
||||
/* Begin PBXResourcesBuildPhase section */ |
||||
97C146EC1CF9000F007C117D /* Resources */ = { |
||||
isa = PBXResourcesBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, |
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, |
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, |
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
}; |
||||
/* End PBXResourcesBuildPhase section */ |
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */ |
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { |
||||
isa = PBXShellScriptBuildPhase; |
||||
alwaysOutOfDate = 1; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
); |
||||
inputPaths = ( |
||||
); |
||||
name = "Thin Binary"; |
||||
outputPaths = ( |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
shellPath = /bin/sh; |
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; |
||||
}; |
||||
9740EEB61CF901F6004384FC /* Run Script */ = { |
||||
isa = PBXShellScriptBuildPhase; |
||||
alwaysOutOfDate = 1; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
); |
||||
inputPaths = ( |
||||
); |
||||
name = "Run Script"; |
||||
outputPaths = ( |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
shellPath = /bin/sh; |
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; |
||||
}; |
||||
/* End PBXShellScriptBuildPhase section */ |
||||
|
||||
/* Begin PBXSourcesBuildPhase section */ |
||||
97C146EA1CF9000F007C117D /* Sources */ = { |
||||
isa = PBXSourcesBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, |
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
}; |
||||
/* End PBXSourcesBuildPhase section */ |
||||
|
||||
/* Begin PBXVariantGroup section */ |
||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = { |
||||
isa = PBXVariantGroup; |
||||
children = ( |
||||
97C146FB1CF9000F007C117D /* Base */, |
||||
); |
||||
name = Main.storyboard; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { |
||||
isa = PBXVariantGroup; |
||||
children = ( |
||||
97C147001CF9000F007C117D /* Base */, |
||||
); |
||||
name = LaunchScreen.storyboard; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
/* End PBXVariantGroup section */ |
||||
|
||||
/* Begin XCBuildConfiguration section */ |
||||
249021D3217E4FDB00AE95B9 /* Profile */ = { |
||||
isa = XCBuildConfiguration; |
||||
buildSettings = { |
||||
ALWAYS_SEARCH_USER_PATHS = NO; |
||||
CLANG_ANALYZER_NONNULL = YES; |
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; |
||||
CLANG_CXX_LIBRARY = "libc++"; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CLANG_ENABLE_OBJC_ARC = YES; |
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; |
||||
CLANG_WARN_BOOL_CONVERSION = YES; |
||||
CLANG_WARN_COMMA = YES; |
||||
CLANG_WARN_CONSTANT_CONVERSION = YES; |
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; |
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; |
||||
CLANG_WARN_EMPTY_BODY = YES; |
||||
CLANG_WARN_ENUM_CONVERSION = YES; |
||||
CLANG_WARN_INFINITE_RECURSION = YES; |
||||
CLANG_WARN_INT_CONVERSION = YES; |
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; |
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; |
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; |
||||
CLANG_WARN_STRICT_PROTOTYPES = YES; |
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES; |
||||
CLANG_WARN_UNREACHABLE_CODE = YES; |
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; |
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
||||
COPY_PHASE_STRIP = NO; |
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; |
||||
ENABLE_NS_ASSERTIONS = NO; |
||||
ENABLE_STRICT_OBJC_MSGSEND = YES; |
||||
GCC_C_LANGUAGE_STANDARD = gnu99; |
||||
GCC_NO_COMMON_BLOCKS = YES; |
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
||||
GCC_WARN_UNDECLARED_SELECTOR = YES; |
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
||||
GCC_WARN_UNUSED_FUNCTION = YES; |
||||
GCC_WARN_UNUSED_VARIABLE = YES; |
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0; |
||||
MTL_ENABLE_DEBUG_INFO = NO; |
||||
SDKROOT = iphoneos; |
||||
SUPPORTED_PLATFORMS = iphoneos; |
||||
TARGETED_DEVICE_FAMILY = "1,2"; |
||||
VALIDATE_PRODUCT = YES; |
||||
}; |
||||
name = Profile; |
||||
}; |
||||
249021D4217E4FDB00AE95B9 /* Profile */ = { |
||||
isa = XCBuildConfiguration; |
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; |
||||
buildSettings = { |
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
||||
ENABLE_BITCODE = NO; |
||||
INFOPLIST_FILE = Runner/Info.plist; |
||||
LD_RUNPATH_SEARCH_PATHS = ( |
||||
"$(inherited)", |
||||
"@executable_path/Frameworks", |
||||
); |
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebrtcApp; |
||||
PRODUCT_NAME = "$(TARGET_NAME)"; |
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
||||
SWIFT_VERSION = 5.0; |
||||
VERSIONING_SYSTEM = "apple-generic"; |
||||
}; |
||||
name = Profile; |
||||
}; |
||||
97C147031CF9000F007C117D /* Debug */ = { |
||||
isa = XCBuildConfiguration; |
||||
buildSettings = { |
||||
ALWAYS_SEARCH_USER_PATHS = NO; |
||||
CLANG_ANALYZER_NONNULL = YES; |
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; |
||||
CLANG_CXX_LIBRARY = "libc++"; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CLANG_ENABLE_OBJC_ARC = YES; |
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; |
||||
CLANG_WARN_BOOL_CONVERSION = YES; |
||||
CLANG_WARN_COMMA = YES; |
||||
CLANG_WARN_CONSTANT_CONVERSION = YES; |
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; |
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; |
||||
CLANG_WARN_EMPTY_BODY = YES; |
||||
CLANG_WARN_ENUM_CONVERSION = YES; |
||||
CLANG_WARN_INFINITE_RECURSION = YES; |
||||
CLANG_WARN_INT_CONVERSION = YES; |
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; |
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; |
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; |
||||
CLANG_WARN_STRICT_PROTOTYPES = YES; |
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES; |
||||
CLANG_WARN_UNREACHABLE_CODE = YES; |
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; |
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
||||
COPY_PHASE_STRIP = NO; |
||||
DEBUG_INFORMATION_FORMAT = dwarf; |
||||
ENABLE_STRICT_OBJC_MSGSEND = YES; |
||||
ENABLE_TESTABILITY = YES; |
||||
GCC_C_LANGUAGE_STANDARD = gnu99; |
||||
GCC_DYNAMIC_NO_PIC = NO; |
||||
GCC_NO_COMMON_BLOCKS = YES; |
||||
GCC_OPTIMIZATION_LEVEL = 0; |
||||
GCC_PREPROCESSOR_DEFINITIONS = ( |
||||
"DEBUG=1", |
||||
"$(inherited)", |
||||
); |
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
||||
GCC_WARN_UNDECLARED_SELECTOR = YES; |
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
||||
GCC_WARN_UNUSED_FUNCTION = YES; |
||||
GCC_WARN_UNUSED_VARIABLE = YES; |
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0; |
||||
MTL_ENABLE_DEBUG_INFO = YES; |
||||
ONLY_ACTIVE_ARCH = YES; |
||||
SDKROOT = iphoneos; |
||||
TARGETED_DEVICE_FAMILY = "1,2"; |
||||
}; |
||||
name = Debug; |
||||
}; |
||||
97C147041CF9000F007C117D /* Release */ = { |
||||
isa = XCBuildConfiguration; |
||||
buildSettings = { |
||||
ALWAYS_SEARCH_USER_PATHS = NO; |
||||
CLANG_ANALYZER_NONNULL = YES; |
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; |
||||
CLANG_CXX_LIBRARY = "libc++"; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CLANG_ENABLE_OBJC_ARC = YES; |
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; |
||||
CLANG_WARN_BOOL_CONVERSION = YES; |
||||
CLANG_WARN_COMMA = YES; |
||||
CLANG_WARN_CONSTANT_CONVERSION = YES; |
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; |
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; |
||||
CLANG_WARN_EMPTY_BODY = YES; |
||||
CLANG_WARN_ENUM_CONVERSION = YES; |
||||
CLANG_WARN_INFINITE_RECURSION = YES; |
||||
CLANG_WARN_INT_CONVERSION = YES; |
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; |
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; |
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; |
||||
CLANG_WARN_STRICT_PROTOTYPES = YES; |
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES; |
||||
CLANG_WARN_UNREACHABLE_CODE = YES; |
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; |
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
||||
COPY_PHASE_STRIP = NO; |
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; |
||||
ENABLE_NS_ASSERTIONS = NO; |
||||
ENABLE_STRICT_OBJC_MSGSEND = YES; |
||||
GCC_C_LANGUAGE_STANDARD = gnu99; |
||||
GCC_NO_COMMON_BLOCKS = YES; |
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
||||
GCC_WARN_UNDECLARED_SELECTOR = YES; |
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
||||
GCC_WARN_UNUSED_FUNCTION = YES; |
||||
GCC_WARN_UNUSED_VARIABLE = YES; |
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0; |
||||
MTL_ENABLE_DEBUG_INFO = NO; |
||||
SDKROOT = iphoneos; |
||||
SUPPORTED_PLATFORMS = iphoneos; |
||||
SWIFT_COMPILATION_MODE = wholemodule; |
||||
SWIFT_OPTIMIZATION_LEVEL = "-O"; |
||||
TARGETED_DEVICE_FAMILY = "1,2"; |
||||
VALIDATE_PRODUCT = YES; |
||||
}; |
||||
name = Release; |
||||
}; |
||||
97C147061CF9000F007C117D /* Debug */ = { |
||||
isa = XCBuildConfiguration; |
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; |
||||
buildSettings = { |
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
||||
ENABLE_BITCODE = NO; |
||||
INFOPLIST_FILE = Runner/Info.plist; |
||||
LD_RUNPATH_SEARCH_PATHS = ( |
||||
"$(inherited)", |
||||
"@executable_path/Frameworks", |
||||
); |
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebrtcApp; |
||||
PRODUCT_NAME = "$(TARGET_NAME)"; |
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; |
||||
SWIFT_VERSION = 5.0; |
||||
VERSIONING_SYSTEM = "apple-generic"; |
||||
}; |
||||
name = Debug; |
||||
}; |
||||
97C147071CF9000F007C117D /* Release */ = { |
||||
isa = XCBuildConfiguration; |
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; |
||||
buildSettings = { |
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
||||
ENABLE_BITCODE = NO; |
||||
INFOPLIST_FILE = Runner/Info.plist; |
||||
LD_RUNPATH_SEARCH_PATHS = ( |
||||
"$(inherited)", |
||||
"@executable_path/Frameworks", |
||||
); |
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebrtcApp; |
||||
PRODUCT_NAME = "$(TARGET_NAME)"; |
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
||||
SWIFT_VERSION = 5.0; |
||||
VERSIONING_SYSTEM = "apple-generic"; |
||||
}; |
||||
name = Release; |
||||
}; |
||||
/* End XCBuildConfiguration section */ |
||||
|
||||
/* Begin XCConfigurationList section */ |
||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { |
||||
isa = XCConfigurationList; |
||||
buildConfigurations = ( |
||||
97C147031CF9000F007C117D /* Debug */, |
||||
97C147041CF9000F007C117D /* Release */, |
||||
249021D3217E4FDB00AE95B9 /* Profile */, |
||||
); |
||||
defaultConfigurationIsVisible = 0; |
||||
defaultConfigurationName = Release; |
||||
}; |
||||
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { |
||||
isa = XCConfigurationList; |
||||
buildConfigurations = ( |
||||
97C147061CF9000F007C117D /* Debug */, |
||||
97C147071CF9000F007C117D /* Release */, |
||||
249021D4217E4FDB00AE95B9 /* Profile */, |
||||
); |
||||
defaultConfigurationIsVisible = 0; |
||||
defaultConfigurationName = Release; |
||||
}; |
||||
/* End XCConfigurationList section */ |
||||
}; |
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */; |
||||
} |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Workspace |
||||
version = "1.0"> |
||||
<FileRef |
||||
location = "self:"> |
||||
</FileRef> |
||||
</Workspace> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>IDEDidComputeMac32BitWarning</key> |
||||
<true/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>PreviewsEnabled</key> |
||||
<false/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Scheme |
||||
LastUpgradeVersion = "1300" |
||||
version = "1.3"> |
||||
<BuildAction |
||||
parallelizeBuildables = "YES" |
||||
buildImplicitDependencies = "YES"> |
||||
<BuildActionEntries> |
||||
<BuildActionEntry |
||||
buildForTesting = "YES" |
||||
buildForRunning = "YES" |
||||
buildForProfiling = "YES" |
||||
buildForArchiving = "YES" |
||||
buildForAnalyzing = "YES"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D" |
||||
BuildableName = "Runner.app" |
||||
BlueprintName = "Runner" |
||||
ReferencedContainer = "container:Runner.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildActionEntry> |
||||
</BuildActionEntries> |
||||
</BuildAction> |
||||
<TestAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
shouldUseLaunchSchemeArgsEnv = "YES"> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D" |
||||
BuildableName = "Runner.app" |
||||
BlueprintName = "Runner" |
||||
ReferencedContainer = "container:Runner.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<Testables> |
||||
</Testables> |
||||
</TestAction> |
||||
<LaunchAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
launchStyle = "0" |
||||
useCustomWorkingDirectory = "NO" |
||||
ignoresPersistentStateOnLaunch = "NO" |
||||
debugDocumentVersioning = "YES" |
||||
debugServiceExtension = "internal" |
||||
allowLocationSimulation = "YES"> |
||||
<BuildableProductRunnable |
||||
runnableDebuggingMode = "0"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D" |
||||
BuildableName = "Runner.app" |
||||
BlueprintName = "Runner" |
||||
ReferencedContainer = "container:Runner.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildableProductRunnable> |
||||
</LaunchAction> |
||||
<ProfileAction |
||||
buildConfiguration = "Profile" |
||||
shouldUseLaunchSchemeArgsEnv = "YES" |
||||
savedToolIdentifier = "" |
||||
useCustomWorkingDirectory = "NO" |
||||
debugDocumentVersioning = "YES"> |
||||
<BuildableProductRunnable |
||||
runnableDebuggingMode = "0"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D" |
||||
BuildableName = "Runner.app" |
||||
BlueprintName = "Runner" |
||||
ReferencedContainer = "container:Runner.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildableProductRunnable> |
||||
</ProfileAction> |
||||
<AnalyzeAction |
||||
buildConfiguration = "Debug"> |
||||
</AnalyzeAction> |
||||
<ArchiveAction |
||||
buildConfiguration = "Release" |
||||
revealArchiveInOrganizer = "YES"> |
||||
</ArchiveAction> |
||||
</Scheme> |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Workspace |
||||
version = "1.0"> |
||||
<FileRef |
||||
location = "group:Runner.xcodeproj"> |
||||
</FileRef> |
||||
</Workspace> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>IDEDidComputeMac32BitWarning</key> |
||||
<true/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>PreviewsEnabled</key> |
||||
<false/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,13 @@
|
||||
import UIKit |
||||
import Flutter |
||||
|
||||
@UIApplicationMain |
||||
@objc class AppDelegate: FlutterAppDelegate { |
||||
override func application( |
||||
_ application: UIApplication, |
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? |
||||
) -> Bool { |
||||
GeneratedPluginRegistrant.register(with: self) |
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions) |
||||
} |
||||
} |
@ -0,0 +1,122 @@
|
||||
{ |
||||
"images" : [ |
||||
{ |
||||
"size" : "20x20", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-20x20@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "20x20", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-20x20@3x.png", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-29x29@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-29x29@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-29x29@3x.png", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-40x40@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-40x40@3x.png", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "60x60", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-60x60@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "60x60", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-60x60@3x.png", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "20x20", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-20x20@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "20x20", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-20x20@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-29x29@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-29x29@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-40x40@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-40x40@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "76x76", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-76x76@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "76x76", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-76x76@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "83.5x83.5", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-83.5x83.5@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "1024x1024", |
||||
"idiom" : "ios-marketing", |
||||
"filename" : "Icon-App-1024x1024@1x.png", |
||||
"scale" : "1x" |
||||
} |
||||
], |
||||
"info" : { |
||||
"version" : 1, |
||||
"author" : "xcode" |
||||
} |
||||
} |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 295 B |
After Width: | Height: | Size: 406 B |
After Width: | Height: | Size: 450 B |
After Width: | Height: | Size: 282 B |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 704 B |
After Width: | Height: | Size: 406 B |
After Width: | Height: | Size: 586 B |
After Width: | Height: | Size: 862 B |
After Width: | Height: | Size: 862 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 762 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,23 @@
|
||||
{ |
||||
"images" : [ |
||||
{ |
||||
"idiom" : "universal", |
||||
"filename" : "LaunchImage.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "universal", |
||||
"filename" : "LaunchImage@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "universal", |
||||
"filename" : "LaunchImage@3x.png", |
||||
"scale" : "3x" |
||||
} |
||||
], |
||||
"info" : { |
||||
"version" : 1, |
||||
"author" : "xcode" |
||||
} |
||||
} |
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 68 B |