From 23749122078e182bb975cabd88fec2912b67e40a Mon Sep 17 00:00:00 2001 From: YuliaGrigorieva Date: Fri, 31 Jan 2020 19:25:12 +0300 Subject: [PATCH] Update audio_call demo to use Voximplant Flutter SDK 2.0.0, add video call demo --- .gitignore | 3 +- README.md | 3 + audio_call/.gitignore | 4 + .../android/app/src/main/AndroidManifest.xml | 13 +- .../voximplant/flutter/audio_call/App.java | 19 - .../flutter/audio_call/MainActivity.java | 12 +- audio_call/android/build.gradle | 2 +- audio_call/android/gradle.properties | 3 +- .../gradle/wrapper/gradle-wrapper.properties | 6 - audio_call/ios/Podfile | 85 +-- audio_call/ios/Podfile.lock | 160 +++--- audio_call/lib/main.dart | 2 +- audio_call/lib/screens/call_screen.dart | 45 +- .../lib/screens/incoming_call_screen.dart | 5 +- audio_call/lib/screens/login_screen.dart | 2 +- audio_call/lib/screens/main_screen.dart | 2 +- audio_call/lib/services/auth_service.dart | 30 +- audio_call/lib/services/call_service.dart | 106 ++-- .../lib/services/call_service_android.dart | 10 +- audio_call/lib/services/callkit_service.dart | 45 +- .../lib/services/navigation_service.dart | 2 +- audio_call/lib/services/push_service.dart | 2 +- audio_call/lib/theme/voximplant_theme.dart | 2 +- audio_call/lib/utils/app_state_helper.dart | 2 +- .../lib/utils/notifications_android.dart | 2 +- audio_call/lib/utils/screen_arguments.dart | 4 +- audio_call/pubspec.lock | 6 +- audio_call/pubspec.yaml | 4 +- video_call/.gitignore | 37 ++ video_call/.metadata | 10 + video_call/README.md | 47 ++ video_call/android/.gitignore | 7 + video_call/android/app/build.gradle | 69 +++ .../android/app/src/debug/AndroidManifest.xml | 7 + .../android/app/src/main/AndroidManifest.xml | 30 + .../flutter/videocall/MainActivity.java | 13 + .../main/res/drawable/launch_background.xml | 12 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2484 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 3986 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 4502 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1644 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 2291 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2845 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 3479 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 5901 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 6486 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 5700 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 11222 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10399 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 8069 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 17593 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15211 bytes .../app/src/main/res/values/colors.xml | 4 + .../res/values/ic_launcher_background.xml | 4 + .../app/src/main/res/values/styles.xml | 8 + .../app/src/profile/AndroidManifest.xml | 7 + video_call/android/build.gradle | 29 + video_call/android/gradle.properties | 4 + video_call/android/settings.gradle | 15 + video_call/ios/.gitignore | 32 ++ video_call/ios/Flutter/AppFrameworkInfo.plist | 26 + video_call/ios/Flutter/Debug.xcconfig | 2 + video_call/ios/Flutter/Release.xcconfig | 2 + video_call/ios/Podfile | 87 +++ video_call/ios/Podfile.lock | 59 ++ .../ios/Runner.xcodeproj/project.pbxproj | 525 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Runner.xcscheme | 91 +++ .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + video_call/ios/Runner/AppDelegate.h | 6 + video_call/ios/Runner/AppDelegate.m | 13 + .../AppIcon.appiconset/Contents.json | 116 ++++ .../AppIcon.appiconset/voximplant-1024.png | Bin 0 -> 84323 bytes .../AppIcon.appiconset/voximplant-20.png | Bin 0 -> 1951 bytes .../AppIcon.appiconset/voximplant-20@2x.png | Bin 0 -> 3053 bytes .../AppIcon.appiconset/voximplant-20@3x.png | Bin 0 -> 4003 bytes .../AppIcon.appiconset/voximplant-29.png | Bin 0 -> 2505 bytes .../AppIcon.appiconset/voximplant-29@2x.png | Bin 0 -> 3885 bytes .../AppIcon.appiconset/voximplant-29@3x.png | Bin 0 -> 5328 bytes .../AppIcon.appiconset/voximplant-40.png | Bin 0 -> 3053 bytes .../AppIcon.appiconset/voximplant-40@2x.png | Bin 0 -> 5054 bytes .../AppIcon.appiconset/voximplant-40@3x.png | Bin 0 -> 7071 bytes .../AppIcon.appiconset/voximplant-60@2x.png | Bin 0 -> 7071 bytes .../AppIcon.appiconset/voximplant-60@3x.png | Bin 0 -> 10480 bytes .../AppIcon.appiconset/voximplant-76.png | Bin 0 -> 4824 bytes .../AppIcon.appiconset/voximplant-76@2x.png | Bin 0 -> 8795 bytes .../AppIcon.appiconset/voximplant-83.5@2x.png | Bin 0 -> 9690 bytes .../ios/Runner/Assets.xcassets/Contents.json | 6 + .../Runner/Base.lproj/LaunchScreen.storyboard | 63 +++ .../ios/Runner/Base.lproj/Main.storyboard | 26 + video_call/ios/Runner/Info.plist | 49 ++ video_call/ios/Runner/main.m | 9 + video_call/lib/active_call/active_call.dart | 5 + .../lib/active_call/active_call_page.dart | 242 ++++++++ .../active_call_page_arguments.dart | 11 + .../active_call/bloc/active_call_bloc.dart | 115 ++++ .../active_call/bloc/active_call_event.dart | 66 +++ .../active_call/bloc/active_call_state.dart | 87 +++ video_call/lib/active_call/bloc/bloc.dart | 5 + video_call/lib/call_failed/call_failed.dart | 4 + .../lib/call_failed/call_failed_page.dart | 59 ++ .../call_failed_page_arguments.dart | 11 + video_call/lib/incoming_call/bloc/bloc.dart | 5 + .../bloc/incoming_call_bloc.dart | 93 ++++ .../bloc/incoming_call_event.dart | 18 + .../bloc/incoming_call_state.dart | 18 + .../lib/incoming_call/incoming_call.dart | 5 + .../lib/incoming_call/incoming_call_page.dart | 92 +++ .../incoming_call_page_arguments.dart | 7 + video_call/lib/login/bloc/bloc.dart | 5 + video_call/lib/login/bloc/login_bloc.dart | 45 ++ video_call/lib/login/bloc/login_event.dart | 26 + video_call/lib/login/bloc/login_state.dart | 43 ++ video_call/lib/login/login.dart | 5 + video_call/lib/login/login_form.dart | 139 +++++ video_call/lib/login/login_page.dart | 17 + video_call/lib/main.dart | 99 ++++ video_call/lib/make_call/bloc/bloc.dart | 5 + .../lib/make_call/bloc/make_call_bloc.dart | 92 +++ .../lib/make_call/bloc/make_call_event.dart | 29 + .../lib/make_call/bloc/make_call_state.dart | 48 ++ video_call/lib/make_call/make_call.dart | 4 + video_call/lib/make_call/make_call_page.dart | 142 +++++ video_call/lib/routes.dart | 9 + video_call/lib/services/auth_service.dart | 95 ++++ video_call/lib/services/call_service.dart | 189 +++++++ video_call/lib/services/call_state.dart | 33 ++ video_call/lib/theme/voximplant_theme.dart | 13 + video_call/lib/widgets/widgets.dart | 106 ++++ video_call/pubspec.lock | 285 ++++++++++ video_call/pubspec.yaml | 39 ++ video_call/test/widget_test.dart | 35 ++ 135 files changed, 4094 insertions(+), 283 deletions(-) delete mode 100644 audio_call/android/app/src/main/java/com/voximplant/flutter/audio_call/App.java delete mode 100644 audio_call/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 video_call/.gitignore create mode 100644 video_call/.metadata create mode 100644 video_call/README.md create mode 100644 video_call/android/.gitignore create mode 100644 video_call/android/app/build.gradle create mode 100644 video_call/android/app/src/debug/AndroidManifest.xml create mode 100644 video_call/android/app/src/main/AndroidManifest.xml create mode 100644 video_call/android/app/src/main/java/com/voximplant/flutter/videocall/MainActivity.java create mode 100644 video_call/android/app/src/main/res/drawable/launch_background.xml create mode 100644 video_call/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 video_call/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 video_call/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 video_call/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 video_call/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 video_call/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 video_call/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 video_call/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 video_call/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 video_call/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 video_call/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 video_call/android/app/src/main/res/values/colors.xml create mode 100644 video_call/android/app/src/main/res/values/ic_launcher_background.xml create mode 100644 video_call/android/app/src/main/res/values/styles.xml create mode 100644 video_call/android/app/src/profile/AndroidManifest.xml create mode 100644 video_call/android/build.gradle create mode 100644 video_call/android/gradle.properties create mode 100644 video_call/android/settings.gradle create mode 100644 video_call/ios/.gitignore create mode 100644 video_call/ios/Flutter/AppFrameworkInfo.plist create mode 100644 video_call/ios/Flutter/Debug.xcconfig create mode 100644 video_call/ios/Flutter/Release.xcconfig create mode 100644 video_call/ios/Podfile create mode 100644 video_call/ios/Podfile.lock create mode 100644 video_call/ios/Runner.xcodeproj/project.pbxproj create mode 100644 video_call/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 video_call/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 video_call/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 video_call/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 video_call/ios/Runner/AppDelegate.h create mode 100644 video_call/ios/Runner/AppDelegate.m create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-1024.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-20.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-20@2x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-20@3x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-29.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-29@2x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-29@3x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-40.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-40@2x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-40@3x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-60@2x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-60@3x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-76.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-76@2x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-83.5@2x.png create mode 100644 video_call/ios/Runner/Assets.xcassets/Contents.json create mode 100644 video_call/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 video_call/ios/Runner/Base.lproj/Main.storyboard create mode 100644 video_call/ios/Runner/Info.plist create mode 100644 video_call/ios/Runner/main.m create mode 100644 video_call/lib/active_call/active_call.dart create mode 100644 video_call/lib/active_call/active_call_page.dart create mode 100644 video_call/lib/active_call/active_call_page_arguments.dart create mode 100644 video_call/lib/active_call/bloc/active_call_bloc.dart create mode 100644 video_call/lib/active_call/bloc/active_call_event.dart create mode 100644 video_call/lib/active_call/bloc/active_call_state.dart create mode 100644 video_call/lib/active_call/bloc/bloc.dart create mode 100644 video_call/lib/call_failed/call_failed.dart create mode 100644 video_call/lib/call_failed/call_failed_page.dart create mode 100644 video_call/lib/call_failed/call_failed_page_arguments.dart create mode 100644 video_call/lib/incoming_call/bloc/bloc.dart create mode 100644 video_call/lib/incoming_call/bloc/incoming_call_bloc.dart create mode 100644 video_call/lib/incoming_call/bloc/incoming_call_event.dart create mode 100644 video_call/lib/incoming_call/bloc/incoming_call_state.dart create mode 100644 video_call/lib/incoming_call/incoming_call.dart create mode 100644 video_call/lib/incoming_call/incoming_call_page.dart create mode 100644 video_call/lib/incoming_call/incoming_call_page_arguments.dart create mode 100644 video_call/lib/login/bloc/bloc.dart create mode 100644 video_call/lib/login/bloc/login_bloc.dart create mode 100644 video_call/lib/login/bloc/login_event.dart create mode 100644 video_call/lib/login/bloc/login_state.dart create mode 100644 video_call/lib/login/login.dart create mode 100644 video_call/lib/login/login_form.dart create mode 100644 video_call/lib/login/login_page.dart create mode 100644 video_call/lib/main.dart create mode 100644 video_call/lib/make_call/bloc/bloc.dart create mode 100644 video_call/lib/make_call/bloc/make_call_bloc.dart create mode 100644 video_call/lib/make_call/bloc/make_call_event.dart create mode 100644 video_call/lib/make_call/bloc/make_call_state.dart create mode 100644 video_call/lib/make_call/make_call.dart create mode 100644 video_call/lib/make_call/make_call_page.dart create mode 100644 video_call/lib/routes.dart create mode 100644 video_call/lib/services/auth_service.dart create mode 100644 video_call/lib/services/call_service.dart create mode 100644 video_call/lib/services/call_state.dart create mode 100644 video_call/lib/theme/voximplant_theme.dart create mode 100644 video_call/lib/widgets/widgets.dart create mode 100644 video_call/pubspec.lock create mode 100644 video_call/pubspec.yaml create mode 100644 video_call/test/widget_test.dart diff --git a/.gitignore b/.gitignore index 496ee2c..00741cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.DS_Store \ No newline at end of file +.DS_Store +.idea/ \ No newline at end of file diff --git a/README.md b/README.md index 6d98bb8..de3f575 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,6 @@ ## [Audio call](audio_call) The demo demonstrates basic audio call functionality of the Voximplant Flutter SDK. + +## [Video call](video_call) +The demo demonstrates basic video call functionality of the Voximplant Flutter SDK. diff --git a/audio_call/.gitignore b/audio_call/.gitignore index e0c65fc..8f72d2d 100644 --- a/audio_call/.gitignore +++ b/audio_call/.gitignore @@ -24,6 +24,7 @@ **/doc/api/ .dart_tool/ .flutter-plugins +.flutter-plugins-dependencies .packages .pub-cache/ .pub/ @@ -37,6 +38,7 @@ **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java +**/android/gradle/ # iOS/XCode related **/ios/**/*.mode1v3 @@ -66,6 +68,8 @@ **/ios/Flutter/flutter_export_environment.sh **/ios/Runner.xcworkspace/xcshareddata/** +**/ios/Flutter/Flutter.podspec + # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 diff --git a/audio_call/android/app/src/main/AndroidManifest.xml b/audio_call/android/app/src/main/AndroidManifest.xml index e58fba2..a74e963 100644 --- a/audio_call/android/app/src/main/AndroidManifest.xml +++ b/audio_call/android/app/src/main/AndroidManifest.xml @@ -7,7 +7,6 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> - - + + diff --git a/audio_call/android/app/src/main/java/com/voximplant/flutter/audio_call/App.java b/audio_call/android/app/src/main/java/com/voximplant/flutter/audio_call/App.java deleted file mode 100644 index f7f9b1f..0000000 --- a/audio_call/android/app/src/main/java/com/voximplant/flutter/audio_call/App.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.voximplant.flutter.audio_call; - -import io.flutter.app.FlutterApplication; -import io.flutter.plugin.common.PluginRegistry; -import io.flutter.plugins.GeneratedPluginRegistrant; -import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService; - -public class App extends FlutterApplication implements PluginRegistry.PluginRegistrantCallback { - @Override - public void onCreate() { - super.onCreate(); - FlutterFirebaseMessagingService.setPluginRegistrant(this); - } - - @Override - public void registerWith(PluginRegistry pluginRegistry) { - GeneratedPluginRegistrant.registerWith(pluginRegistry); - } -} diff --git a/audio_call/android/app/src/main/java/com/voximplant/flutter/audio_call/MainActivity.java b/audio_call/android/app/src/main/java/com/voximplant/flutter/audio_call/MainActivity.java index 22674ae..856a4a7 100644 --- a/audio_call/android/app/src/main/java/com/voximplant/flutter/audio_call/MainActivity.java +++ b/audio_call/android/app/src/main/java/com/voximplant/flutter/audio_call/MainActivity.java @@ -1,13 +1,13 @@ package com.voximplant.flutter.audio_call; -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; +import androidx.annotation.NonNull; +import io.flutter.embedding.android.FlutterActivity; +import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin; public class MainActivity extends FlutterActivity { @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); + public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { + flutterEngine.getPlugins().add(new FirebaseMessagingPlugin()); } } diff --git a/audio_call/android/build.gradle b/audio_call/android/build.gradle index 305f967..846858b 100644 --- a/audio_call/android/build.gradle +++ b/audio_call/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.3.2' + classpath 'com.android.tools.build:gradle:3.5.0' classpath 'com.google.gms:google-services:4.3.3' } } diff --git a/audio_call/android/gradle.properties b/audio_call/android/gradle.properties index 1441b1d..38c8d45 100644 --- a/audio_call/android/gradle.properties +++ b/audio_call/android/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Xmx1536M - android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/audio_call/android/gradle/wrapper/gradle-wrapper.properties b/audio_call/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 2819f02..0000000 --- a/audio_call/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 23 08:50:38 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/audio_call/ios/Podfile b/audio_call/ios/Podfile index 649f0e2..c28fd4e 100644 --- a/audio_call/ios/Podfile +++ b/audio_call/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project - platform :ios, '9.0' +platform :ios, '9.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -15,49 +15,64 @@ def parse_KV_file(file, separator='=') if !File.exists? file_abs_path return []; end - pods_ary = [] + generated_key_values = {} skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) { |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - pods_ary.push({:name => podname, :path => podpath}); - else - puts "Invalid plugin specification: #{line}" - end - } - return pods_ary + File.foreach(file_abs_path) do |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + generated_key_values[podname] = podpath + else + puts "Invalid plugin specification: #{line}" + end + end + generated_key_values end target 'Runner' do - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - system('rm -rf .symlinks') - system('mkdir -p .symlinks/plugins') + # Flutter Pod - # Flutter Pods - generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') - if generated_xcode_build_settings.empty? - puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first." - end - generated_xcode_build_settings.map { |p| - if p[:name] == 'FLUTTER_FRAMEWORK_DIR' - symlink = File.join('.symlinks', 'flutter') - File.symlink(File.dirname(p[:path]), symlink) - pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) + copied_flutter_dir = File.join(__dir__, 'Flutter') + copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') + copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') + unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) + # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. + # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. + # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. + + generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') + unless File.exist?(generated_xcode_build_settings_path) + raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" end - } + generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) + cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; + + unless File.exist?(copied_framework_path) + FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) + end + unless File.exist?(copied_podspec_path) + FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) + end + end + + # Keep pod path relative so it can be checked into Podfile.lock. + pod 'Flutter', :path => 'Flutter' # Plugin Pods + + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.map { |p| - symlink = File.join('.symlinks', 'plugins', p[:name]) - File.symlink(p[:path], symlink) - pod p[:name], :path => File.join(symlink, 'ios') - } + plugin_pods.each do |name, path| + symlink = File.join('.symlinks', 'plugins', name) + File.symlink(path, symlink) + pod name, :path => File.join(symlink, 'ios') + end end # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. diff --git a/audio_call/ios/Podfile.lock b/audio_call/ios/Podfile.lock index 900ba77..e0a7b7c 100644 --- a/audio_call/ios/Podfile.lock +++ b/audio_call/ios/Podfile.lock @@ -1,50 +1,55 @@ PODS: - - Firebase/Core (6.13.0): + - Firebase/Core (6.15.0): - Firebase/CoreOnly - - FirebaseAnalytics (= 6.1.6) - - Firebase/CoreOnly (6.13.0): - - FirebaseCore (= 6.4.0) - - Firebase/Messaging (6.13.0): + - FirebaseAnalytics (= 6.2.1) + - Firebase/CoreOnly (6.15.0): + - FirebaseCore (= 6.6.0) + - Firebase/Messaging (6.15.0): - Firebase/CoreOnly - - FirebaseMessaging (~> 4.1.9) + - FirebaseMessaging (~> 4.2.0) - firebase_messaging (0.0.1): - Firebase/Core - Firebase/Messaging - Flutter - - FirebaseAnalytics (6.1.6): - - FirebaseCore (~> 6.4) - - FirebaseInstanceID (~> 4.2) - - GoogleAppMeasurement (= 6.1.6) + - FirebaseAnalytics (6.2.1): + - FirebaseCore (~> 6.6) + - FirebaseInstanceID (~> 4.3) + - GoogleAppMeasurement (= 6.2.1) - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - GoogleUtilities/MethodSwizzler (~> 6.0) - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (= 0.3.9011) - - FirebaseAnalyticsInterop (1.4.0) - - FirebaseCore (6.4.0): - - FirebaseCoreDiagnostics (~> 1.0) - - FirebaseCoreDiagnosticsInterop (~> 1.0) - - GoogleUtilities/Environment (~> 6.2) - - GoogleUtilities/Logger (~> 6.2) - - FirebaseCoreDiagnostics (1.1.2): - - FirebaseCoreDiagnosticsInterop (~> 1.0) - - GoogleDataTransportCCTSupport (~> 1.0) - - GoogleUtilities/Environment (~> 6.2) - - GoogleUtilities/Logger (~> 6.2) + - FirebaseAnalyticsInterop (1.5.0) + - FirebaseCore (6.6.0): + - FirebaseCoreDiagnostics (~> 1.2) + - FirebaseCoreDiagnosticsInterop (~> 1.2) + - GoogleUtilities/Environment (~> 6.5) + - GoogleUtilities/Logger (~> 6.5) + - FirebaseCoreDiagnostics (1.2.0): + - FirebaseCoreDiagnosticsInterop (~> 1.2) + - GoogleDataTransportCCTSupport (~> 1.3) + - GoogleUtilities/Environment (~> 6.5) + - GoogleUtilities/Logger (~> 6.5) - nanopb (~> 0.3.901) - - FirebaseCoreDiagnosticsInterop (1.1.0) - - FirebaseInstanceID (4.2.7): - - FirebaseCore (~> 6.0) - - GoogleUtilities/Environment (~> 6.0) - - GoogleUtilities/UserDefaults (~> 6.0) - - FirebaseMessaging (4.1.9): - - FirebaseAnalyticsInterop (~> 1.3) - - FirebaseCore (~> 6.2) - - FirebaseInstanceID (~> 4.1) - - GoogleUtilities/AppDelegateSwizzler (~> 6.2) - - GoogleUtilities/Environment (~> 6.2) - - GoogleUtilities/Reachability (~> 6.2) - - GoogleUtilities/UserDefaults (~> 6.2) + - FirebaseCoreDiagnosticsInterop (1.2.0) + - FirebaseInstallations (1.1.0): + - FirebaseCore (~> 6.6) + - GoogleUtilities/UserDefaults (~> 6.5) + - PromisesObjC (~> 1.2) + - FirebaseInstanceID (4.3.0): + - FirebaseCore (~> 6.6) + - FirebaseInstallations (~> 1.0) + - GoogleUtilities/Environment (~> 6.5) + - GoogleUtilities/UserDefaults (~> 6.5) + - FirebaseMessaging (4.2.0): + - FirebaseAnalyticsInterop (~> 1.5) + - FirebaseCore (~> 6.6) + - FirebaseInstanceID (~> 4.3) + - GoogleUtilities/AppDelegateSwizzler (~> 6.5) + - GoogleUtilities/Environment (~> 6.5) + - GoogleUtilities/Reachability (~> 6.5) + - GoogleUtilities/UserDefaults (~> 6.5) - Protobuf (>= 3.9.2, ~> 3.9) - Flutter (1.0.0) - flutter_call_kit (0.0.1): @@ -53,36 +58,36 @@ PODS: - Flutter - flutter_voip_push_notification (0.0.1): - Flutter - - flutter_voximplant (1.2.0): + - flutter_voximplant (2.0.0): - Flutter - - VoxImplantSDK (= 2.25.2) - - GoogleAppMeasurement (6.1.6): + - VoxImplantSDK (= 2.26.0) + - GoogleAppMeasurement (6.2.1): - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - GoogleUtilities/MethodSwizzler (~> 6.0) - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (= 0.3.9011) - - GoogleDataTransport (3.2.0) - - GoogleDataTransportCCTSupport (1.2.2): - - GoogleDataTransport (~> 3.2) + - GoogleDataTransport (3.3.0) + - GoogleDataTransportCCTSupport (1.3.0): + - GoogleDataTransport (~> 3.3) - nanopb (~> 0.3.901) - - GoogleUtilities/AppDelegateSwizzler (6.3.2): + - GoogleUtilities/AppDelegateSwizzler (6.5.0): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.3.2) - - GoogleUtilities/Logger (6.3.2): + - GoogleUtilities/Environment (6.5.0) + - GoogleUtilities/Logger (6.5.0): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.3.2): + - GoogleUtilities/MethodSwizzler (6.5.0): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.3.2): + - GoogleUtilities/Network (6.5.0): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.3.2)" - - GoogleUtilities/Reachability (6.3.2): + - "GoogleUtilities/NSData+zlib (6.5.0)" + - GoogleUtilities/Reachability (6.5.0): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.3.2): + - GoogleUtilities/UserDefaults (6.5.0): - GoogleUtilities/Logger - nanopb (0.3.9011): - nanopb/decode (= 0.3.9011) @@ -91,18 +96,19 @@ PODS: - nanopb/encode (0.3.9011) - permission_handler (3.3.0): - Flutter - - Protobuf (3.11.1) + - PromisesObjC (1.2.8) + - Protobuf (3.11.2) - shared_preferences (0.0.1): - Flutter - - VoxImplantSDK (2.25.2): - - VoxImplantSDK/Core (= 2.25.2) - - VoxImplantSDK/Core (2.25.2): - - VoxImplantWebRTC (= 74.1.0) - - VoxImplantWebRTC (74.1.0) + - VoxImplantSDK (2.26.0): + - VoxImplantSDK/Core (= 2.26.0) + - VoxImplantSDK/Core (2.26.0): + - VoxImplantWebRTC (= 78.0.0) + - VoxImplantWebRTC (78.0.0) DEPENDENCIES: - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - - Flutter (from `.symlinks/flutter/ios`) + - Flutter (from `Flutter`) - flutter_call_kit (from `.symlinks/plugins/flutter_call_kit/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_voip_push_notification (from `.symlinks/plugins/flutter_voip_push_notification/ios`) @@ -118,6 +124,7 @@ SPEC REPOS: - FirebaseCore - FirebaseCoreDiagnostics - FirebaseCoreDiagnosticsInterop + - FirebaseInstallations - FirebaseInstanceID - FirebaseMessaging - GoogleAppMeasurement @@ -125,6 +132,7 @@ SPEC REPOS: - GoogleDataTransportCCTSupport - GoogleUtilities - nanopb + - PromisesObjC - Protobuf - VoxImplantSDK - VoxImplantWebRTC @@ -133,7 +141,7 @@ EXTERNAL SOURCES: firebase_messaging: :path: ".symlinks/plugins/firebase_messaging/ios" Flutter: - :path: ".symlinks/flutter/ios" + :path: Flutter flutter_call_kit: :path: ".symlinks/plugins/flutter_call_kit/ios" flutter_local_notifications: @@ -148,31 +156,33 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/shared_preferences/ios" SPEC CHECKSUMS: - Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 - firebase_messaging: db3f19ec4490799e5c660723626740e539c41c04 - FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a - FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 - FirebaseCore: 307ea2508df730c5865334e41965bd9ea344b0e5 - FirebaseCoreDiagnostics: 511f4f3ed7d440bb69127e8b97c2bc8befae639e - FirebaseCoreDiagnosticsInterop: e9b1b023157e3a2fc6418b5cb601e79b9af7b3a0 - FirebaseInstanceID: ebd2ea79ee38db0cb5f5167b17a0d387e1cc7b6e - FirebaseMessaging: e8d71368a5c579083da02203146c953f3386d503 + Firebase: 5d77105d9740a07ca6b16927ca971db7e860faaf + firebase_messaging: 73b3e7dd7b3b6a7e4bdac10d5295211ca4f87f90 + FirebaseAnalytics: e83e64b1231dedcd9ddd4bdecd9bcfd6ba341679 + FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae + FirebaseCore: 4aeb81ff53dcd9a3634ca725dc1fb8c2a4622046 + FirebaseCoreDiagnostics: 5e78803ab276bc5b50340e3c539c06c3de35c649 + FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850 + FirebaseInstallations: 575cd32f2aec0feeb0e44f5d0110a09e5e60b47b + FirebaseInstanceID: 6668efc1655a4052c083f287a7141f1ead12f9c2 + FirebaseMessaging: 448cf4c727f3c95f4f90816907d67306ba785cfe Flutter: 0e3d915762c693b495b44d77113d4970485de6ec flutter_call_kit: 0598f2eec54579aa00b53fb68a622ccdb08fe4fe flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 flutter_voip_push_notification: f28f3ce1c6b835a3fa9e833f37f33dc1291ab888 - flutter_voximplant: 45b9dabfd7f73e21cb5ef3dd28a4afab39853f4d - GoogleAppMeasurement: dfe55efa543e899d906309eaaac6ca26d249862f - GoogleDataTransport: 8e9b210c97d55fbff306cc5468ff91b9cb32dcf5 - GoogleDataTransportCCTSupport: ef79a4728b864946a8aafdbab770d5294faf3b5f - GoogleUtilities: 547a86735c6f0ee30ad17e94df4fc21f616b71cb + flutter_voximplant: 5d2223da5d47ff2ee5f43c84a60c8fc4f5a01ffa + GoogleAppMeasurement: a08a43b8677b95ed51fcef880e36737334d804fd + GoogleDataTransport: 574a983e829327d7c18f2627f65d9e80164ea8a4 + GoogleDataTransportCCTSupport: cad3cd6cdbdbad6b5c2c9206ec413402755faaaa + GoogleUtilities: f8de7ddf8c706f58e9b405d53e38bbdaa2731e5a nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd permission_handler: 67637977b227d62d46bfbf524f335f8568de5a73 - Protobuf: 20d79da7f20b5928b80043b05080b816e802659e + PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6 + Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523 - VoxImplantSDK: 003dcf5b3413cec415a03aaaf7986ad86c148c82 - VoxImplantWebRTC: f1bfe15b2a7d3fd8875d204c1b3dbb370279b12e + VoxImplantSDK: c53bd6ed2634a43a33ae0d517cc90c7ae4b0bed4 + VoxImplantWebRTC: a4bd73d41b9f8f3a60de032337b661bab8ead6f9 -PODFILE CHECKSUM: 091f1b57aaebffcf04ec409c33ea6801c9622bcc +PODFILE CHECKSUM: 49ec7d4076524b7e225c38b98147173651ac4b9d -COCOAPODS: 1.8.4 +COCOAPODS: 1.8.3 diff --git a/audio_call/lib/main.dart b/audio_call/lib/main.dart index 2008f3d..b366706 100644 --- a/audio_call/lib/main.dart +++ b/audio_call/lib/main.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'dart:convert'; import 'dart:io'; diff --git a/audio_call/lib/screens/call_screen.dart b/audio_call/lib/screens/call_screen.dart index db4d4a2..b74999d 100644 --- a/audio_call/lib/screens/call_screen.dart +++ b/audio_call/lib/screens/call_screen.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'package:audio_call/screens/main_screen.dart'; import 'package:audio_call/services/call_service.dart'; @@ -19,13 +19,13 @@ class CallScreen extends StatefulWidget { } class CallScreenState extends State { - String _endpointName; + String _endpointName = 'Unknown'; String _callStatus = 'Connecting...'; bool _isAudioMuted = false; bool _isOnHold = false; String _callId; IconData _audioDeviceIcon = Icons.hearing; - AudioDeviceManager _audioDeviceManager; + VIAudioDeviceManager _audioDeviceManager; final CallService _callService = CallService(); CallScreenState(this._callId) { @@ -38,47 +38,46 @@ class CallScreenState extends State { onCallRinging: _onCallRinging, onCallAudioStarted: _onCallAudioStarted, onEndpointAdded: _onEndpointAdded, - onCallMuted: _onCallMuted, onCallPutOnHold: _onCallPutOnHold, ); - _endpointName = _callService.getEndpointNameForCall(_callId) ?? 'Unknown'; print('CallScreen: received callId: $_callId'); } - _onAudioDeviceChange(AudioDevice audioDevice) { + _onAudioDeviceChange( + VIAudioDeviceManager audioDeviceManager, VIAudioDevice audioDevice) { setState(() { switch (audioDevice) { - case AudioDevice.Bluetooth: + case VIAudioDevice.Bluetooth: _audioDeviceIcon = Icons.bluetooth_audio; break; - case AudioDevice.Earpiece: + case VIAudioDevice.Earpiece: _audioDeviceIcon = Icons.hearing; break; - case AudioDevice.Speaker: + case VIAudioDevice.Speaker: _audioDeviceIcon = Icons.volume_up; break; - case AudioDevice.WiredHeadset: + case VIAudioDevice.WiredHeadset: _audioDeviceIcon = Icons.headset; break; - case AudioDevice.None: + case VIAudioDevice.None: break; } }); } - _onCallDisconnected(Map headers, bool answeredElsewhere) { + _onCallDisconnected(VICall call, Map headers, bool answeredElsewhere) { print('CallScreen: onCallDisconnected'); Navigator.pushReplacementNamed(context, MainScreen.routeName); } - _onCallFailed(int code, String description, Map headers) { + _onCallFailed(VICall call, int code, String description, Map headers) { print('CallScreen: onCallFailed'); Navigator.pushReplacementNamed(context, MainScreen.routeName); } - _onCallConnected(Map headers) { + _onCallConnected(VICall call, Map headers) { print('CallScreen: onCallConnected'); setState(() { _callStatus = 'Call in progress'; @@ -86,18 +85,18 @@ class CallScreenState extends State { }); } - _onCallRinging(Map headers) { + _onCallRinging(VICall call, Map headers) { print('CallScreen: onCallRinging'); setState(() { _callStatus = 'Ringing...'; }); } - _onCallAudioStarted() { + _onCallAudioStarted(VICall call) { print('CallScreen: onCallAudioStarted'); } - _onEndpointAdded(Endpoint endpoint) { + _onEndpointAdded(VICall call, VIEndpoint endpoint) { print('CallScreen: onEndpointAdded'); endpoint.onEndpointUpdated = _onEndpointUpdated; setState(() { @@ -105,7 +104,7 @@ class CallScreenState extends State { }); } - _onEndpointUpdated(Endpoint endpoint) { + _onEndpointUpdated(VIEndpoint endpoint) { print('CallScreen: onEndpointUpdated'); setState(() { _endpointName = endpoint.userName; @@ -124,8 +123,7 @@ class CallScreenState extends State { setState(() { _isAudioMuted = !_isAudioMuted; }); - } catch (e) { - } + } catch (e) {} } _onCallPutOnHold(bool onHold) { @@ -140,16 +138,15 @@ class CallScreenState extends State { setState(() { _isOnHold = !_isOnHold; }); - } catch (e) { - } + } catch (e) {} } - _selectAudioDevice(AudioDevice device) async { + _selectAudioDevice(VIAudioDevice device) async { await _audioDeviceManager.selectAudioDevice(device); } _showAvailableAudioDevices() async { - List availableAudioDevices = + List availableAudioDevices = await _audioDeviceManager.getAudioDevices(); return showDialog( context: context, diff --git a/audio_call/lib/screens/incoming_call_screen.dart b/audio_call/lib/screens/incoming_call_screen.dart index 919db35..812ce47 100644 --- a/audio_call/lib/screens/incoming_call_screen.dart +++ b/audio_call/lib/screens/incoming_call_screen.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'dart:io'; @@ -11,6 +11,7 @@ import 'package:audio_call/utils/screen_arguments.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:flutter_voximplant/flutter_voximplant.dart'; class IncomingCallScreen extends StatelessWidget { static const routeName = '/incomingCall'; @@ -21,7 +22,7 @@ class IncomingCallScreen extends StatelessWidget { _callService.bind(onCallDisconnected: _onCallDisconnected); } - _onCallDisconnected(Map headers, bool answeredElsewhere) { + _onCallDisconnected(VICall call, Map headers, bool answeredElsewhere) { GetIt locator = GetIt.instance; locator().navigateTo(MainScreen.routeName); } diff --git a/audio_call/lib/screens/login_screen.dart b/audio_call/lib/screens/login_screen.dart index 3919e34..ff26676 100644 --- a/audio_call/lib/screens/login_screen.dart +++ b/audio_call/lib/screens/login_screen.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'package:audio_call/screens/main_screen.dart'; import 'package:audio_call/services/auth_service.dart'; diff --git a/audio_call/lib/screens/main_screen.dart b/audio_call/lib/screens/main_screen.dart index e87c812..0af2e8e 100644 --- a/audio_call/lib/screens/main_screen.dart +++ b/audio_call/lib/screens/main_screen.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'dart:io'; diff --git a/audio_call/lib/services/auth_service.dart b/audio_call/lib/services/auth_service.dart index 662b3ee..a6fcb89 100644 --- a/audio_call/lib/services/auth_service.dart +++ b/audio_call/lib/services/auth_service.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'dart:io'; import 'dart:convert'; @@ -11,7 +11,7 @@ import 'package:shared_preferences/shared_preferences.dart'; typedef void ConnectionClosed(); class AuthService { - Client _client; + VIClient _client; String _displayName; String get displayName => _displayName; @@ -41,7 +41,7 @@ class AuthService { CallService().client = _client; _client.clientStateStream.listen((state) { print('AuthService: client state is changed: $state'); - if (state == ClientState.Disconnected && onConnectionClosed != null) { + if (state == VIClientState.Disconnected && onConnectionClosed != null) { onConnectionClosed(); } }); @@ -49,14 +49,14 @@ class AuthService { Future loginWithPassword(String username, String password) async { print('AuthService: loginWithPassword'); - ClientState clientState = await _client.getClientState(); - if (clientState == ClientState.LoggedIn) { + VIClientState clientState = await _client.getClientState(); + if (clientState == VIClientState.LoggedIn) { return _displayName; } - if (clientState == ClientState.Disconnected) { + if (clientState == VIClientState.Disconnected) { await _client.connect(); } - AuthResult authResult = await _client.login(username, password); + VIAuthResult authResult = await _client.login(username, password); await _saveAuthDetails(username, authResult.loginTokens); _displayName = authResult.displayName; return _displayName; @@ -64,18 +64,18 @@ class AuthService { Future loginWithAccessToken([String username]) async { print('AuthService: loginWithAccessToken'); - ClientState clientState = await _client.getClientState(); - if (clientState == ClientState.LoggedIn) { + VIClientState clientState = await _client.getClientState(); + if (clientState == VIClientState.LoggedIn) { return _displayName; } - if (clientState == ClientState.Disconnected) { + if (clientState == VIClientState.Disconnected) { await _client.connect(); } SharedPreferences prefs = await SharedPreferences.getInstance(); - LoginTokens loginTokens = _getAuthDetails(prefs); + VILoginTokens loginTokens = _getAuthDetails(prefs); String user = username ?? prefs.getString('username'); - AuthResult authResult = + VIAuthResult authResult = await _client.loginWithAccessToken(user, loginTokens.accessToken); await _saveAuthDetails(user, authResult.loginTokens); _displayName = authResult.displayName; @@ -92,7 +92,7 @@ class AuthService { } Future _saveAuthDetails(String username, - LoginTokens loginTokens) async { + VILoginTokens loginTokens) async { final SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString('username', username); prefs.setString('accessToken', loginTokens.accessToken); @@ -101,8 +101,8 @@ class AuthService { prefs.setInt('refreshExpire', loginTokens.refreshExpire); } - LoginTokens _getAuthDetails(SharedPreferences prefs) { - LoginTokens loginTokens = LoginTokens(); + VILoginTokens _getAuthDetails(SharedPreferences prefs) { + VILoginTokens loginTokens = VILoginTokens(); loginTokens.accessToken = prefs.getString('accessToken'); loginTokens.accessExpire = prefs.getInt('accessExpire'); loginTokens.refreshExpire = prefs.getInt('refreshExpire'); diff --git a/audio_call/lib/services/call_service.dart b/audio_call/lib/services/call_service.dart index cae5d92..a390ea8 100644 --- a/audio_call/lib/services/call_service.dart +++ b/audio_call/lib/services/call_service.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'dart:io'; import 'package:audio_call/services/call_service_android.dart'; @@ -9,35 +9,32 @@ import 'callkit_service.dart'; typedef void CallMuted(bool muted); typedef void CallPutOnHold(bool onHold); - - class CallService { static CallService _singleton; - bool navigateToIncomingCallScreen = false; - Client _client; - set client(Client client) { + VIClient _client; + set client(VIClient client) { print('CallService: setClient'); _client = client; configure(); _client.onIncomingCall = onIncomingCall; } - Call call; + VICall call; String get callId => call?.callId; - CallDisconnected onCallDisconnectedEvent; - CallFailed onCallFailedEvent; - CallConnected onCallConnectedEvent; - CallRinging onCallRingingEvent; - CallAudioStarted onCallAudioStartedEvent; - SIPInfoReceived onSIPInfoReceivedEvent; - MessageReceived onMessageReceivedEvent; - ICECompleted onICECompletedEvent; - ICETimeout onICETimeoutEvent; - EndpointAdded onEndpointAddedEvent; + VICallDisconnected onCallDisconnectedEvent; + VICallFailed onCallFailedEvent; + VICallConnected onCallConnectedEvent; + VICallRinging onCallRingingEvent; + VICallAudioStarted onCallAudioStartedEvent; + VISIPInfoReceived onSIPInfoReceivedEvent; + VIMessageReceived onMessageReceivedEvent; + VIICECompleted onICECompletedEvent; + VIICETimeout onICETimeoutEvent; + VIEndpointAdded onEndpointAddedEvent; CallMuted onCallMutedEvent; CallPutOnHold onCallPutOnHoldEvent; @@ -68,13 +65,14 @@ class CallService { Future configure() async {} Future makeAudioCall(String number) async { - Call call = await _client.call(number); + VICall call = await _client.call(number); registerCall(call); print('CallService: created call: ${call.callId}'); return call.callId; } - onIncomingCall(Call call, Map headers) async { + onIncomingCall(VIClient client, VICall call, bool video, + Map headers) async { print('CallService: onIncomingCall(${call.callId})'); if (this.call != null) { await call.decline(); @@ -84,7 +82,7 @@ class CallService { } //#region Call events - registerCall(Call call) { + registerCall(VICall call) { this.call = call; this.call.onCallDisconnected = onCallDisconnected; this.call.onCallFailed = onCallFailed; @@ -99,16 +97,16 @@ class CallService { } void bind({ - CallDisconnected onCallDisconnected, - CallFailed onCallFailed, - CallConnected onCallConnected, - CallRinging onCallRinging, - CallAudioStarted onCallAudioStarted, - SIPInfoReceived onSIPInfoReceived, - MessageReceived onMessageReceived, - ICECompleted onICECompleted, - ICETimeout onICETimeout, - EndpointAdded onEndpointAdded, + VICallDisconnected onCallDisconnected, + VICallFailed onCallFailed, + VICallConnected onCallConnected, + VICallRinging onCallRinging, + VICallAudioStarted onCallAudioStarted, + VISIPInfoReceived onSIPInfoReceived, + VIMessageReceived onMessageReceived, + VIICECompleted onICECompleted, + VIICETimeout onICETimeout, + VIEndpointAdded onEndpointAdded, CallMuted onCallMuted, CallPutOnHold onCallPutOnHold, }) { @@ -126,77 +124,80 @@ class CallService { onCallPutOnHoldEvent = onCallPutOnHold; } - onCallDisconnected(Map headers, bool answeredElsewhere) { + onCallDisconnected( + VICall call, Map headers, bool answeredElsewhere) { print('CallService: onCallDisconnected($headers, $answeredElsewhere)'); - call = null; + this.call = null; if (onCallDisconnectedEvent != null) { - onCallDisconnectedEvent(headers, answeredElsewhere); + onCallDisconnectedEvent(call, headers, answeredElsewhere); } } - onCallFailed(int code, String description, Map headers) { + onCallFailed( + VICall call, int code, String description, Map headers) { print('CallService: onCallFailed($code, $description, $headers)'); - call = null; + this.call = null; if (onCallFailedEvent != null) { - onCallFailedEvent(code, description, headers); + onCallFailedEvent(call, code, description, headers); } } - onCallConnected(Map headers) { + onCallConnected(VICall call, Map headers) { print('CallService: onCallConnected($headers)'); if (onCallConnectedEvent != null) { - onCallConnectedEvent(headers); + onCallConnectedEvent(call, headers); } } - onCallRinging(Map headers) { + onCallRinging(VICall call, Map headers) { print('CallService: onCallRinging($headers)'); if (onCallRingingEvent != null) { - onCallRingingEvent(headers); + onCallRingingEvent(call, headers); } } - onCallAudioStarted() { + onCallAudioStarted(VICall call) { print('CallService: onCallAudioStarted()'); if (onCallAudioStartedEvent != null) { - onCallAudioStartedEvent(); + onCallAudioStartedEvent(call); } } - onSIPInfoReceived(String type, String content, Map headers) { + onSIPInfoReceived( + VICall call, String type, String content, Map headers) { print('CallService: onSIPInfoReceived($type, $content, $headers)'); if (onSIPInfoReceivedEvent != null) { - onSIPInfoReceivedEvent(type, content, headers); + onSIPInfoReceivedEvent(call, type, content, headers); } } - onMessageReceived(String message) { + onMessageReceived(VICall call, String message) { print('CallScreen: onMessageReceived($message)'); if (onMessageReceivedEvent != null) { - onMessageReceivedEvent(message); + onMessageReceivedEvent(call, message); } } - onICETimeout() { + onICETimeout(VICall call) { print('CallService: onICETimeout()'); if (onICETimeoutEvent != null) { - onICETimeoutEvent(); + onICETimeoutEvent(call); } } - onICECompleted() { + onICECompleted(VICall call) { print('CallService: onICECompleted()'); if (onICECompletedEvent != null) { - onICECompletedEvent(); + onICECompletedEvent(call); } } - onEndpointAdded(Endpoint endpoint) { + onEndpointAdded(VICall call, VIEndpoint endpoint) { print('CallService: onEndpointAdded($endpoint)'); endpoint.onEndpointUpdated = onEndpointUpdated; } - onEndpointUpdated(Endpoint endpoint) { + onEndpointUpdated(VIEndpoint endpoint) { print('CallService: onEndpointUpdated($endpoint)'); } @@ -224,4 +225,3 @@ class CallService { } //#endregion } - diff --git a/audio_call/lib/services/call_service_android.dart b/audio_call/lib/services/call_service_android.dart index 60d520b..93570d8 100644 --- a/audio_call/lib/services/call_service_android.dart +++ b/audio_call/lib/services/call_service_android.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'package:audio_call/screens/incoming_call_screen.dart'; import 'package:audio_call/services/call_service.dart'; @@ -14,12 +14,14 @@ class CallServiceAndroid extends CallService { CallServiceAndroid() : super.ctr(); @override - onIncomingCall(Call call, Map headers) async { + onIncomingCall(VIClient client, VICall call, bool video, + Map headers) async { print('CallServiceAndroid: onIncomingCall(${call.callId})'); - super.onIncomingCall(call, headers); + super.onIncomingCall(client, call, video, headers); if (AppStateHelper().appState == AppState.Foreground) { - print('CallServiceAndroid: onIncomingCall: navifate to Incoming call screen'); + print( + 'CallServiceAndroid: onIncomingCall: navifate to Incoming call screen'); GetIt locator = GetIt.instance; locator().navigateTo(IncomingCallScreen.routeName, arguments: CallArguments.withDisplayName( diff --git a/audio_call/lib/services/callkit_service.dart b/audio_call/lib/services/callkit_service.dart index ca8fae5..78194ed 100644 --- a/audio_call/lib/services/callkit_service.dart +++ b/audio_call/lib/services/callkit_service.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'package:audio_call/screens/call_screen.dart'; import 'package:audio_call/utils/screen_arguments.dart'; @@ -16,7 +16,8 @@ class CallServiceIOS extends CallService { final Uuid _uuid = Uuid(); final FlutterCallKit _callKit = FlutterCallKit(); - final AudioDeviceManager _audioDeviceManager = Voximplant().getAudioDeviceManager(); + final VIAudioDeviceManager _audioDeviceManager = + Voximplant().getAudioDeviceManager(); CallServiceIOS() : super.ctr(); @@ -42,7 +43,8 @@ class CallServiceIOS extends CallService { } @override - onIncomingCall(Call call, Map headers) async { + onIncomingCall(VIClient client, VICall call, bool video, + Map headers) async { if (this.call != null) { await call.decline(); return; @@ -51,7 +53,8 @@ class CallServiceIOS extends CallService { print('onIncomingCall($call)'); if (_callKitUUID == null) { _callKitUUID = call.callKitUUID; - _callKit.displayIncomingCall(call.callKitUUID, + _callKit.displayIncomingCall( + call.callKitUUID, call.endpoints?.first?.displayName, call.endpoints?.first?.displayName, handleType: HandleType.generic); @@ -83,39 +86,41 @@ class CallServiceIOS extends CallService { } @override - onCallConnected(Map headers) { - super.onCallConnected(headers); + onCallConnected(VICall call, Map headers) { + super.onCallConnected(call, headers); print('CallServiceIOS: onCallConnected($headers)'); - _callKit.updateDisplay(_callKitUUID, call.callId, - call.endpoints.first?.userName ?? 'Unknown', + _callKit.updateDisplay( + _callKitUUID, call.callId, call.endpoints.first?.userName ?? 'Unknown', handleType: HandleType.generic); } @override - onCallDisconnected(Map headers, bool answeredElsewhere) { + onCallDisconnected( + VICall call, Map headers, bool answeredElsewhere) { print('CallServiceIOS: onCallDisconnected($headers)'); _audioDeviceManager.callKitReleaseAudioSession(); _callKit.reportEndCallWithUUID(_callKitUUID, EndReason.remoteEnded); _callKitUUID = null; - super.onCallDisconnected(headers, answeredElsewhere); + super.onCallDisconnected(call, headers, answeredElsewhere); } @override - onCallFailed(int code, String description, Map headers) { + onCallFailed( + VICall call, int code, String description, Map headers) { print('CallServiceIOS: onCallFailed($description)'); _audioDeviceManager.callKitReleaseAudioSession(); _callKit.endCall(_callKitUUID); _callKitUUID = null; - super.onCallFailed(code, description, headers); + super.onCallFailed(call, code, description, headers); } @override - onEndpointUpdated(Endpoint endpoint) { + onEndpointUpdated(VIEndpoint endpoint) { super.onEndpointUpdated(endpoint); print('CallServiceIOS: onEndpointUpdated($endpoint)'); - _callKit.updateDisplay(_callKitUUID, call.callId, - call.endpoints.first?.userName ?? 'Unknown', + _callKit.updateDisplay( + _callKitUUID, call.callId, call.endpoints.first?.userName ?? 'Unknown', handleType: HandleType.generic); } @@ -128,7 +133,9 @@ class CallServiceIOS extends CallService { if (this.call == null && _callKitUUID == null) { _callKitUUID = uuid; } - if (call != null && _callKitUUID != null && call.callKitUUID != _callKitUUID) { + if (call != null && + _callKitUUID != null && + call.callKitUUID != _callKitUUID) { await _callKit.endCall(uuid); } } @@ -144,7 +151,8 @@ class CallServiceIOS extends CallService { } Future _didReceiveStartCallAction(String uuid, String handle) async { - print('CallServiceIOS: didReceiveStartCallAction(uuid: $uuid, handle: $handle)'); + print( + 'CallServiceIOS: didReceiveStartCallAction(uuid: $uuid, handle: $handle)'); await _audioDeviceManager.callKitConfigureAudioSession(); } @@ -155,7 +163,8 @@ class CallServiceIOS extends CallService { Future _didPerformSetMutedCallAction(bool mute, String uuid) async { // Called when the system or user mutes a call - print('CallServiceIOS: didPerformSetMutedCallAction(mute: $mute, uuid: $uuid)'); + print( + 'CallServiceIOS: didPerformSetMutedCallAction(mute: $mute, uuid: $uuid)'); await super.sendAudio(!mute); if (onCallMutedEvent != null) { onCallMutedEvent(mute); diff --git a/audio_call/lib/services/navigation_service.dart b/audio_call/lib/services/navigation_service.dart index d3d786c..df3689a 100644 --- a/audio_call/lib/services/navigation_service.dart +++ b/audio_call/lib/services/navigation_service.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'package:audio_call/utils/screen_arguments.dart'; import 'package:flutter/material.dart'; diff --git a/audio_call/lib/services/push_service.dart b/audio_call/lib/services/push_service.dart index f201dca..b6461b0 100644 --- a/audio_call/lib/services/push_service.dart +++ b/audio_call/lib/services/push_service.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'dart:io'; import 'dart:convert'; diff --git a/audio_call/lib/theme/voximplant_theme.dart b/audio_call/lib/theme/voximplant_theme.dart index 79de74e..cf531ed 100644 --- a/audio_call/lib/theme/voximplant_theme.dart +++ b/audio_call/lib/theme/voximplant_theme.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'package:flutter/material.dart'; diff --git a/audio_call/lib/utils/app_state_helper.dart b/audio_call/lib/utils/app_state_helper.dart index b3655cd..b92abb8 100644 --- a/audio_call/lib/utils/app_state_helper.dart +++ b/audio_call/lib/utils/app_state_helper.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. enum AppState { NotLaunched, diff --git a/audio_call/lib/utils/notifications_android.dart b/audio_call/lib/utils/notifications_android.dart index b5b3d33..b323e35 100644 --- a/audio_call/lib/utils/notifications_android.dart +++ b/audio_call/lib/utils/notifications_android.dart @@ -1,4 +1,4 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'dart:async'; diff --git a/audio_call/lib/utils/screen_arguments.dart b/audio_call/lib/utils/screen_arguments.dart index ca3c234..8b77d30 100644 --- a/audio_call/lib/utils/screen_arguments.dart +++ b/audio_call/lib/utils/screen_arguments.dart @@ -1,10 +1,10 @@ -/// Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved. +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. import 'package:flutter_voximplant/flutter_voximplant.dart'; class CallArguments { - Call call; + VICall call; String displayName; String callId; diff --git a/audio_call/pubspec.lock b/audio_call/pubspec.lock index 422b111..ba94f01 100644 --- a/audio_call/pubspec.lock +++ b/audio_call/pubspec.lock @@ -70,7 +70,7 @@ packages: name: firebase_messaging url: "https://pub.dartlang.org" source: hosted - version: "6.0.1" + version: "6.0.9" flutter: dependency: "direct main" description: flutter @@ -110,7 +110,7 @@ packages: name: flutter_voximplant url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "2.0.0" get_it: dependency: "direct main" description: @@ -265,4 +265,4 @@ packages: version: "3.5.0" sdks: dart: ">=2.4.0 <3.0.0" - flutter: ">=1.5.0 <2.0.0" + flutter: ">=1.10.0 <2.0.0" diff --git a/audio_call/pubspec.yaml b/audio_call/pubspec.yaml index 2467e05..6e9638e 100644 --- a/audio_call/pubspec.yaml +++ b/audio_call/pubspec.yaml @@ -19,14 +19,14 @@ environment: dependencies: flutter: sdk: flutter - flutter_voximplant: 1.2.0 + flutter_voximplant: 2.0.0 shared_preferences: 0.5.3+4 crypto: 2.1.3 get_it: 3.0.0 uuid: 2.0.2 permission_handler: '^3.2.0' flutter_voip_push_notification: 0.0.3 - firebase_messaging: 6.0.1 + firebase_messaging: 6.0.9 flutter_local_notifications: 0.8.4+3 flutter_call_kit: git: diff --git a/video_call/.gitignore b/video_call/.gitignore new file mode 100644 index 0000000..ae1f183 --- /dev/null +++ b/video_call/.gitignore @@ -0,0 +1,37 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# 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/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Exceptions to above rules. +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/video_call/.metadata b/video_call/.metadata new file mode 100644 index 0000000..1b5cec0 --- /dev/null +++ b/video_call/.metadata @@ -0,0 +1,10 @@ +# 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 and should not be manually edited. + +version: + revision: 27321ebbad34b0a3fafe99fac037102196d655ff + channel: stable + +project_type: app diff --git a/video_call/README.md b/video_call/README.md new file mode 100644 index 0000000..96449ee --- /dev/null +++ b/video_call/README.md @@ -0,0 +1,47 @@ +# video_call + +This demo demonstrates basic video call functionality of the Voximplant Flutter SDK. +It is possible to make video calls with any application (mobile or web) that have integrated +Voximplant SDKs. + +This demo application doesn't handle push notifications, so it doesn't receive incoming +calls if the application is in the background or killed. + +## Features + +The application is able to: + +- log in to the Voximplant Cloud +- make a video call +- receive an incoming call +- put a call on hold / take it off hold +- stop/start sending video during a call + +## Getting started + +To get started, you'll need to register a free Voximplant developer account. + +You'll need the following: + +- Voximplant application +- two Voximplant users +- VoxEngine scenario +- routing setup + +#### VoxEngine scenario example +```js +VoxEngine.addEventListener(AppEvents.CallAlerting, (e) => { +const newCall = VoxEngine.callUserDirect( + e.call, + e.destination, + e.callerid, + e.displayName, + null +); +VoxEngine.easyProcess(e.call, newCall, ()=>{}, true); +}); +``` + +## Instaling +1. Clone this repo +2. Run `flutter pub get` diff --git a/video_call/android/.gitignore b/video_call/android/.gitignore new file mode 100644 index 0000000..bc2100d --- /dev/null +++ b/video_call/android/.gitignore @@ -0,0 +1,7 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java diff --git a/video_call/android/app/build.gradle b/video_call/android/app/build.gradle new file mode 100644 index 0000000..f30a585 --- /dev/null +++ b/video_call/android/app/build.gradle @@ -0,0 +1,69 @@ +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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "com.voximplant.flutter.videocall" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + 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 + } + } + + packagingOptions { + exclude 'META-INF/proguard/androidx-annotations.pro' + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/video_call/android/app/src/debug/AndroidManifest.xml b/video_call/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..0bc8220 --- /dev/null +++ b/video_call/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/video_call/android/app/src/main/AndroidManifest.xml b/video_call/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2e3dce0 --- /dev/null +++ b/video_call/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + diff --git a/video_call/android/app/src/main/java/com/voximplant/flutter/videocall/MainActivity.java b/video_call/android/app/src/main/java/com/voximplant/flutter/videocall/MainActivity.java new file mode 100644 index 0000000..cb885a5 --- /dev/null +++ b/video_call/android/app/src/main/java/com/voximplant/flutter/videocall/MainActivity.java @@ -0,0 +1,13 @@ +package com.voximplant.flutter.videocall; + +import androidx.annotation.NonNull; +import io.flutter.embedding.android.FlutterActivity; +import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} diff --git a/video_call/android/app/src/main/res/drawable/launch_background.xml b/video_call/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..1071587 --- /dev/null +++ b/video_call/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/video_call/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/video_call/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/video_call/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/video_call/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/video_call/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/video_call/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/video_call/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/video_call/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..13a36863ce2cc7717b647fce3bc9308e9fe9aa25 GIT binary patch literal 2484 zcmV;l2}|~gP)wA}xptA{22$7^;9u0)l8oz}8Zix>Z4892Fef zkt$dPwSZQ1szsc-00lv0UlasU(6R}#LkRi8x%2J|36QXa5F}rkcg{6x@;$!$%YAoy z?_=CJ&Cm?Z&2VW?fJiuMAY34z5>PjVEUEYUBoiizz&JDN zC0sDkbxI;Cj+fS19zYW)9G%s+J#aXnX2Q(TT?6lH+dB5vc{qTyOmtTtR$oBQ%-k8y zFl)NqSE#EZfX18Xt~x26Og#Z{z;L?VS=3b#Kog9098W0|kf}Zg+#UD8iQs5B5flaP zPJ6&?rpuTDnl){CIO?hppxHVOp~?ib<>Nz8Q&k5-VHb3DbwOptOW5WeG`1ErZF$5< z0EHt z{G0<(5pi(X{|xwg9tPJHJHhV5&9L0U8}{!AfwnfD1W;3B3;c86X|N^l*;@F3%SSuu zHAfDdg^TBJLTXYjowJ#I?p0kQxH;}-51<8xYauy4OU9>&MIaDBJAu(q-wf3xw4;M= z?*&IJ_U0Wc)Sic zdN3S5ob5r9M>mMOmNeuwe10eR@BD^cfFi?V6#{hi;%!*)z8jqb!**Iq-jLU{wzPq_ zdjNX?VSe&+e8#ZhV3O#t_%q2o_6t9OvZs|pURPJ!0BdZwvj-4Hll0X5VFOCPUjXKY zu3$kdXsg#zI2U#e+S@yZybjZZkE}mslLc|$a^z36ZGk=|{--oJucBj4t?%9XANb+>yAToj1FT-YO*MUxz11gh z{9hMfn@ugFBqwA+Ow=uKTJ|}~ZPwE0w2|vayM+BIdGmS_wIIyG%br$1TPv^MWh0X) z64;SvV`2T8eefN5MeF2u@TsGZ3co>Lxr5|cAuVI4C}cYAUCsU z$m>dq%15EGKgyYO{H-*F94fX*uz@DFL|k@5UGt*6nzmP1Rf}QdP&8EEOU$OV6)v#^ zk~7IuYG8YXRe*v>PNQg8Mo8GAt*>hwFzc2sRyVH;WEUW8)OU6YUQ4sAlix{88CC&u zUAapp85}J^i#zkpRdxZgv-E+|k{5C-I9R?j)cYuR|978VfUp~gxliA^NJy7M3-KAh zJg=rLk!vyWaQ5U?BLAh0_ue2dJHDTs2cchoPc0<&Y9bB$)s=N5iEO7!Se!XOA@y6I z9aw!)WzV($f@IQPL%^O;@bx@GawH!xldHM^8fvjq$1l-D54(aFNmRpjho`GQwJzxr zM7$G%`&(i_IT?kpXx_)rAN&>8pVDLy_sFh9--aKrBuJ7>1h8|KJe+5WtddICXs4 z=vPzy3Y`D3L-he+1WHcKk{rJicLT9cE%q;iAHZ^x?4+R2iA6a1A~=2oP7PlK4TX{F zIPUuFI6KYdmQc9_elg8~L%)fpWfUv75y`%f0O$d(X^WhEW zGcbAm1-NwYNuNUxfqTQ~M#8TGkl4}VvAo`pp4K$O`jAAh_KyXpqqm{BvJn^oLwA3z z25ji7DIgSlgyBI-KD7|Z_77hGO>KNCH7^@zaXfe#qsD;f7WaHl@cSYJ?%YhJ$!5vp za>&Unf{W+lNR-?s$JuKo05Vqcvl^ozxb1_xBM8jW*nQajAcK)TtKk@?>VU?yVP^E6 z!*O+gpl+u2vM_}K8E7wA+nct!!0Fb7G0|NG@4ap6g}P>DW=!M~ZD}6SaVqLM>|ZqCVdq~1G=uFTM0cv(-|I)+U$LwnI>ym!kA@y}MEBbO0000gqXF}s9mG>EJ|q< zK~Yh@^n3q(|9H=N#yR(%``q7i?{lAXe=+*H8o=uu*8uOql`CHTOF&5@HAp66y)sussSjGG&JsYUcJkd-wN4>79xmeDhhPySn;dWHvV% zcn}i2*Zw2NdynR>K9ick|2){Os;qIRh8xixKt<&86)+P|J9cAi`~b4f>O9$Xs=Gna zK@Qu<2=HCF50gXvG=iUKQ;#N_ymHh8Ig`DCOj2zOu<-wvtAnVC za-veX(p|^;6#Zp1++ifSnc-FjG5dZ;fpyEU+h+=>BxB zag?%;c~b$&ySxY_8XJVV{MHTCYDpKwJl9krQ|3jTTMql34;CK@h(<`2thhP`HiOu}UUuCSBu&;DmAR#OW zKj9SZK~)eqS~|=oalBx(+nw|$M;tXlSTCWIub(8ca2O+vpGvzH~g-tCqM@F z+HJEyUBOdc$!ETt{5%nk!{O#G_QRh^4+$Qjnp;(}hGqw5kBduUbDL#CIF(@>s5uMm zj%-m0dcf#li%{B?COU$kJ9IwXDj{Veq^WXIs+~7x&(6XoFbwnDcZ#Fe5YHI#+V0wS zctwcRz8d2nM3L0-dU<6FTeg||x=RZ?>Ou!c<6RpNPWLQt-tBIxxZ!GAE*f zT}T~{K)qgBEG$MmW1GKPasq}mshh~KuJ^tPQR6L(6{wGNqCIFSxYu7JJ%4LeJZ%E0 z7KY807$_x}j;shrdOmw>@rVduo!>2bAR>@X{yGhd`YdK8IoB7QViPLOl z_^26`L{;!f>G%rvI7&wj$}2Sz_b55Zg7)o}$8UJp&lN=f;HI{7%S8~`YM?Jz>))m3 zP=CM?pikRxxV($BR63t$EJPHbo{g4GTccFWU%ydl~ic!oe=wEJ|56|inSdDFJq!i_{b)nK)8PorL3Q}T+fi! z$+gI<4{FV=zdF!P!6ETWa0G_5S|(&pF5C$Qvg};6@w)xJ`9YVf_}~w;QGvKgu~75$Z~Xq6*%azQ-Mz7*hF@YdGg zAyjdIm=qHMpc0E@ZLJ=-)2uLxJhr6LsFu6OZaLE{HTxx^#R5T>_vbVnLh!qtra^bq z=PGH6eEv@D+v#kb!fVKkjBIPtV_HOBH#mKmi}`Bjm3KkYuu%^4F zaxF>Le}p?_vt86St!IZawyDI0Cc6aqm#W|alb%H2R~u&O=0l6)vccJCE7QpQ&cBp4 zCP;pyupasN+71H0au6>s6V0IN0l=!W%kGnZD1e&2ynI|+KW%N(VfcBycQNv9WQL6h z4@#YszDJrx9J9T&Bg718oHW^)H}`874|cU%2mg!tz2?>QkF&*;7yVH#%*6%B+gtG~ z)a%y&RP>>8c$|M4*mI%5auTbx`INkmup$lXXCyu&REu4tztxap+mTXK_|R%=(BQLb zp{b!Ze@lfxU+H)<>{89s_(UtHfzf)g_tBHr)qRaiZz4(&Ap>Rzo=d0qC|nsA8ob77 zjITodF_=#{c76Sgl{H1Px5zBoBS!)i9H?syCZVHA_5D?%8ri=vveVOXuyRYo#rQ0d zgQ54h@<*D@n3+IRy-O-(+Ha0Kkb zPdElu(r^?gp)^Xe2e6+tAH&eJ9VlJx?*N;fQi&02WK`t|mlAP}nc~maC9vwF9Ls>Wp%1xiwL3Oko<;_4{Kz~GUAZ46e@AGwxYyt&Y_snkLyVb>L z%UNAhqv`PJ2^}Z?p{e%`tWY=xB*jBMzbf@=VA^ZEG^!+5LT6u4@i}m7ZAvWMEF+4s z65w^i(j3FRWjj!-tJ5q%3@IAu;#*ONANPBvzq<2*89UZ*XY54fw!SAjIG|1vwA-!o zJeN&?Ak`{eHfukvPc8CrTx54U|NhT_JMu~fa(g}CA}Oy?^I5a+8tbR(oxjw)JJF-K z)AFKK`NdH9>vRnbzOs%4vyo=@$Kg&0tE8D1dVwDgNx7=6bxmctD$?AHL}UPSrMJ|} z4)smtfD1f}!CE*6nw;^0=OD9>h0*bQZVhn#m!-B&>XG3SI)(ohQWS?1!0L z$d(w~c6l}^S`Ow?nlZc|d?SY!l~W`A)znzpe8qa3vI55^<2d@Hl|apa z60rNk1hl?t2czILA#2qms?8 z_z5Jj^~Iu*o6Ssa(A6YJfGi5Jc*Cce!20lRz{#D+2Ub$D6Fb>rQq8p8H%xLsN8Q;^ zSxvq!1R1>E!jnxbN2m5lo1a=;qgVc!^IpXVQC|38)@?+yFLd=21wFi-;x#2b4j57y-%EkH9pG=fc6j*%sk<_Bc z=cf+8KD=*{glkkVSV0hRF#8>Z1Cp0;gr>U+YO!D=*Fo#P|5#)( zy%RhN$69{id+3w~e(Q?42I)u)VkjVqeC;*-G$usLVaBpfA+u^2YrKn@n~c}eCf2W# zaoDCh34@GhDlcX(|Jn#!Y)|xF1YuVDGC3g%MS{_Ikxj!9>kNP*`h=;umFt}~9Tz+MFJHI-@HnQp3r8FF$f1+ep^AHHP`p#-mIz|l zR5cDQ!#Bdvd+uHs{-cc6GqC&O?)nFF;BfVxKuYIWE9CB}R)D(2N6Z5w!G`upxv7UrS{7WnDYjqYxfsP`HSz7vw zdo;373}GzDV+uxho?-Ms9cOB7ZD;;%7d)N~u7)|-=c4Q5U3c1Rhp5+&o;p>C-xX9Q z`RSDXoxpnoa$Fid^|gkG}}xL)MySQIMGqdlqOJu|1t_i2=NIeSMrX z-g?EY90UfEU&uDyOufdxf*r!LH~)FAeYlb8?(C-l$~Em_DGW^#Gp}>aD&lo4oc?w{q5K{%6+ukKaO)o@l#1w|6MHb6^FR~7T{N%;Q(_BVDh literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/video_call/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..17c2457db2f1c95cdcbee0c8969b2429ecc492da GIT binary patch literal 4502 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 literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/video_call/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..5b453753fd2211c4092a752cd1de816061cf4f09 GIT binary patch literal 1644 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 literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..dc8b10dd13c2144269e95522b7635803c5566214 GIT binary patch literal 3479 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 FV1j4!tepS= literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..cdb8d02e1ee6c0096908670fc5db755e4e0de884 GIT binary patch literal 5901 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 literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/video_call/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..d0afb5babeb34c662eed0d0c72503a639731c810 GIT binary patch literal 6486 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 literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/video_call/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..33b3ac372a8a8f31903f8345b5d291fea462321d GIT binary patch literal 5700 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 literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/video_call/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..ccf25b2fbf3193d1ed536046bfe196f4f7c6fe50 GIT binary patch literal 10399 zcmV;QC}7u#P)8><|0H{;)r6 z^+9Tp2c}G!QXBGh#@7#)C*t$)8vDxCtOwojDYY{)G9GN(wrw2<{w@68^!F_Nep6~! z@ICDhYXXb}DCIskC1hBGgs?1+WJR`LQg~KqD^+e}q9Qj2f`8+8_#2*s=jsEA2rN6G zYz#EmI9-5g9i8Exq|A;_4$H|+4$GaAtjhT$NtLr9QI)fc{`{B96)O2u)Km(o5H5xM zclrD||MJ&tz{u z;4`)*D|2VF&!*SFwU8Z5*7Xp~lk_(*ElH~Ebh>dfsb=_#Ym8ExoT!9G$yRgGK=3<3 zvhSBK!t=z}iSHx)u1rAX3)hl66W7MgU(rKi=IjqkXd7%mvT9I!x=|m}P0A}{1I10& zhybDgCguVAo9rPq#oz`baHN$fjrCg4!=nnD+U5tUn7z~N@ZvVhSKDA9bD&`h|OMYuOR zkSY;4(gjRZWTz#ove#*YhJU+>jfzGaOt{B{u-uNi*1`TTfagfLL2`Ij5>@l7OKTg; zo2N=Pb0vVp?l~+sxg^=P^P_SfQs5+pX8LneB`&JSZAdj2ZLYKkYf;u3*&k(Vod+lv zc$O~QbuCYd)G(2HaM!UWq6V^SqtYaqJ)p9A{H9u(stTL7u$&!IvsUA|QEcqUx<%ko zWlxoS<7~pCvYh9ZJ+-VgtZ@NB{3AYMPyqdA{i5Yr*@2^z9~Eh%U$Ay%g*vKz3ZjT8 zE3*dB#kf|ib!x7;GSRGEOH^bIENgA6J>N-G|HkZPliD8YV1)Iimi7l~e$N|oV|q|EtFbj>T9>i|4M z`cEQ1uG&JbUAaLt8VxBdEG&|H_X^1VJ$dAn7d|4Xu@6-PPfc+76BJp?Cx`->f@zx5K#~JQgm>iNSicgBI;Rz zx+>?ixxoWTjTu6|`s@dzzympU^aRQ5KE8Un`W!^@ip(=MXU;@7vQ>C?6M7T-s{%Zb z)|3o?Hh+03uS=gCKKKvm-}%Yv7cb%*j4TdHgKWI&x4oj$Y>!P*Y0();NEZ5vc^)`qClY{r%!R~jAim#@Tj)`x{JE#<$Gfn zFI*wxAAg&AZ@D!je+E)LkVMORWLcGGCZd@K3NKr_01QFFS6`e*u3oubZV>UOAGcRy z?xVXvEj~2kN~El7u(gotBHojv6iYHnCq~<~97=jp&5+*e5z;1lFliN$Yu4y*R?lad zcclwJck}O&nXi3jzH11}W|}R9-KTY#vP5diS_bvqM)&MNi}N9|w36D_mv!-;4hh4_ zXY-bm-G3h@+cxhcOTSu2-g{#)nKwBm9bDcy(W+&hyK+K zpu6|TyVE}>$>BMb62L@0tzFzOYCcDk+&&Y@*oUW+H>Z9~KVuOY(Di96OO@oP6R0VR z3hMc$Rw=P%NOPhxGod`*gUyth6Lo=_c|VsfUL|=)PB0?7`um^BoOhRy=bw6?Jd^=Y zjU$~>Mlwl)Q6WOMysK zd$ki)Ilt*LU0C!No_^opm<-(S+th{PQ&xOw9ixp4k6Ii7ct#d&_+w1cc(_A@n&-;-Hy zf5}YZ{12CsA6NZKPMtWf*8>yfCe?(0{%~7(lKmU`bNfD4 zjCSVK1*%PMk~_EaNdYqb8pEz1LCqJR`M^p&y&QGCVgQK>?l!54wU96{DOQ!?%V*^f zT}5Fa&+AriH5owq;y48b1*~-A-d*9RMy)aaeJB`^fW1d~5x5cF2WHmTlt@`};rtcy zaQ0*?F4WH(N;|b&>!3OGCpPP0mhag{R>0=)2f0{ zGZj}mNtwOOkYf0!N6nz#(DfP#9+<_I-)*v)G)J_&=Nch4WF|8vYM+FV0qrEc>gBq= zaBpwlzEdLs1j0Rg=2y0oaJ^5t5DD|`)ZL6)h-)8J_DVz26^O!q`RNZvR|r-YK@8}H zr{1>}0BM*O3hKVzELy0D`vf!YV^FfRUEENzk-EY)mH!}?_2{6fHkE8`8Pb=8_;qMk z=~}4B^HOBZGc;M+Ep-&xyX%P6Y$yVh|NV1@?AmdVMT;*|7aL&!bA2A-Rhd0(sZ^F~ zA;mxvA?sS%9+?pLi45-ELSNiRySVH0$@3Nm4uXofjztSrkTJtwBbnWwVU34VCd^`~ zhk|?N0TF_o-EFAWNQ?``2KTuZ=$#}N;zE@GBCg76CnyIzZK(D^2Kuof)5!H}H!TVt z1Ot(4dx8Q-JDq^&@UxGP)j0&8fy(6|3v&vIrqR5Qf(7CEvoS*I!3^Vrzfx|Nah zg49V=W%Ic`*&0KVk1tQ0%{&oHg6E%Or^w^OUM;g^6=@b^%A!YK*P* zo8@4#Er|~9xrgq#lVtxZ#(iRgGg=u_X^72PFzZ``b5iE=f@Z$Hh$UQgmA@jHYL06} zN@Uveb1SVprRvFaKN8~Ip)>ZrLS&k&um=;A1K%>H(h$+t^*?O0Xb|tmm0L)c){pAE z#!kr(GoDfzIWKL2=^pp+bXzUL*P!$@Jh1az?0rSd7*k&=cU66AzV;hRo*^g|-L=DV zIWV+0k01Rut0U5NjmS}<9?2Y^f9~uh@=(U}HaiWCnK60K!`=unbrO`BuNhk? zk221yS8iAYJo%Iqzxu*F(n?RS*DI8x+__^OlD~h?QD!1-7(g1-3WdwkKLiF$0g$M+ z9H=_mVyO33RMg&Myv1C26n~-CTDzDX9uW%r5uX~G@d8=(-KKJ@2`eHn-|gdv*))Jq zu^1KD<4=kKXA{hrkoSs`bq`8X3iFzc>GMLFs3o%SAjH_b?x`gMcqo7UV8$2Z_icN~ zfxXAbsT1eS8e%{M9wo81-bWS_)ca;oi?}GEqt%F@qUe3K4DO$440#r%Yn#VN-r*BE zD*#b&jVwj@6tvR>07u^8|5$N4%uJ``ku2$oh%FX;(ztiY?_2kntQ`=4Su}q+>zoj; z1*wa_e%r@@TUDCyI{ktG7}^0$1Xz(HoHAiH*}U;Da^l~!EMA3r>*GgHl5f8Fkv!D@ zc`NDF7u@-`Pee=-)ahh@y^n`&Qwbs$4 zfCYwoz2x&X2KBd>l`wth^+hF$*r!dJ%QmU1P3fMUN61r;zR6-@NTWczJTvMomVbi= zE(_4mpa=IKClkiZw1Oa{z=I+KyKUt>$k18T0{`*yigim=WuGv`gcX5-s_6+&%w%5C zsE4MJw4@PwJ2mn5z8%Ms^{clUZEir^0T^lg2ScZznJf{^{P*~2^4*dRxVp-{1s-HToe)=54@Ss)#3U7sOEY~?0v5s8 zR%R5VjeYoaqlq}44>Kr!7Ji~8$z0x+VL&Qi9Up2V3hMy)#S2%Gw1g2BC(^MYeboNm zNvQ@$rTLTUw3PSiFF8W8%5MN(%+}32jUv^TFJ5J4LIhAMX}hn|2p{BO}3qs$N5rJsImMiGG8#ttPr{@8Dm z0K&aIMeoIu0D>8d4;?_1{%NlR69xf@KglscF<_Rd1iEsjuI7??A1q~&WrH=)rK_yQ zM+6W+h}Ifg1Q3Y!3r~Mw6;+DV6I%pK80g9~4&eJOmX&`ufFVaPq za-g5qZnr20GFby%xXR`MSc4}PF6)e9`+6K3dLMXFJ^I4mEos7#(cfky2SN`$f`(G> z1!U9`URXut;J#xlv5yXV znT??{Hjz5#o&T{Z8{&Ims)o6;?&cDBZJ#e#K{~__w>W@+fvBKvd9`ZQ$Ee^sQ_6GY zc?m}ye|MEy!RE4CWZS{};i<8VcB#a=hJpYkd`u3p(aY~}D!|ZS!_!~fu$!AFQ;FKYZ z^}`p*nuc-~mv!{H>(?wi3D_tXKqH0O!Hz*KlA{t;IrmHj(2#zU3@<3tRKEH6=>4yC zc4LTwqB3)kYY<=@A(awg`}3!z=?vdysuW-&LzUs67eI2ar09wO2nFR(%a-zD4(!d- z>jGmSImXwSqorpy^#rTK0P`XZ6w(g3 zrK^MbKBvfH)|XmsTV*QLgBQdt81W7 zf-=kGVltFsV0^BnBf1#li;zLb#D~lDhLCGAhpFBD_aTyILxUCc1E~9%1`WJIfQ`20 z<-%sgOfDg%Y=YgcZzinIVs>HH6tvO<3;v4x2lGval#bdMmW)2qW6n+K4X z%7_T;nny9woRMff-5Is{R0h`s#lY>R0tn_|(fk!v(g9&8sm2jdZ@uy<1I_r+Z?Pyj zyfAZ&;5&QzBAZZa^8n&)&JnUMJ1HjIIW}tRDX90ylbXaUGQKypoCC?w8Lxa|by;vk z!ckz4G>JLW8Ze6hYBf0Rkj+jE3rIsbhbzZM`2h0r@~TIFHjWMHH``0H`7<<>4W24;8j0e2Ez0tzaC@Q$eq>7Ytz=cLxX3d-t zUBG(ZY;V9+>5^7VEDQ2!Jp-6920#r}{vER_(vi`dl1Pxrng}46$E9Dcv#Akxx{B&! zL;4bb&$!2c34;J6m&@UWH3;;IOHNW|o19QZIR`T9HFeA{qTJn6N7;N7Iy$J=-R8|g z(}4+pe}5;v0ODnfE{&ZU`z0zf|1s5!p`d;FHyf?S6RT=LT~C%xjrlFxg^vvEda8kA z1H^z__}OB5yHg+JPxgpYWUQ|Uk)HeB*Njls%t7O4$)kg(+PnuwsmxX$1F9!EXSLi% zZFhI~`t+w;Oi=H4D$<#O(+Vv;>eo_&`+jl!hc@kjfk21&q<#!6a7-9<1VU|2mRwZ< zX@e_5q%pDt{opn7u$4RcY}Bt!6X@VR#J_p$7+`^8qPBt4IT(>{>K zH+>x0xBFhfCFdlIvq+G;xaF7s%On!D2`F!C@Rs~>4dV|l! z%vwq&j(vv>B*#$*C^3Cw%0jYm*0-!I1EYXZZi}gAD9pdbfojOGs=xm{z{+P0jozaG zzfZ@pWYmypWXi}YaSSK=I39G&&jGar%>S(8~Y9AZr7>e@gGgYln$ju>(0%dt?m zmJws_9&~eaLnE1Iw7kc3Qvrl;&KIAoDikZ%)@1Bc+-iXwfa5HMq>yv-Hn_Z%jVq;R?B%e~(ppqLv&TA0NH{4WkJ7l2#^=iUWxKiQGGR9-JvxSJ#Gy66hixDo*!arJ8^HveKYO{{wi~q9RNf#6q2mME zu`|6V^u9rBLi?0;U-)9-Z=cRv&NNs>DgsbAhp~b0y}6ilOMR@u+DOR2XOS@fPKW5; z2XPEI8ar&91r!@KYSaWgC`#UAW<~O12r6RmrL^VPobt@*x5~}K;cu8^Z;2Kfm@JsY z^*?MiIN4mFp+M0gYRPadn0=T-Q$Zv(UqRl<3$gbN8#Z*++Y_&c2Q~BaY}qA2nSHOK z)5@wsFrOKR-InK(LH(~-y0OGG*D3)I-B@TQ%tO`2axZu9qEjg{j&_Xse6{4U^ z-{zb@dx<@_s!A@P?fP^YOE#?CW>}9rCf?uFkV$!J(rH%#>9A9f_Eg&aT|jd7tI4`c z8gg4*I{pM+nVvGzB==p2K6k)0jzGTmj>htz67D=#VJ(!h4$p}y&RPKkk7@myZHBq= z^f@4}=_!v?$+f{n|9I{)=0xZXWl%XvHO~vj)TFZnJfaNPrzUGCc&~` z+0Y0c%Dm#IW6v8jXwcMH_q~j~7-Qhg8oRhh#VH1yt?0xKbDD?e#=dJ*w<)|agbB>8 zg`gRq88w4>T83zz161=ob)-&G(kky@ zM9RzCUDcUtA*&?Q@IH)ZwkasO;-c;5XdtIwmlSZa`UuBhdIJ>yGc+j7+XnD`&)~JQ> zEk_ZTu>jh(c^8XEnd`cs-7xg3yd%a%&GQ@uPuJZ7c%%RVc*-KodMEea&S!_rlov3S zX5K@6Qc*lF<9qE~QS((6nfCT+7S%gmk)gIWErjw>L}iTy(5huW8=S8)Mfy_DYtODD zPoUUlDh%~$}oQ!zu=AANwga@eRc~L@`rJ4ueS!;sXD(m!WB#q0u$0F_% z*!51cMt=Q-%sbOQ4izQOy0nmsv$JyxAT>lCE#ORNzuieQu6f zr)c1MX3zXznPt6*^OOai4id8k@IXslyjMuh-Yq0&v;@D?2QZvq^ql1U5N+*)BfjM= zlHhsC>E3$ta^^afseQB}(+r`$_3AZ^iwWs-8W&wryh{s)FknLa$+2DF8vEOr@l`%kGkKp26Hz2Vn+y zHeS|{p$CN2MO!YZe+%i1u}9Qo&key8mS0+XmmPs61&|nZjt=TY{5)b_#a^0Q`)F|? zmg4uJ5*jJ%wplP`S!!#GOtXV_+docndQD(aSsc2{fKx?Tcub(h;Pbm$CXA&jD0zPA zSaF_9Oi#chAFUoSgjW z&k&_=o7WKrw*#oO7DTNzGXG_|@fra{e_hv*n+1jBE(OmIXEmhrwgTe6u7Ct?C?GK$ zMD3`S8hJ7kkI|P^@{bU8@Qnq84%zMt(S91in%g zkiG$v9IP=J+jkA`eLHsa1R2u*`Jz6rNO`wHuV#u-+;jy9{a)rL&iYIll5R~M9UbLRiy?lk zXJ8}<&RVth^4F>o6x#o=Tz@$SOj#b~IHPx~DF>q9`S?H5_>pgk%YgZ$UgiSQeE1?V zfBgY+%>Ye=njjo*(@x5wlF zyN_pk5EI;+1o@<_z~1mZYGz5(rOT8x5b8)+D@eG?KW!5Tn;k^OJz$^BTh4fiA=+dA zsjDR8t@WgS_Cn%Ffg=^akzbI78xD}$`2{+U{+vE#0cjOESOaSi;?sHy-IGYZH!b*H zSRP~!_6>YKU;hj9yg!uF=IBwg`9 zEh~9Q`H(9mXfi~p8#p&e3X`QD!O_un5DA1jxAz3HVeNL-5NJqQ>X9>7$+U0&B2Rv@ zwUoTQd>1)(_F8e;;&wjy=8LtYNBhTxNV9+YV{{K%VK4ZexLO16(Z`1n(RAZPP0_f% zXS?u#^y8u?vhyLKD;4n>^t&6PiS8Asb&8r3b40sQ`Pi+^D0RF7;OX#RBNvY}>;c^i zm@YTIH+8HLJlc~zK+xPp&kP_^1#~=Y=S0#&`9`s0p-}Kukpo{?b-{su$SW^?L^>u6 z*R%}jPZWOb@;G=zkIUVd5p~u;s&S#L9f+e}NmXfz!ar??=$+YJ{A@NCVD!*e$%ZxC z$oX@ZjRF#YgOM}eE!jW@_n&mXP1Fz#db&dVQg=6SYS5a4Cy0Ao^{X;fQJEkD+xMV1 z5=?)p>ej6rqx5UP5jQHtiG-Szn$3%ZIZBTVdYR2P!f;OXxuY}}(QEJ^0E-RPq8#Vq z`77)o8_W#CiP-I8hayOLKPIRb3Gr>UnXYk5tTkVA555O=t&KDr>Y0h|y(hmRCB4C@ z5bsvspcX~U&)7XQ0Z5p8gchUhp3e${u3lcqx+*YvLHW~@?65qc8B!R# z6D99Xc2{4w))8W9$ZLi8 zwEDTeQ~gw|p@T#HFh0xBP2z3YwC2&JiR$uL1QK~Z6hunoXTXaByyD-CkafMqUH$tB zc5PGyoCHDZ+{fC42c+Nf_lTK^HN)ERFQN}$(|XkrJY@wN5e;o3ngo8G z!obpj80bxKFZ7-kyEgLf$AJ^cO%}|RA76_`cCBL^H*(?Lg{QEH4hq5Z5HymrvvZ1{ zN7O5!zNvqRT8T%sCEknW03`xOdMykz%1o|py57dM(|dT8-b*Wq#sSY!aNv0IHE^lP zT*p*xREMkT`n(XTxxfJ&LM5gxib||oL;tM67I7ab{M+x22<(~d58OXdSMAyRt($9zbwcUbia&H_sgkEDDzt%`xJJ+hg5{)AQ$H@+y z$_J7YU)(0V&c$2E|2QbMv=TNbrjd(lCvSJT1(p~dG5-a z-%As_#;H0WIqm_olj9Scp*a8agU3ArJ3 zUWOokg3Xg?C~Z*1a19ZM&3AID-;QdH&P^J6c5BkWtp^kOZ~P8_;{b_=xs<$K0v18T za6#-QgkOt~7HC8>RhQq39XJ*MlD1Zof~hHYf4%rO9-A1%y*UP|x^-QOG=%6nOC(B5 zivCuM^;n7jcZn(n3-g|W_-Fa@&-UQgA_a}Mwy^`pO2Jf*2i_WUa_Y{BY74Fr{PMuS_>c(M9GEypKFsK{#+S4`DZoepIy%m8rucagM8EKa&qd-V=DDI ze-eS!l$#cJPG~(i7^LFC|K`r0+f)LShWtHU_-8os&#a?mp6sBpaX?8yB?8NVZ@3fR zd}ppT$`bMKPW&|v5}-)IVh2nO0hKnmYHI;aDrG%K`+aKMM002ov JPDHLkV1kUm`lA2< literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..02f0e1ca8e2e5b480b33185c50d09bbfd138e79d GIT binary patch literal 8069 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 Ixp~0<0L18I5&!@I literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..c488e62f0b6e8ec547f0034dd044c3b365f6743c GIT binary patch literal 17593 zcmdtKcQ~BU*EX6)5)nd*Acz)G22rC&4MvGNIuRwKM(;!j5xtGxTh!6}DA7AJdQF1S ziP6jOJtMz!eeZkDd(Qd)b6x(iJ$pZU@3q&y*S+rb1ie#wd!K-U;M%oo_vK`zRIgpT zUW)s@gAe?rTZxn9+BK=qa#G^zuG3oxC-sG?#5|!(y){u(O`ZqZc_>lHer2#fk#}xP zBTw&7>h}i8&u?O0+PS!p{n@^|>tEY&PwMXVFW^reJ4bU712y=q052*qlMcF4f{LFZ#q>PPu9QYwaD2kgtLxDG6?AK8Fj4 zdHuHg{y;)cKu~inzN7m-zE{BrO-R~hUBv^5Z>)LmjD5_O@Ndc75jXnWa) z{ts^9-wAo}rRAD0iNu{7H-T2#JA@CO{ zY5qMk-LK`ofnmqB3_-3B>BG0h;!v#juionE>52W*J=hETTUulPaY2Bb-!Z@P2THlXd#%+&9=BG;m!oGrkW-g5 z_S;9Pv8z8^dj%RkFO-#-Q3Rxh z+1twzHZd{jX-dg!Zc`7&dykd2(h&7Q(hXb9Z|2p1zwk@8VwNz}EN-RC93l1|ZJT!SCgIf*N!_jIpL;BMp{@amM(tjiS zkW~XO^E(Zm;-)XFjryU(pYlEk)0N@I?9M_q@NX{vz1ZUe zC2=$ri9&M2iL>MVa0ZyYnX@OlCDYeYQInIr5(^$kH1){VKwLK?4%@-I>U>SG-)95l z)tDDwLK!AQdDG>ipj3f(kLZ7fzJ>m9ceB9Z*7(Ss5b}S2BZoaWP=FakM(zCKZFgcl zOu%4S?u1;8#%A6!%})^V;Wo$X#&41wKhLXlIKIEWvi{yD2yr)T0XFJE+9s#3^xKY} zQf~*vJ)@@ESG!>#Q*v54L`;4c4Uq1>=p00GyaE-Td*#Z5V8nNE zC)-LR)RpfzK;QiR8kD@;y@wjAT_aY(adq}*Dr1m{(mE8M?D0lTRGj%4qSSNa!#v_K z9im<-N@s!Vj1G7B%2f8>*yWkEEv@{2vSU4- zz!DNniR33vnkfHGNubHxh>Y7~c=fs7$ZccnDXf3)MWk&eBR@Y}PoFpeXrNnwKy6fGyO8WR=QKIThZfx9tLvs1++X*c=bN?)_x+$ zJEc=@1>Kfyinu_Q$}7`17_!I)9gmJIlWCam zRrefcfOFDzcy^&;GJ-r*R;Spp%lw9evc_49YZJ>&IeSibU**n%zuCRI`)ABKMi)f8 z4jP$eZdR!>K<2i-+5IRW;qIzXN^OSj-IUuf*-P{zwG!!H9r>)E6yEplQULw__FbIG zvm@S^v+@h&tODgiU*^W8jD!=qx zn{$eCwB}Zw<|T^A9e?PFpuuLJP8hHYlqS)IA*z{ijx(|+3lg6YTqvhUY&&r}uIpVq zjq1-7(yo9m5PdLxb41Q%*KV)fWE3c%noj1uK2-}iYKLy!duo*uYCe4XpAQorPIN4I zu#mn19Ejcr{LC{x!Pl|Q*C6?8zhIG(re@F{xg7>RL6uao`*DSF+daM_<|YH>2(Ax5 zE%u}q`cS00847K_oMe`J1klm^C zGp4+7!&r67{-*gX!@c^)XGL(+Z==Wcg>zCGZHXi6{nc^@SLnRt+t3?EFDYo0IT9K-irb)mb8O1816h zS!XmAFN&+q@WM}b9m*XTMMO}9>2_s7W_K~md;Ip7+iKhncc;Ck2`?P-O86_jUian> zF>y4MF}EJr*ypt`JoAHVN3nrPg0@e1O6GM>PZg@nzL_)9ve&8mx$YX~$*P+a@$Suj zKpd8hvjLZ>=b8$U+)3g@VV^gPbV}>te*8 zjZysYEJn0-Bf|>@%8d0kDYwHT(Z&S@vA}IV+Uvko*S|JqcHo1FPDu(ESPJ+v6b$P6 zrl>2}p;b}E|9b@UXNnRFbr@E+GSXlITZYPjbnmh2jF9}gvz&(FqKS-N@ERu+&7kvfXM2-ABpCm8ao zBKrmJX*^bDj$ZBV2K;o0<;N4JvjhT}xg_M&k0+{x+q^UVxlj6M*)|~CHD)DwOIClK z>bw@qw0rM)kehl@r)V%Hi3saope$s|P&KMzUHKm%q4AN|0Edru^o1TI$V((I!i`~c zd;KZ;JM%dSIUKP+0i1#1S*jAQJ?rnscYHIUL{YC-ZL!Oa!ZV0_;pEKaHcGI!VPzRm zSM(`2lN&)cUc>?7ohw0(ho{8s5B7g^Y=#18NJdJntAuM#&@n)u^;F~1?P5PvW^jh@ zS)}CIV9!)E|1!GjE#~jML&bhxAAH12Ce|2sVQ+8W9}5bT5xbnHV#;yCUYEUw^T6H{ z_w^IMR~~J(A12l2MWaf0$mYME{0`M2f$vO)s-QCykJx$5ba`f41oy$WL z@!rCnPJ!mni{@h5d_F>1+>gLI76E#K9&hoT(|oVtuBw%LMRo@Ux%cqi*sYG-E-n}? zQ2zInz7c4BKURoe64zrTfn!&0R_-j#b({koEPiv2Y};oU?dAIXhvmURV*>0H6$;!Y zz>47gnb7Zm@3|)JU-SQN;2UolM%SNE9@ZyFf*UMvkhqDgcseb?|}0)M>mCruY&IWU)o2fhFM7B}sA zi3003U;B+|df=(18?X3!_7klDeDI$x!E8eOG-f5-*I$O!M3$8s|5mE7?fn&wTNT8O zvb+_kp8kF_#{jyK4Q&Ha5BiE1B{?@puI91N&Vm@E=io>qq4+N4@q8XZPM3A_3D;kG zVE!d`w>voHS-9(-jrdWbh6s&P-p);Re;86`KP`c=GWJDDJEGZXPd95iHiiR z4`z6twYOZoa`TOmiUU~yolwxnYU!O|*clZiXaak7CF4xS{^+9(imrR3a`L*QDjNBq zOZIzbr#q4~%~AW6ggx+U9wD|_fBJoo0yI4SO=3{73ND=UHtsHf?m`mewc7u#OZ(T! zo1ojPaKQys8{W)woD(>DG5FTPd(qU}S}P}z2abZ&SJ7M{;a~J|jIU@ritm}K&%TG# znGTK~s4i04{#%Eh8cv@LdSLpzH@P2$R==zFS_~>GHG7U|P>RZ}IxqH}?c1dHKK%AG ztwBC(9bw{nd4dt<(X+Rob&*psJX^fY(Qg$^>VDCA#tx`UTV+0Wpn?GaD%aMdz*tiqqh%$NesX zNQS>ev|T-|us%2>`o6C?+6##-Ddz*vS1tRKd=}yu>+EFc?QFS;tZ%*cZ?L-j)0{kQ zBKN&hQ10n1Xg<09<}c~pqXar9?^Uw_tv;=ndnw^-29dcr`!;NxDdOxYH3PF$UFlb* zQFmixW^-Vbobecp!C;nJ=ga}L!3EVr)Fep99(au_F&*vr%L8GRN8E68NQ`#$I0Y^D zD$bad6x&!tOb25Qcy_V3+}UmBzI!1vdLB4vmI&`u4BDpwU}IMA2=r_C&%@%(XJS_Q z33dN@knLBg8UDd(g2?^j55GHc;Y#xkPd-+%#y&1YnH-@?H{TwwozjrGa_itHiuS_c z>EA0K0D10g!KWTZUHiFAlwI?iQUo41pM1si1)o4^gZG#>5W?DTXsXuJxNa}q-#tqG z`T1&shDM@WUEK$)#GK=Xn_kO(Q_&NO9>s}#ALG;yz{Gb&-KXxfq}+QAT=mPtO%7=D zfa_N~VgGP}J(ntKzT_Sa;b>1j*FvIKY|W=dFC0YLo^#&0LBu$pC~hOVs@ z2krb4t$_YHBdLLl@%5STHXWAtu+@P3NH7>Tf88A)=2y0hjGuaJpayv~H$`#2Yjzbg zSxXD<_tN}(hRJwRRawB_^1{QAr8M#;nQXT6uTOjOL*4wZ%8fc-poF6Ty_$uE&w^rZ zn7;H~?Cq6gM?OKDRn?>v2PC5`LI^BYBDCZ4STBo|5!Hp4SZMrj?ecQxmA%pLSk6Vy z>OHvI^<<%i4oatXVbrg84)LDph@AY+h*p?7wn!w1ioSz!Ows~zkmDJC6V1IM!7HXk&zRV%pQQ#K zRxw7c>}i!5LRp{PZk^@m%sc8+Vx{NRG8+l_IgvWIgN)e*DmrDFKshPb5C+C3hm8$2 zQBR+Jc5c`MoS~2vO7t6_yxTcp05<0Ie zvX?_skvVH$Y}f@r1g;O~7JI+i{+SK-S-iphv4Sn-Z;}xHBKWC}DDO;)EH}0cK3L_U^L2ITiL$K6xO0S?*KLCFT)&TBUGsjcAoUImxWsSLR(wh5A?k~?`Pffm?0pQj-+ z+BXk@D9+S^D=9j~5`Xtzo^8+cvWMwrM8}^QyW~pfYuUu{>eOt@eLkp8MR;Ywf}yZ( zC?~h*<3t0}6U+%^oPbmc5Tjcb`>Gk*+F55fl5dS5R&rOfxFXF4GKcUNBAVuMVJ8ta z>|)N)S9+a925gqFEnczP(+ZLCt+&eTpCh-IAqFf`ToDLS)dKsvk4T0S76T{trl~t?^~eAHQ6ElmFORn#yP#V~0r5w$&Ug@ZYN0KTC^>G9!Ql z9Hx8_33+7Lud)m#20MG1L>xq9iG5&UpL;l#;37wJZJ$o@@m$u~kRpeSzUF9BySAp3 z(Yqczv(zw9f~zifFk;4!k%enJx-UpzN`Um_h324+-$XL=M!#r;O?_OR;V%x@{{Dwm z>kc7)s%U=rf}phVX(b$-QBS5en*O5$udtXr?_#Q#@9gw10?F9q=P}s*c^d^VFmqx; zizP={X?5>f|ykkMvlOy*?sO0i^%f>51M!imu(Zz*SX3yN!M=<`v2|= zS>3Ovo)fF+I6A<#1w0{GTdC>@y?)ErH|gFcmNbEVs7P_d}^Jhv|p|xXww=kz> zf&mJ}HY6^%PA%uxYy-Hnw2M%{Y4f`_yS?LGELKQa(N01IUIt({wbD$#S1V{tKdrU? zxLQ6(LW4$b=zX5si&di+zve42`*QINOfwhHYrMBh<08>}0B74`=EX|#^u|p9H1v?+ zF%BO1tg(j{9KdA8Jd#W^*9~2&Hta*atw4msHY>#2qE-0JT_8p?Q&Sulnw_`OPG^{< zsSWT{KU;T*4~aA`PFpfuzOL=wQFK&qYy>M+Y>?d4w`g+P$_RPJxzK;AB`<|TyNLw= zg=t!!q8pafE7g^9y)P=*+%|#!nzVj!rg?1Y*G6ZZvb&z@0;lZy)z+_BQgjKkS~;(< zHO~)Z+hz*jaMw#Efm`p@xB`Cc{?sP zn27)CRzpJ{c$CI(Y&S}a1|Xl}Z*dhb`YL~2*1s)IvP$x?yx^mF%1UjStM{Xxi#M!t zjT2a1f9XplZAqG&E*=N4a zkz)40z5q;HWA{XM&Wv5zo&K>}?`2=YEg{JI#cJOI4GxjjAIh#YWxS2LQ`!PQFOox2+rSD@%dxmvzWoV2u`1XWELq~r~b;juZ031JP z7B?S)V_kF0!XCssONu@8oZI(1w<1R{j^*rCCwWK2j5IvqNNtJ)n4Cm|*mEq--z7KP zKJroi0JF{c-gZgrseKOy&i%#3zaUGZ zXdIjyrp+8q^E#J6MOSWZIS9bdEEp%~;&k9qs zrm?q)x$YmWmyT&a>?6mF)=&<-&h4OJeH9wsQn>-QE%zD?qtu$-6OQBKE_o-IfwU$ zmv$cDOu2GZe3bm*c>EL9u#$b0SMl;a=SSK-xfR@?{nu{$-y19ZZ{sa3FDJ<>A?6wA zMfzyD%>mRBrvKPyhgtQ^gXZ7r;;p1i^E`Wb(_=6ONDU-B5&3}6!F8s3;C&cvc+nwB z)m-H$nm)ni0NmBz7j1>dD~x9NsbgUWr(~e1b%g0u;}+)BG-kk-!kGiQEC)pG!fwZ^ zVKhxw#2G-a>o!yK-5xd!l$I+=G0Q*wwJjP;xP=AV({{QQ_H-Jovpd$(L<9A zaf5TOifh!Jt7GB}SOi_x@u4a;&Fa|iIg+>VV|9!K3z1AyJ>yn=$qv2!)%f4_=t)Dh z>B{ko<5yi#+@Jn@TgJr&^r`k<^Bj)oF-3O|MVQEp-?FuO@`>IcOP40JP&PQaf-iJz zkhp#{e+O(zC&cL7}F+tdWp$Dnz3WYg{gZDEf>JyD+t zp6Icuc=>l?O48Q6IpAE9->+aXM6yhl;~Gn6`_iq;*{4R?kd)0CH+cza1kc+C@(s=T z#AEmF?m7(Rd^w5ZRkb{*7IV^2#>{7vfDWKhWEffPj5)*LfJh%1)X0YY1WszUy7 zM;HVtzJ7Rk(1lL)n4@$**$kDEZcj|gVf`{%sk+x5$!gZAhb$0_MGVFyj%~AM;e&YS zJY09`@}G~UWeg4U?jId2bTx*?dALXnXz(=w^!

qRx#RIIgT(KT*EY4F*d~F-;;- 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 literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/video_call/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..08d6641529f4daf05e4d19d1be6b9d6af10b2b23 GIT binary patch literal 15211 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 literal 0 HcmV?d00001 diff --git a/video_call/android/app/src/main/res/values/colors.xml b/video_call/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..c3ed4b8 --- /dev/null +++ b/video_call/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #1c0b43 + \ No newline at end of file diff --git a/video_call/android/app/src/main/res/values/ic_launcher_background.xml b/video_call/android/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..c5d5899 --- /dev/null +++ b/video_call/android/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FFFFFF + \ No newline at end of file diff --git a/video_call/android/app/src/main/res/values/styles.xml b/video_call/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..00fa441 --- /dev/null +++ b/video_call/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/video_call/android/app/src/profile/AndroidManifest.xml b/video_call/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..0bc8220 --- /dev/null +++ b/video_call/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/video_call/android/build.gradle b/video_call/android/build.gradle new file mode 100644 index 0000000..e0d7ae2 --- /dev/null +++ b/video_call/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/video_call/android/gradle.properties b/video_call/android/gradle.properties new file mode 100644 index 0000000..38c8d45 --- /dev/null +++ b/video_call/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/video_call/android/settings.gradle b/video_call/android/settings.gradle new file mode 100644 index 0000000..5a2f14f --- /dev/null +++ b/video_call/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/video_call/ios/.gitignore b/video_call/ios/.gitignore new file mode 100644 index 0000000..e96ef60 --- /dev/null +++ b/video_call/ios/.gitignore @@ -0,0 +1,32 @@ +*.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/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 diff --git a/video_call/ios/Flutter/AppFrameworkInfo.plist b/video_call/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..6b4c0f7 --- /dev/null +++ b/video_call/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/video_call/ios/Flutter/Debug.xcconfig b/video_call/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..e8efba1 --- /dev/null +++ b/video_call/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/video_call/ios/Flutter/Release.xcconfig b/video_call/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..399e934 --- /dev/null +++ b/video_call/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/video_call/ios/Podfile b/video_call/ios/Podfile new file mode 100644 index 0000000..98a90b8 --- /dev/null +++ b/video_call/ios/Podfile @@ -0,0 +1,87 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + generated_key_values = {} + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) do |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + generated_key_values[podname] = podpath + else + puts "Invalid plugin specification: #{line}" + end + end + generated_key_values +end + +target 'Runner' do + # Flutter Pod + + copied_flutter_dir = File.join(__dir__, 'Flutter') + copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') + copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') + unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) + # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. + # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. + # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. + + generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') + unless File.exist?(generated_xcode_build_settings_path) + raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) + cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; + + unless File.exist?(copied_framework_path) + FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) + end + unless File.exist?(copied_podspec_path) + FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) + end + end + + # Keep pod path relative so it can be checked into Podfile.lock. + pod 'Flutter', :path => 'Flutter' + + # Plugin Pods + + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') + plugin_pods = parse_KV_file('../.flutter-plugins') + plugin_pods.each do |name, path| + symlink = File.join('.symlinks', 'plugins', name) + File.symlink(path, symlink) + pod name, :path => File.join(symlink, 'ios') + end +end + +# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. +install! 'cocoapods', :disable_input_output_paths => true + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/video_call/ios/Podfile.lock b/video_call/ios/Podfile.lock new file mode 100644 index 0000000..817b61b --- /dev/null +++ b/video_call/ios/Podfile.lock @@ -0,0 +1,59 @@ +PODS: + - Flutter (1.0.0) + - flutter_voximplant (2.0.0): + - Flutter + - VoxImplantSDK (= 2.26.0) + - permission_handler (3.2.0): + - Flutter + - shared_preferences (0.0.1): + - Flutter + - shared_preferences_macos (0.0.1): + - Flutter + - shared_preferences_web (0.0.1): + - Flutter + - VoxImplantSDK (2.26.0): + - VoxImplantSDK/Core (= 2.26.0) + - VoxImplantSDK/Core (2.26.0): + - VoxImplantWebRTC (= 78.0.0) + - VoxImplantWebRTC (78.0.0) + +DEPENDENCIES: + - Flutter (from `Flutter`) + - flutter_voximplant (from `.symlinks/plugins/flutter_voximplant/ios`) + - permission_handler (from `.symlinks/plugins/permission_handler/ios`) + - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) + - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`) + - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) + +SPEC REPOS: + trunk: + - VoxImplantSDK + - VoxImplantWebRTC + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + flutter_voximplant: + :path: ".symlinks/plugins/flutter_voximplant/ios" + permission_handler: + :path: ".symlinks/plugins/permission_handler/ios" + shared_preferences: + :path: ".symlinks/plugins/shared_preferences/ios" + shared_preferences_macos: + :path: ".symlinks/plugins/shared_preferences_macos/ios" + shared_preferences_web: + :path: ".symlinks/plugins/shared_preferences_web/ios" + +SPEC CHECKSUMS: + Flutter: 0e3d915762c693b495b44d77113d4970485de6ec + flutter_voximplant: 5d2223da5d47ff2ee5f43c84a60c8fc4f5a01ffa + permission_handler: d4838243e7d0f4b18911a6422d81e7e6b71ad545 + shared_preferences: 430726339841afefe5142b9c1f50cb6bd7793e01 + shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 + shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 + VoxImplantSDK: c53bd6ed2634a43a33ae0d517cc90c7ae4b0bed4 + VoxImplantWebRTC: a4bd73d41b9f8f3a60de032337b661bab8ead6f9 + +PODFILE CHECKSUM: 3dbe063e9c90a5d7c9e4e76e70a821b9e2c1d271 + +COCOAPODS: 1.8.3 diff --git a/video_call/ios/Runner.xcodeproj/project.pbxproj b/video_call/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5294a25 --- /dev/null +++ b/video_call/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,525 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + 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 */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 821ABEDD885EAAF31B41C12B /* Pods */ = { + isa = PBXGroup; + children = ( + ); + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 821ABEDD885EAAF31B41C12B /* Pods */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* 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 = 1020; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = W9BHJBL635; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + 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; + 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\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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 = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m 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 = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + 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 = 8.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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = W9BHJBL635; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.voximplant.flutter.videocall; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = W9BHJBL635; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.voximplant.flutter.videocall; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = W9BHJBL635; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.voximplant.flutter.videocall; + PRODUCT_NAME = "$(TARGET_NAME)"; + 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 */; +} diff --git a/video_call/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/video_call/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/video_call/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/video_call/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/video_call/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..a28140c --- /dev/null +++ b/video_call/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/video_call/ios/Runner.xcworkspace/contents.xcworkspacedata b/video_call/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/video_call/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/video_call/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/video_call/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/video_call/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/video_call/ios/Runner/AppDelegate.h b/video_call/ios/Runner/AppDelegate.h new file mode 100644 index 0000000..36e21bb --- /dev/null +++ b/video_call/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/video_call/ios/Runner/AppDelegate.m b/video_call/ios/Runner/AppDelegate.m new file mode 100644 index 0000000..70e8393 --- /dev/null +++ b/video_call/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#import "AppDelegate.h" +#import "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1851bdf --- /dev/null +++ b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom": "iphone", + "filename" : "voximplant-20@2x.png", + "scale": "2x" + }, + { + "size" : "20x20", + "idiom": "iphone", + "filename" : "voximplant-20@3x.png", + "scale": "3x" + }, + { + "size" : "20x20", + "idiom": "ipad", + "filename" : "voximplant-20.png", + "scale": "1x" + }, + { + "size" : "20x20", + "idiom": "ipad", + "filename" : "voximplant-20@2x.png", + "scale": "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "voximplant-29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "voximplant-29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "voximplant-40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "voximplant-40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "voximplant-60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "voximplant-60@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "voximplant-29.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "voximplant-29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "voximplant-40.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "voximplant-40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "voximplant-76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "voximplant-76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "voximplant-83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "voximplant-1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-1024.png b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..a21852eb2eca9c3540f7bf8af841d34740b8caba GIT binary patch literal 84323 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

FA00iVtE1CM3YkPqe*HUT3gd?XtX_ry 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

C^R4t1H9paQ&i0A4vjY?{K8~)NSOKJ>i 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 literal 0 HcmV?d00001 diff --git a/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-20@2x.png b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..76e874c8f1c2afdbed5f19027e9d95378cbbcfdb GIT binary patch literal 3053 zcmVHg1+lHrgWSWcKdPn90sKGrRqvPeo9CG3uKX#J{(IASm?@+di}}l?o-=)F3E6 zwD^Ni=!>T7nL9I?X}YoAW$t|Qo$sD|?zw001?ah|SeB6#0T!CBEf+H4bBB+JJu8re zhoBb*p;u8ID_yBf0ya+zcePvJL&AGs+11_tpRKn>9TgyPA7ZoSs0)aX0r00)%XR^J z`jH<$>RKN5V(7OqK*TS4xZz{h!*f1C3ECFkK$#7nA@pGN!$;%jYv zwjAKwmYb0gKL(K8-kPtb5${A?tlI~wzMrJ6wTdBr=Y%%%EaEMQ&o}4FQ^DA)s*}Z> z!FI&AHCpoWI|RUqx?7s@$8!5^Q=anY%X@i5{QA6kNcMelpE>R6eCYFpmMsVT zrI(b06~u#xf1yS}_UGdMvD``!0~u->P=lA4?YN`hilQ z|3tHka)7T{2CGqwjZfMwx$5irQN_*|e4l)UHmiYuz74Yp1t^#>hrJ3-SOXDcC_o0^ z7T9R1gAN8V6s;5)ieI5-7aQlmJn}lUna#nz!j%5V$X|o`xX!dHWQRV27P1=rj;t2b zW$~+pTw@bIek?ZvKPDL<64`^#UNTAck#RBsB6*5DP4<%UA_FqU$I>2EH_cM;u)Q~SI+rg`Rn{L z_AC5qq~L$#SMj%U$6Cz0vP{G5Y*=%5RT^yu;}-DInZ=349rJPVM6C3K^oO)8y(fJr{l>k`ead~!ea?NsT>_Ci%bnxC;Vy6= zb6>{xYV#Ue-+LB$7`JEXmTRm^AtP)R9u{)KHsMiWGV&)32xCG~*nyU<>-!d;FP=Re z4r3qYr~6#KE>;1F`>_J_P5xC?ROxV(DIHdCO*p$HRQI@7^PwV@Pvuf+ z5K}u-6REM(K@W$srgorh0{i?O)v0c>QtHxU-hBdD(>iYJ4b2sIOVX2K8m~4gmYVA5 zh^QEb$V`rCQ-|7ZS{nuL-t>?3n=-o(6I(7vocj#GzCZEo`!3>+v;dYIfPu#&ZWzzX z2i^rZ^Mu;6+rb@?NPG+6)c5T6zxpzGe*M(x+{AON=PiJ>H#?ob-|uwRK0yDg0B4PV z0id6JRRdfL?*IS*IAvH#W=%~1DgXcg2mk?xX#fNO00031000^Q000000-yo_1ONa4 z0RR91D4+uX1ONa40RR91C;$Ke09h_XmH+?;OG!jQR9Fe^SZQojRTTba>9mEe(_y+& zN=pk}*aa0(2_PauumP$-#0EqKD^VaM;KCB3M2#3V5(ox_fE$WvN(9+{5D1kDbfYb$ zErk}k@7r`1&$+`4Gt>8`4MQS7yyTVp-o59Z@7{CHcg`I}a`f{SJc3QBP{C|5ZBjmh z*qk8!576m29^gg&05ZKqj7Aeo^r+NIsMQZ;NxKe@S7UG^l46lODjp?8H<5F>kbtV} z3Owz21hA*ah$&OYW5>?-5D@5xuFh_3T>CjPkDP{=#>-P|Lf)ewu~;lfTQXaKzf6Jj*c$u|MmzJ4v5TV3(1*;d{_bh9#2TvyY8=H@m8hXkUN0P=~lZ}J|zy)_8d`XMw-hv=aZNEk5` zrPnKP^p{ic@{(2U1X_L;X_!815~e@*q4fJ1eFyj;Iwss{H!771A%lX& zlb90cG-i7lksJ$tWyej8aAa$JY)@9ewPL-yC!*pEWn({js5EKr2?WA1IA5E7StgI?)@n$ zC`IM1YP_ED5>nG<5=eQ!Wz!mZdY~k5!zlWr28SUprx;C*Ewa{<1gP=$Lgvx4&{4!@ zXXWGci3@^YpPfAgpM1F<0|xrqG2X7YD>!h)TWNw$>;n>=vEvi5dfig^`47Z`MYG7q z{RJguEZ;)ZMZPH!JSu%){ASm+6l8<8)^?mZc@bqLw?uAbe=I5}!}y6Q#CuV8k*o_> zMHQ32Vt$`Fn92Ex$zw2XLNa`Oyu}(EjLfT9=X0QTAaC|l3oK_PebBC*I_x2K`XJw7 z@Q%%!6mg2{A=5o*6Yk`^tbHj-fJ`$wy%rm{ti%iRriv`UPCYku8YWH}Wf$g7WK<|> zDcv2AD9wQ5Nh>c%7e-+1mI}43Wd8UxM)p4Y)dUpxdY*;3A z6y%jq^cgU6OhT^|Reh%pFV0+v)|Ph4JQ3J)@FPS->0Pmj_oIhTV)crxRF?TrkVKOY z29Vp73Ja)QxUtV$ontajN*P9elhg|wYh`Mgw_pa^+d8a81r-Bwjf)G7MkCfKCEw1@ z$^%z8uHYQyC8L=Aj8CS&ZPhzVP<6Wo7tUQqdwYkh7;i@HWhH+Oy8h$=Nq|a9=9Q$d zzm3cNFLu2zsv9o5fD$aI74wz_Ik)SJ84YP#O#BuL<5z#t1)D# zwHReCY-((!in>wyMe+G&QwioT^Zoi@isshV7c3*Vq%s;(pTBL7~?FQqG~8X0R| z!P3`K;U6%N)yXuoT9OBCv-!egBr_=JA18Y24)5=h?;ej&8jaltwuvhz`|Pqs8*qh+ z3tQUajq<}K9G|e6{BP}s<$`Bzdd}2akXdWSGg<}a=xKf10O0=DEmp!&=j~(VE>7k) z6WG>RoIY28<99A17A>7aAnun?>@Fh@nH|E>K@mHM%8;ecoGy#)>oWO}W zl0Imc?xUk5wZKv$w9|(FyYJ zFDH(j6P(F+-opGF$j>d2Oo>)?bXWG(h;EFp0&hkup(Br5pGy@ynKw1e;^=>3o<{(A z1-|d*UMZ%)xF+gB+x=Ip?)ryJs8U)}otA!EN{>`xUA7t7f8Rn{QU_v2Cb~+<(@d|K zZay$5x4_)UemIKK>hVHs-jN3#fliyA=yZx6pP(Dv{Td3O$k@Af8cJRs2X76XE<2$^ vu>9u$c^5u(2TF;RzHE6E#r--W4=4Q#EX>Oel`W7D00000NkvXXu0mjf;76Hg1+lHrgWSWcKdPn90sKGrRqvPeo9CG3uKX#J{(IASm?@+di}}l?o-=)F3E6 zwD^Ni=!>T7nL9I?X}YoAW$t|Qo$sD|?zw001?ah|SeB6#0T!CBEf+H4bBB+JJu8re zhoBb*p;u8ID_yBf0ya+zcePvJL&AGs+11_tpRKn>9TgyPA7ZoSs0)aX0r00)%XR^J z`jH<$>RKN5V(7OqK*TS4xZz{h!*f1C3ECFkK$#7nA@pGN!$;%jYv zwjAKwmYb0gKL(K8-kPtb5${A?tlI~wzMrJ6wTdBr=Y%%%EaEMQ&o}4FQ^DA)s*}Z> z!FI&AHCpoWI|RUqx?7s@$8!5^Q=anY%X@i5{QA6kNcMelpE>R6eCYFpmMsVT zrI(b06~u#xf1yS}_UGdMvD``!0~u->P=lA4?YN`hilQ z|3tHka)7T{2CGqwjZfMwx$5irQN_*|e4l)UHmiYuz74Yp1t^#>hrJ3-SOXDcC_o0^ z7T9R1gAN8V6s;5)ieI5-7aQlmJn}lUna#nz!j%5V$X|o`xX!dHWQRV27P1=rj;t2b zW$~+pTw@bIek?ZvKPDL<64`^#UNTAck#RBsB6*5DP4<%UA_FqU$I>2EH_cM;u)Q~SI+rg`Rn{L z_AC5qq~L$#SMj%U$6Cz0vP{G5Y*=%5RT^yu;}-DInZ=349rJPVM6C3K^oO)8y(fJr{l>k`ead~!ea?NsT>_Ci%bnxC;Vy6= zb6>{xYV#Ue-+LB$7`JEXmTRm^AtP)R9u{)KHsMiWGV&)32xCG~*nyU<>-!d;FP=Re z4r3qYr~6#KE>;1F`>_J_P5xC?ROxV(DIHdCO*p$HRQI@7^PwV@Pvuf+ z5K}u-6REM(K@W$srgorh0{i?O)v0c>QtHxU-hBdD(>iYJ4b2sIOVX2K8m~4gmYVA5 zh^QEb$V`rCQ-|7ZS{nuL-t>?3n=-o(6I(7vocj#GzCZEo`!3>+v;dYIfPu#&ZWzzX z2i^rZ^Mu;6+rb@?NPG+6)c5T6zxpzGe*M(x+{AON=PiJ>H#?ob-|uwRK0yDg0B4PV z0id6JRRdfL?*IS*IAvH#W=%~1DgXcg2mk?xX#fNO00031000^Q000000-yo_1ONa4 z0RR91JfH&r1ONa40RR91JOBUy0H_zsW&i*S0ZBwbRA>e5S_^bk)fL?{`Tu|9N5~J7 zMS(&EjD;dvR1}JUODG=&mxYC(AX21D&;pj0->Ow>SGA=|TdI^oDYV8@pqK;l&pgz7CD*0_ldcu)hm@A6?k(c679N!aqQ^2D<|e`2+?9 z_-M4=yY)F>Tc-`tv5|Q2;VBq#%Mdg-wjg)!A?$nmJ^13xO}RD`>-%Qn#18hr$pS2j!s-`ZA06|cDe3U+stLXcHOXAttcz0 zz_wTSx-_Y)ZNRU#?CupT$Fs@$?vOZe@nW0$@Se9~I!aUdm1`HOK$CZ}2nBg(aHgmX z73Ec^uWv$ITe|{pwOGVWt*}}x;Gaz<t3|VWLsp6D-~0KIn#Yp5-@%C1cZbJTb`lX3sdyOn2zgajKhufkI$sJ+l2o@06yy6B@_n6_~LtklaC*E-Sr z4i!%@5>BA|B=+=7(diQ94MD+yJvA|P-}H15@U;|L`11%_rU27*Gy3+70ORaxtGz+%6~fF(lHx{S70DmB%0 z*!1kr6^RH63RJ;w@X##N-PKgpqOqaLqoCPS=Y}qA6Ee_GHh=f6rKb+{?vqB6Q~Ue- zqrI&I0RaKyrG)d@0c?DD0a7)nAyISuq66$XHoX zJNIMAuq?d!hlBX-uiq5bQ?Im*iiyB8>mI|jS@-B_PwL5JAwDq{Gv`jyZDVwE_|1bc z=UY>7=r6}`+Z{Pruz03oetfREsTG^oZNcw;lWPjJ#mw0ftwZ+-6qeH>0|ba0X?r4T zR^bxRcICc=4B^1;a^iSCW=whs$(@bwIEEA2zMckoiS-CPURQ(=-wWk zEfE~oAX7C~8#S;Tn3>ImnmQai`X6^a)HNrBWt?E)%ib34^uTfu@`N0znUT92iD8sB z>fqAvG9ecIuDB#PDYT9mh0Kk2c`K3=$wm!DUrV>g=+3khmFKpi^46|494I~^245ZX z6}P7@T}DQQBTRBz76K~Hy9Phq2YR{LDz2+1j1fl z(mQbrIVbTAMPHW zh+%6gSmDOBJQ;v(X@NEC7b8=0Y8LRg{_{R9GTlw0Fe`6MJKA7|F3o`|B`}cEF?e06 zWDZEh)*YL$Yx_Hr`7~qd^t()V#U&LGc;#a|4`kR2%dORtp4HbidYuz9xGi5b&v|@P z|C5%6g@vNIxy7rjje{Axv=9nz3$*gJl2|D~#7J~^-v6&u7el~|7CdPmXeX#PuIeV1xnP{j)53!$ocg?ZF~#C3bAY+&7fK=AS-7=SOJS{4s)K%OI!Trf|iQc1$9HomX| zBjt4mO`7DjhgIKxPE|s9kHvV>)kHbL;F)oH{}d?;rywo8ubMDUMpkyZVrpzp_Ln^{ z1G6N*9)0U@#n^ZRL{j1olrgYVsS&w3W{8-`4i0L5}<<%$`?oP`wmaww2{zuEDt!o{tM&|rT ztsOSj;H0nH<17epre|GBnF?BLOVB*mq5B02rK6ko=01Fe0VHSiFx-3JI9_&3T%Q=s zfApJ%QJ4L5QdPZ5{-+zSdUnxeV5=ngdg?P9p2@dkQ=tSf0qw5?mI{~#+^ww#|By4^ zCyYw(ovaD>j+Lw_K{xX14Z#4#SD&JyBV2wa*r)Ss_^82w*g#<8KtD`~=VH<+DBo94IFYJEVM?|JfN$ zPxZ}U^zsX@OZm3ZFb?nmhrAlWHvzP>sF?_hoX1)liRD zS5887xIP)WDi+pL^z*#8U~mvNJTMG{vy*YWpaMU9;|SU%FzU(wg@yGLcey8-(BkPi zm^XPiPj?j!_LnuSC)WqyE@UA=U2wE-9mM+6pwsYrxpl(<{x4oHLScGH>UjVF002ov JPDHLkV1lgsuiO9t literal 0 HcmV?d00001 diff --git a/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-29.png b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-29.png new file mode 100644 index 0000000000000000000000000000000000000000..b8336e77b42dcea78a12d56f5318f8eec1c1da34 GIT binary patch literal 2505 zcmV;)2{!hLP)Hg1+lHrgWSWcKdPn90sKGrRqvPeo9CG3uKX#J{(IASm?@+di}}l?o-=)F3E6 zwD^Ni=!>T7nL9I?X}YoAW$t|Qo$sD|?zw001?ah|SeB6#0T!CBEf+H4bBB+JJu8re zhoBb*p;u8ID_yBf0ya+zcePvJL&AGs+11_tpRKn>9TgyPA7ZoSs0)aX0r00)%XR^J z`jH<$>RKN5V(7OqK*TS4xZz{h!*f1C3ECFkK$#7nA@pGN!$;%jYv zwjAKwmYb0gKL(K8-kPtb5${A?tlI~wzMrJ6wTdBr=Y%%%EaEMQ&o}4FQ^DA)s*}Z> z!FI&AHCpoWI|RUqx?7s@$8!5^Q=anY%X@i5{QA6kNcMelpE>R6eCYFpmMsVT zrI(b06~u#xf1yS}_UGdMvD``!0~u->P=lA4?YN`hilQ z|3tHka)7T{2CGqwjZfMwx$5irQN_*|e4l)UHmiYuz74Yp1t^#>hrJ3-SOXDcC_o0^ z7T9R1gAN8V6s;5)ieI5-7aQlmJn}lUna#nz!j%5V$X|o`xX!dHWQRV27P1=rj;t2b zW$~+pTw@bIek?ZvKPDL<64`^#UNTAck#RBsB6*5DP4<%UA_FqU$I>2EH_cM;u)Q~SI+rg`Rn{L z_AC5qq~L$#SMj%U$6Cz0vP{G5Y*=%5RT^yu;}-DInZ=349rJPVM6C3K^oO)8y(fJr{l>k`ead~!ea?NsT>_Ci%bnxC;Vy6= zb6>{xYV#Ue-+LB$7`JEXmTRm^AtP)R9u{)KHsMiWGV&)32xCG~*nyU<>-!d;FP=Re z4r3qYr~6#KE>;1F`>_J_P5xC?ROxV(DIHdCO*p$HRQI@7^PwV@Pvuf+ z5K}u-6REM(K@W$srgorh0{i?O)v0c>QtHxU-hBdD(>iYJ4b2sIOVX2K8m~4gmYVA5 zh^QEb$V`rCQ-|7ZS{nuL-t>?3n=-o(6I(7vocj#GzCZEo`!3>+v;dYIfPu#&ZWzzX z2i^rZ^Mu;6+rb@?NPG+6)c5T6zxpzGe*M(x+{AON=PiJ>H#?ob-|uwRK0yDg0B4PV z0id6JRRdfL?*IS*IAvH#W=%~1DgXcg2mk?xX#fNO00031000^Q000000-yo_1ONa4 z0RR919iRgM1ONa40RR919RL6T0R6KxYXATRCrLy>R7efgR(nj9Wf=dR8yqeNINT0+ z00BFu;ia;cZnW4i&D5q=TADIi z1R)3H$W=IT=Uh17IX%w{2YJsqF!;xRQmOH;eE_#wyF_F+ zo7*rrFii6*v96Gv+dU@sOdtCAN>HW@_|PLukh9c+8;z}Kw{^j8@5ktf6YXu?xN@l$ znb~Gsx>$qWo<2lHM<6OH0trb*%+H)BKrjDVGh_Bapj^fc&#a+qtq5yqXav2t`_SFl z3x~rc0^)_D=hk6?B?HlhNTj4DAu-t~z)u|c5f`ejB0M~7JgpGFL7;4$k!hYZH5j76 zSJr~G$vJ*7#>XIk?J8-GUmELMM7e_&rc6j@%4Zi%0IBArDJJqGpWFV=zQv&f$K-{H zx7L>S8B5D%5-7JovMC-3iE$wv^5n^*=dfp21sdv_gKU_5ogL$BW@2#?p@sy?MiCKu z==I@590#n8Ht-qy2M6{2sVWo}J&xj+3;olRcdo)Xqk(KXjz}U{s9u)Nl>5(m!-n$G zgZQ(i0rhoOL6~>nd!2eyjgeso9HTCLT(J}8G}9!Q|A9&M_O8t$=-kIvp!RwLO175M zzEROyemf~s?m36UiLdq_#q~ex1pUvQxrm{`VPVf%>vUQ~QZ+&i-e0gGA8Ve>6-*_4iuUrOwL^#$L=D`pXEikxT9*+mVR9z8S2LiM6lgG~E zLe*7pt5u!<4b~=`sM1thsk{magJn@BcE7(3PNxgqU3R2rq)f6gEKG;{S1d-!mU3)+ zrx@EyUzzF)b`pyZ%f7_us1x(3{5{=vxLjkjUnSW|nR0oUflLU_m=z{aS6|$^5lfa^ z&|+ literal 0 HcmV?d00001 diff --git a/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-29@2x.png b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ce883db7dc1f08c5a04fd05932c95d33936f0733 GIT binary patch literal 3885 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 UUo~W}od5s;07*qoM6N<$f)m+wc>n+a literal 0 HcmV?d00001 diff --git a/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-40@3x.png b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..2e0ea1bb19e6c904a96b9919cf3c71ec9138ab3f GIT binary patch literal 7071 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 literal 0 HcmV?d00001 diff --git a/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-60@2x.png b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2e0ea1bb19e6c904a96b9919cf3c71ec9138ab3f GIT binary patch literal 7071 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 literal 0 HcmV?d00001 diff --git a/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-60@3x.png b/video_call/ios/Runner/Assets.xcassets/AppIcon.appiconset/voximplant-60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..7e64d7f865c5843929fd203be967a79a5cb18041 GIT binary patch literal 10480 zcmdUVRZtvEu=OtPE@9E&?g4@acXxLS7Tj5ayGsb}8f*!{-3jjQvJl+$^1b~3^L@Mz zJ=4|GGgC7)HPz>IN2(}EqoaUO0002Gtc--(dk^_fkPzNmp}z>600113t+=?#S8-`^ zCwnIsb!Ss^OKD3-OBY*nHEA&bfG;*y)6j-Q6HmC+)tZWWT-}~K)U8Yeod!Kwi#s3E z61cX;B*VzQ7pufRf5r(j(qR=eQQqT)S z?t@hhqf3r|2yp$dZK+$gJoUTEKFjevZMHsxKWwhhNlU~75@h~jA>`b44UdlyVoC@J z&m%<0*H$HEGAvhs;Za8QY}DTn@9{NWnp=C#t!|Pc#i#g2Zq~40h8htMJTKK8^#J-j zCX$Ol^~i3`4x2bc``CQ`Y?&|gx(Wxx+FI>0Z_h-)YpUBtq+`X8_1{aOJ#o~|8|Nw7 z9akLg6`1{WU(2g=J~MsIb?CMUy>jR+o%oR}9CBuA@Wk|q=3q;;Prf24SLzvQ`>TWh zZ<5WGw4aICA_xhq>zOqr*k=+3RV#=U9l1r-jZq&14nlaYn73IXCU_4<)VmieE0X)O zx;^@uKIvUv3cz(mw&-VG47xlysOMZB>_IN&`sMnC@>B)|cAz&P!_#N5hqt3B>cC=K(2F8$ z5G>l12V)>`;#K1jMH%N?5fUGC310F;e*Eq3=t+4U8Zr)k_%jY+vJ>$puSMWjPW~+YLwv#-mv|7z_`xfh?!UQ_cl>>i}v_~@x$>m z=PlE-UD0OXuJ%Qf%b?y^YrR76iM@`irzXe&VTa&+>PLTMKk3!Ci(PF@serWM9|twp zhJw0ItQb;N>F|$s4_ZV@u@Y6+!Pnss=5{)N`j>(Bzy2fsfBnb(yA5Fy1xB-XI<{Dy z$z6>HZtbo>dKEYQ@HRZgdLqjqbQ(X*7t3G}r$YskB zBE>K#-!FYK=wQ_XMn2WSTr0k6YHA!gr!bIeIVtjWe8G*O7Pp8=;nBGJqkWZ6nX0^} zW{agRppIK!H~R%MyrIM+&jIG?nRKq)v0e>2ZNBagqdUXzc#QrR-&1}%*$h;}!;Db9 zlS0G+0BR*!i7y&nz<-9wewzJrBDzarIAStL@;x8|-Bo}p9==4Mf4LcUv`V!6T-xK( zLd-qOnDo$S&n6ho?SsNsd;5Zr(={9Db;G?YZ7hjU zikc6ts=WaksikN-p629!P1BV0Sxqs^Pfr~495ZwC9ivpq>X7!@WX7!0Y zfwyBRkPwf+VgKL1EY}w!Y)8uRZ3>9DgleTq7hgt4leb(&X)~vW1i;OW#i@?%$EDY+ zqnKfET#lIdyW33T#l@rK`H{&=`2&TDpj^i2uX|vKOWE#+>%9k017%c#@wqDD>!Wlj z<(CIxeuo}*2@QuDf*0cz+BS-F#(8$)yT; ziG^Vy^yR15np~x-Qn}m=#dCG?t_;YBSj^E;aRs(qw4wCHuWmIEyiDhPowR8dC|eSZ zrmH9nKT>6$qnomVi9mz!w66CoLuvf3q~wn@{jKnv4V=j@eXdBL0vQSDqs)aWCWKeJQ77}Fo8szk^u$_t?t;$P%!MKm>Z7zu14 z#tbz`{XpbH3X<;!tNF|P%XOdVWElRHcDz`%o)66g6t_|0{dZnxB;4Nkw?o*}?6&CTb{^Wl(r-fe( zOV}-+=$R+O_ln3$Ga=CfM7F_S?cK%tm8&e&!fY=RW4LlRvtg{u;9sD5E|5ftGs)OY zxWN#|^J}F?mEO3lZF|rxL#N~XnwXLswM0~Q;9D0DSgLf#{Hqyr#{(2`wkPgY&&F6u zxccGxD?@f8JIh%8@ApWCXU|lKhewOAilKi(EKb$% zyhq~dOa*>16T|PNWz!+gTgg;1qn>)y=nK;qNAc3v*O#mawb|D_V9hSm*5eFRD{HHY zl8a*Emfq5t$(&Sf#G3?Mm2oUxA98gTk7o-+F2{ZNlwoBctot0B0=o6j4>Z4{`M3qtVmXFLQcZpG~G}Yn)6tQGhO2 zqsH^GgtdnNShLD0zOCHD?xAzUA|o5ZJ3nC#<$V-yusJ*ja%UXR#IGc#WOcz5MiH!D zvirB%wla-Hron(n{cgQ?;)0h5sSS0KEYMGwgb%Vrl(G=OUn}g&%gVAYb-tgiBrE&6 zUY1eR=*V0xXZH3`P7RQrpkEJB^KZlfm!uZf*n_nnw*4wW*Iq-l%>04N5}!#@xGCg_TRSid#<_HAZum=?pzd9Ih(72YO^8C zKWam47=q8|+hW^d%iDW>Ww4Pejr!V&uyCS%qrx^affqr2|59_rB4v^7D&5-*@KKSP z5-f2*NeKK`qNi9wNZHxrNl3ZL%H-dk(^#r}7c|Imrk^N$n}M65@WpWPO*mK+-`Fh_hQC9a~zT{In~IZ?;Du!cj%?fLE9g364BWSFo_ zRZ=kOWbt=;lsBvMt_-Y1J%B?rH)lOrZN^8%C0^pfZwxhtS|=lbb4MvB;tZFqCUJuE za$T-~Xq1}UYAwOf2S$>qmjXTCb2~VHg;^{I!|y~i^~6|h1osTgm_W){o{urm@%n}F z`<4fmvK})>JAC;<;BtA-^RzirM%tGz+G+apC^m8I*0S|!uupgRA^&pC9R9wDtZ|AC zUQuJ<=p{9hEDqkjm|v-VWh$7NVF7Y8ldSO(tG-pO^M4Xwr!~Mh+0Y-_mk-t|=&9C# zThN8E(c!B-iHfH_<^va>J&D;!7syVYw$t#%LLW+CL1Y%^Y4ZQ}98nRMBg=?e)x`a& z1Z+~9?Zl9bex8oz^U-t%E;xiJhRz3GkosRv`795QOS4CJH`_kW3H2*L|~g!q;mr1?>buA zUh!~rBmq%TCt$(^QP%SE8vX@3*$>A2sq$=rL07mi0Y5&T!1ipimbcIOdLb@-gy4OE zW~<6;keRAe>#TH*PX?+DhST>@*u)tnI=CI-Kj#c}(_s-;DtN@WOw?{=E>>CL^T9*j zeHtyX3J%x>8Wh>dzB;%r#nuNxZ@a{hmv9oXmNgY>`?C{6zDe3>S@aupO7id(`^iJZ zWZ)VtZHQ95+S20-nUDF>6L5y@9)=_>oBNho;oyUu0M<4whiq&T4uAcrsG$2kz?#il ze7WO%mRLi3fnu7xY)b|;UO|^R`=6O_&8EGqvz*vEPE%qz4v7EfO!i~vMq9ElVI-k= zB?v_)!JNwXUUYBr(&>Z(Y~wU~nM^bUoB_l}$_TDlBx?5zU*G;DSBI?u*s1=k_2Tf` zrC8x^Ez28omj&VPXCl~8=K}J4i>MhVJXSr?^?5p;{TfQp1M>U^HbBpg>_-gsO)#c_6>Cv@zH;@jmd69{g<-LOHb9yXA70f zpDCp{pRsXtBw#BMF`_~wV+O6^v_up;6;;D$lq!it-=QtAxu4E%5*nxIMNJ`rz?sX>%rgYHRA9Rq@S-vrM zatBAdg5E~yli8+<YZ0X{!x(=5#GFEUe!cUjMaY!uk+p0T*DJdP*$bM)G#(#!T z$P>)j;O_Ii2oO4^+qg<1F?8VLE|t_Cyd}BAXfgZ6E?u8?EK5L#abp7i+3{L5-RYBhxW|_ySU+hNv zVbD}dgv(k#v>p|k3egFKn20*)&H$=4Z1A19{D$!l7{b4FF8q28t5w~jT_>+iyAo(> z@ch6JGYubeJkDULOzMgAH^&n`Tfkjx(pS<4=Z9FGMa*?e&g@X(ID{xU1h(_w%;VL! zN0%;|`fyG&{QIL76_{XjM}{Zx?+xM9J=b8w>THgK_>VK*vjXk6Th=H4z>oV_uTmTn zUt^vHXjyCzDXGXey`A_jD3Bj&v4g)`J%vaFIB(5d&r-=th6MmVy!Q7D>O5GPbo0VB zFC{oN-{MpL)F0KIX&O>%E~n?9DiQb(~@`>znjZt{f4^67}zbNfdDh z9%Sp|`@T8?vaFJv^R!QQTe8+NmwJeyYPqmT#L| z-{p)$^wL zQzT`GT&%XI*n_KEtBRtGnViJ*AL|?D7~M(Me!Xepsg$nDv~H_8+v{`9wstvg4dUs$bAtp8@JGkNH0d7_=sL>J>2@HBgvE& z$b4-o6TZlYp^HM9DE{q3dB3oiCwjK`c)1&k(`g}{X*_|kb&i&iAkpDDnu>afGPPe< zU^}hb&iDsKSEmQ$m!rha@>`kN${GcIhU@BD6~Yf~I(~qNi+=)Jm+ex2zuDV!nzb&gU6bvl z(tE=Q&U&9;aNKTg_Cv@A6jaFf7}l3|7TG6mPRs$ObR35VR*6i&*kNJ=p*qfT!pMG@ z+<@+|48_nMYjGh746@9mFl-|>mYi;u8;Q7smRaz|Nr4y|4QHrT;y(H+&mz@3 z+S)LnFXc;A2+)zCz9L6DwCu_JL^b($x0B@#W7j{KZvy3SbE)94Bge~>3utp*0ri;c zItn6f2nQrLIgD87K|@tYpWxvnxkjlLjmS`S0SNjPS2$oX6T&qJ9chJJYZzB%v&;V5 z^M9??j-+;aU$@RULurnB`=W!ho=P4V+mCWTMagkLRTztXb{Dk7ZQtAU3N1DBASL?R zRud*ol(sK~j5`6X(9?UlK$yrSec)ANIh6cRmlJS;&p&qL^LI8^HBi0%A6{6Hx6QRz zTEV&bY4%jK9G~&Uh^I(lwZ2DmK8a(j9x@xESYEAIF)wh^u*L1v*~7XaPfW$>_2NL}0u1)LH1t554-qf=W|sR%IjL$c^-=D~sc3Hv;-L?fSMm+ieWmA0e)C zDR~qxqy%sgP`y5N>mPQ6JC@E2#BWnG!!D`@QX6{QXlxPJr4vdrj#Ns1{^Z1`Af9l^ z<lZ{q^tZ(D+0@XVkX_jVM!6$cNU}ad29sQ!$<`K-PW3Hb4}NiWm4E zw8Td2_>$ejuMI7o01=eG!-`~$SR3&CNTwK=>B#Z}QXokHR&ZBU*x(YpFW?gAJYPI8 zSakTb;ecN2>NTC%Mv&VEMK>@ko}cjti;zdtQC1@hTkHwtJwXo-qc0MEyQC)#&ub;5 zX0zQk5sy6%gnnxS%}>I9Z?2~16T7?DktB!2QS9;e8M!{mra!qK+81`I1~}|vGL8tjZ!Cm#T@<|tMQJ- z6bV*k;g*=DY%g7KR}&W?L@J;;&jW3Iyr{1aE)i8Ad#*gOFnn@PTY1W`=B_$;d518a zxwJnz=Kzi`$n!E(E<$q>vM%(w?L-0Fif6m1o4FCU`OK{EJ=PfT|LjefbP$Z6tNKl~ z*`{IH=TKMaBAf?*l7%GjcFdU2cK%yFv3UeDGd=c}(BgJJCZatC$+B@DK6E(4mvxX~vq z{4*AAX+bdQ6zS_JdgBlw{o%7goWDd$%UsA-vP_DT?z5c%nAB!JyWYccHt zJ@VvpO`Z6Y0xUP0VN~-t20CUFhW6_&%*RBE;#nLpU^JE#$&Oq~zA4ETJRpJbnIx-2 z_i=GXYO=^xd103)N><}FC|K+a0+OlyxdZRY^kbeAO_3$*5UVm+iS{stcOxL1mH{2` z5gmqBRSP$(Dy!-?bUW7;EF}pd8q>*k;m_uIrEa-gwl!-uQq(`kArUqhw4IEa!{ddZ z*^eM+A!|+)JBl+^UF^RHPBT{3APuR}3bYR|c=i<=pf%WfH~hCZBWz7jk|;N6J)F`ac2*zvB<5b*cVqGdc~R{I%@osAgq6rs$=B19ckjZj^jO43*>%DYB<7CqP7h;?Ai=m z$L@E;ldfv583xA{RE&TUxnPx89Seb3e=c&K97~K@GZf(;`gUzU8wR>F^)#YUwiqWtG{NG=cpD7IrOCZ7Y`(7f{pi; zP>3ea1(_IAz7+eo8U49C9Ip(GFmrOxR}L=+OCdsjH=^HmIh_FT;X z&FV4@TSo5mKPcLhnlz)_JhwB-03hNn>O8JeOap+@;)1id_lLF+O0V0Qj*&$NT>v#d zhj2uDr&YU`SQB?ulH5s#K#Sq(>86$FcU34E(5xai((5Ll-)*s{= zpR;$n&Q(3%%@S*rCQ6yukURRHzB>tuJ`e;mG7$Z? z*h%mfuBfVN5cn&c1_#s_mNLHNPjP}^(~gw{^Q%(k1YNT<;;QxIATg&^Pb^Nf&?n9C zIBP!1->)Gdj&Ql*sI2_atnJX}2-iPb4^H2B=9J&sgZ`cOYZwP=ECwaU@#YASmOy5W zgvxru`LiEyl?f-psZ{0cl0HTJsY|U|`o@lPhx0UshM`^$0ikamwfW z;=UAk2~i(_@Bsc~+&vZ&!kHlOiRWNYNZ!j zt8>=N76XEF4;vgf)R6dLXY*bIWAicrW8*6anoHmplpX`5O%F8hi;qO3lJV9@tLOcm zkj?qj6z?IrN z46(k)bPH?`XhNGjOt2%{u0t227p1E6u$6`1bA`F~Z;J)pUI-`X(|5)A=Jf)dWk6s8 zaHt#V+z-8sh2x2e=H?4WTZwZLXFGc>6tK}_+_v>Ow4<_v&)S5xd*;3A_LM`yB&|M=EmNMm!Xl7 zT8XX}(3`H$4g2^`(MLZ**B-*W6;`|L1FQwAN=K*uf_!a-&V^_WzofT#v z;igtE;-Qc?9>f?;`mpp}#v+suaCL+$HKWe9PUq&f=h+&lU$1sJiYH?%gOUM0ZyN3y zYvO;6_lAhRur_ZSyd4BT`%GCLL~M~Urs5*m4II|>9v%^%dE#Ys>yOevaQQ#D+uPe0 zp;~1rT4xpetB)jqmVLaIAJ6wp3nZyyS+NN)g<1T`LLD#Cn&4AhdU*KHa>Q{ny;{+3NS?k*2}6CS1j=LuXF^ z6G?!0_>x($cMvHu71H$)BEg2Nv%z$58mWDu^`#e0qSJnmH4mVRzKdz#q&;)YPvX|>h3oGbD<4dLOBkmu zaQom*0qSQ|2CxHNG~zQ?9*$wa-;{`-3|%A=oT%(qV~S40RT>5`dRrm6PHx;;;7!>Q zLQ9NI%@$K#GhdAMQ=%jPgiyETe(NijW*&0Z&`SsdS%#mOmQX$bpy7^ zRZv?zj(xTxkphE2Gh1Astys4|By0rFzry25@NU=OGL|xf@ZI3Ya(LBeWBQi{WUcnR zr!lIXdnS0>QcXvufA*|>)j#vu4A7Aowo(@CBM1{m$?#tg$2;;P8AGTb%DG9ySxzPv z4m1bCz0UhsA2Dx55S5X6}c;JlIv z_j8lVz32Q0MPIJXNBeemTv0#}uv=t>VG!FR1D>bVI}Nxx zbMsqeUcphF;v0i?E6|4PX>GELZ_8&c3e65-A8!Y0q z*Tc*)yKnBf>mqVSO*(?lDq++5*MggNb>Mfk5fK4)RaHWFyT_0ubzFlXZ06)~Aw#}f zifRIqhdNIMvQmAW!L-D9t$;7hSsou*$+|0eEIv_z+|>o_#-KAnW2H;Ruu#~p?6JR> zhU4o-GfJIHQ*x<(WF3<^a1`Qm=Wq=N4>E7RKc-VTB-JgzLXb8kL3M=bZL(~g_dGP; zxaE0`#-*5dv6ULZZSIP(f5j+Qyp>(Ss8#|j*xZ0mzkDx6iHmEaqea*!^auI5tmTxH zEgQe9!+s=hj_@Zj+AwWU1jcvFo}=QJ_g5Lowl zF<$nv{4)$FXm2kIb6C*Hp9%jG!CHl@qH-}Zw-;yWE|M?mugY-MtnvGoAOW{Q>dkUe zcUf9Yl#szuC(Iu-LTr$}<)00>Y9a5AS#dU_tKdg~@*%k6B0}l;8%73gSoaN?{-%$j zW{m@d{Ny^S?Mj=;Oa`LAV_NxSL1bm1CHo&TMcB0z0I|D2;2?>s?p^JT6~wQZkm{D~ zOTK)(kaj@5^+yDE;seKDIt`IhDf`|z9J@})HsXuWte;TeAu*!#OhMfgB~1_~P=gPv zKY6@x!?7r8LTjdKqf`286CQmj+Cv(cC!~73xtt6v_0@@pK=CflRHY$e01gX^(6w6o z4fa!&q4>8GTy@=?5+lfT0w8yM+D{aw)JI5Lhq48$D_x687d?y&N#@&+%qH7u*Y<)wi=2#iQn zSMwQ^M%d>+~I>CTb?%ZCz^JTmuZo043`+3N}Nr)Z>%SKuO@af zB*(wfrP%GE>5F|>s}n2zRr=$uW)lB>Uy)1QcX}U@V2ngL+DRxklW0~tjz?W6FwS|h z?$VQMkSi^PtYGw1SLtoJ_Dmw#_`^*iQ>ZDsqESH(Y-fif$<5(|6Kr6cZoFAjjsV05x2eJ@w2-f8!%|KB=oz5ydGPgVX=_6q!0VI(W5B=JkkHg1+lHrgWSWcKdPn90sKGrRqvPeo9CG3uKX#J{(IASm?@+di}}l?o-=)F3E6 zwD^Ni=!>T7nL9I?X}YoAW$t|Qo$sD|?zw001?ah|SeB6#0T!CBEf+H4bBB+JJu8re zhoBb*p;u8ID_yBf0ya+zcePvJL&AGs+11_tpRKn>9TgyPA7ZoSs0)aX0r00)%XR^J z`jH<$>RKN5V(7OqK*TS4xZz{h!*f1C3ECFkK$#7nA@pGN!$;%jYv zwjAKwmYb0gKL(K8-kPtb5${A?tlI~wzMrJ6wTdBr=Y%%%EaEMQ&o}4FQ^DA)s*}Z> z!FI&AHCpoWI|RUqx?7s@$8!5^Q=anY%X@i5{QA6kNcMelpE>R6eCYFpmMsVT zrI(b06~u#xf1yS}_UGdMvD``!0~u->P=lA4?YN`hilQ z|3tHka)7T{2CGqwjZfMwx$5irQN_*|e4l)UHmiYuz74Yp1t^#>hrJ3-SOXDcC_o0^ z7T9R1gAN8V6s;5)ieI5-7aQlmJn}lUna#nz!j%5V$X|o`xX!dHWQRV27P1=rj;t2b zW$~+pTw@bIek?ZvKPDL<64`^#UNTAck#RBsB6*5DP4<%UA_FqU$I>2EH_cM;u)Q~SI+rg`Rn{L z_AC5qq~L$#SMj%U$6Cz0vP{G5Y*=%5RT^yu;}-DInZ=349rJPVM6C3K^oO)8y(fJr{l>k`ead~!ea?NsT>_Ci%bnxC;Vy6= zb6>{xYV#Ue-+LB$7`JEXmTRm^AtP)R9u{)KHsMiWGV&)32xCG~*nyU<>-!d;FP=Re z4r3qYr~6#KE>;1F`>_J_P5xC?ROxV(DIHdCO*p$HRQI@7^PwV@Pvuf+ z5K}u-6REM(K@W$srgorh0{i?O)v0c>QtHxU-hBdD(>iYJ4b2sIOVX2K8m~4gmYVA5 zh^QEb$V`rCQ-|7ZS{nuL-t>?3n=-o(6I(7vocj#GzCZEo`!3>+v;dYIfPu#&ZWzzX z2i^rZ^Mu;6+rb@?NPG+6)c5T6zxpzGe*M(x+{AON=PiJ>H#?ob-|uwRK0yDg0B4PV z0id6JRRdfL?*IS*IAvH#W=%~1DgXcg2mk?xX#fNO00031000^Q000000-yo_1ONa4 z0RR91OrQe*1ONa40RR91OaK4?05x&t+5i9!Hc3Q5RCodHTM2MflR&(S2n*5v!zc2zd?ac%ReqY8p$b%7(XEulSPY8 zoi-8FrkPpkND<8&5fP^Pds&|S&)&jO0N8*YQB_liRzen>hz)81en^esj(Fe zN1IT8v{9{|xcC^Heg0`kO-mkXYdbNSO!)nycVgb9XQQm73haAaS`yMTQZQ(a#3Ldy z+}7OXZ&^vD@=aad9KoNuSC~asMvklut;E46CC95HXZj?qk13GOxnMSU=q0XTu5gn8 z?QhcEBW2RmoQeMC!>|1vZ|_8Hb-iq3|H>~isS7a9Tx4VfCQX^(*8%#wGj984F;|R6 zMu9{t5*uq zY#pY77KW+O);|2=5LmWn@@Hh*PIdkE_Vl4aTr1jcfgoMIMnr^T;-n0}^0DK!Pf+-M ziG$x5Cazab-ejNN)7EzUCk?4Q>PnqhQ>Cz(Z8I^~V+v<%K&G$9SFa{y$O#4$dR8<~9c}cYbY(T&|_4Itqn3ap{ z+)3g{r)VC8eM6?~EEe-HlVUKsGNAm@(6A7nx2$HsIAe?=w6z{rNeX)=56G7KVgDhC zOqgWQd751(`iY&LU21Tr&d$e{?duUEQHPOGLQ=eJ?=Yn}D05YqN0e1={uG=vGY4h~ z`|RDlA4erK6&9}F@X!I6K{Qt{w*B=TtX_XNLPXBcUwi)PSMcfIcFVwJ8^}mw;-ax= z$pYN_;8F*<c_H;s*o&^iG5!cqM^PC;o)IJ%=Gv6<4@0S zSJ!txaEtT%9IhF`kjY1ULaf?~4mW+gpmzM-n&m1I(k(k;&b(iO-ibYBNNDKsXC6Sa zynoNXzR?v1*990~O6Pmu*9TPaj)6pKPJ1%QHsDNdf9XA3zj(e1$=KhwKkw@5R;2-P zaWM)s`+FlfXF%~%Sy7&dlfUeah4}K{-+5{_?4D*VY5ydF;;M3I>+pXD6B&v1MAW&+SWD_Nj*)rKdhz-J{|9fm8s|q37heB2Ln#7hcl^7W*-! z#^Wq61yRB$-Q)^#5J=-Gp0L+#q0h-jeL^ zoi{%fgV?B2ZV8ETN}h4$vh+#M%-i^-X1w=~wRmCUHhlEnKP7W?P$fswBzM4Y5&Qn( zyF*y@z(#z#uSm0oWCXn_dZPK>rPlJLfd&nZjX#vp&IBw$xuRIUbik~q!d#TL>+ z9ml(H&7~_)Q!OO{f-S*ka)T>(+glq{CP+&^_HDSTZo6sKQ1*zELM27-fmK0VS;Ys- zmEEYP{>)bHq}i+>V9_yANKA~k=TDtyi9^mqFVU*MVD1^%Dp_uZzQe+d$`U_PQ?F8V zOr7baqeny*(zyGHY@jfIdQgIs1`z>VX}14u?X>=CmSM~d(mC$!^RG5rw4^|)c;bf? z2)7}(Hq&Ij5Ca6Rwz2|Av@%zltNU8tr5P~#J#>xQy;R(2eX*_GwA?H#UwNY_ihkQ) zYI~Lx`vzF57f@|jL>ciHUN#mH6RL2Zpq104Jv;sMz}qiF~-C zvO`s>&Xu3hFgltl;iB>Ku>;*D`l<{cvBtwy%#9yS@SrV6lZC|G0e#hpSs7r#U$z*` zY(uRYE>YvqP?L(BI0O7Y-iWAGKVTI6KZ^5ePpn5J5LFd*vihoo(P}B%tN{nhJR!49 zoK>17oJr0j2f#?h*4Ljz{)}n%-Ki~q`^~FVl7$1N`AS2SEb}@-+#g0Z(q+ICrM#0e zYg$g0ly7E&@p{^E{Aj`|kqHUNsMy^EsR_CLt{ZUqf;mVOv%^O+>0V*<#r8?<=#zik zgb>O06dfo-)!|xIlG!1^F^$EMvHFh%Z8SwVNZU-?Guj}lk1=&;z={gXP$_+~ipLf8 zO9X=D0Ft! z_j}*=l;ba*?fC_BaK>3P9dF1Lh4$j51-d`XA`hHAg2gS*(yVnG?{^DUO^+47Ibg=J z@6EVrzZt6zSaSh6UQ838<%XF^W2XRz2;Pyk~-GEP>Qw{09R!rPZH4M9F-cAhdB zoB<R)SfE3t@y3e%6eMB$_O{$aF-R8a=%P|8$HjV ze#6zCi4mR4pdMfIXUSbA;uj*T?1>gS(_l1seF2Q7h_e~7v)+mW$E^q#!=Kx5W4;M7 zAqL!8XjVX(WrwCk81RG${uD7S+>th;$=%Z<_@AZ-4cFzjJc3^>xIjRgDaLJx)R`6I zgPpr@Oag$ufJK&UW{*94w`PhM5cx$xPp~4yIb89L8Rax16j;EzTqAP52>ze}#=&rF z@>|Q-w|%G%3SkO)+IGHz#eNA`i1>!~6e}ZLoozy!0Aw*6uynT>KeSpgE=4{CN-|)b zcxQPr?pKzrub{{<+spaO!G+5wd+Lxh7!6`q*1i2R-p(n*T=hZFGG*IsEw$jQMwu7^ zwZ5Vi7q?bw0*mhr>I(BVaNqBX>qOMt(8_!xD&_mt_X?ZQ|M9z6)7gwnQvnLj8}6n# zcMA>Ei!Nks^Tfe~gaWOdSWcMZSKU=^EX>3dcUVgX$9o_PowCrHBcpxS(6-Pg7zz7*ag7_b<2) zzhq8wGA9o?$z&$t>lax}G-5OW0DvhkC#Ck*r~OwbNN+7+A0-t4fIws|Df!h_QdZK@ z&Jm>U^xf24*4)7yWNoS@`xyY>kBQMVup-s`AlmL?NkcoSZucp~wNwm~4l_~fQ+{Kc z|LQ8QLyA1_67_-E&FN&?$Rs~^`*XgE^j9Cwqs$Ne-7R3skJs4CqK)jyXmm?6lpjSK z?}EM_L={8Rg}BqL+v?WLPkmt7XF1-d5X&>f14#L|l=u%o{ETW=0$lH%;e%yNLS5SX=C{Z2b#I)Ks?#PsRB;K5!?4@yJ;_XOyRG z11&$;EilP+Tg|I;I{W^TYu{@X0<-^J@+Uo4H2Cbh{v$IF-TtO(zhZepuFMn4maV;S zGwH^1N@n~!F{HSawTznLcV|-imCMNGUAcu-O_5Z7`@y_0mMzxsKYaV6>b(mU<%t7X zz3%-jJi3>cLI^z(ZF(6OL!d`{^_f!ar-u$Nxf@?luE5Em&jBnrg%$a! zC^abvuRkcqJxj2LI0Nqd3w! z{(@Cm5Ec^GhpG=mkw*Cz1SI=C!k2=L=@Y$OeMv9F!$v{(t&@#RW?`a%`1Qn3v6cA$ z%r7cJ^i6Ta{8;$l#OR4A-!BIJG31iJiFf7#QhP-TE8irN*5jI;JuE2LNgE3D%{_NS zbE_3+O0Nnuw&xkYax*FEtIt=mU^R!*j4?hU8gxDl8rA6^vhb-kZxLm;X;0o8-9w+a zZkV5J3OD?Bv@cpfL%QSb^-8~w?Y_BqXcF5aZR4L$r4K|5kincUcC@i&{8C2J_iL^U zgmoO*uw*Jz5g%;swTQmNNL5}1U4=EWbTasUd>-ta@E!G?@SXJSHGqp38q419+GKO0 za4{OZv4Iimu6yHq5w=(!rr1_0P|?`ok>i8S0Uvx+I8aYga$7GP&BZarM|_vmP;ey2LJyAKA8I8v!Y#;D8|-2f{z2 z$ZLrFu;8WoeIMf_F(09+p2|Bj^P!T%rrZ*nx1 zk{HOFatoFg5=?QyDH z?DFcvme`){efs)z`kDn>|1y~8U~1FPkP9!rCvG7lZc|=SY(Wpv@8-{iry@NE;`d?s zGc3M=6ua1m-4Lf90OjO*I{ePj-0VUu0b$4nt`d0);Kgd~s3Pe4Ou3irDits=#evyqcl=xZv*V;D-1T97deJ%WuBj zfG~&T%3>YP1r6`EJl`(i>t$r~yWw7$%f&Xv33dfVFcky|>y#$3c!ksh)?%~znf%8w zoAn}>_V&wD-1IjLB}FhNcgJBfbCLAeUfmt;h42Qc_kfq0-}o654cEs5<0W9F?krA7 z_VSp3U<&ASDpOC!(y?x~FvIMbvJhBPOH1K3K%_|7k6G4!-ccOedOg1i@GbXfUwjD| zeOf2^z5PMJ1ctF{oB1>+Lu3m}Y3z7Asq{qU^GwVhD+|d?kkK(WjFf!D2Mu=QX)NOa zadFI9oQ4sg~Mnz?(ut^@H&cYpyf>stoHPJAgPxTVaoUUWt%@TpL1LQ6z1Il>b#+# z4wW{9W^`M(c6uw|nYEk!Zety^b87@p~!6p62{0|%4gQfe~CadC6Sl-L<&&P~_VivPGe zV)1?ONELl~L+qU59%BUiuZ_D=?Z6-mveH zlV>m8FB|NICkk;bP0hod4M&*_LP|Yi^fvxy|2npE=uhG!;m~gzYr{5M3%`{O00ue}9<{nDoJ39XECQY4; zMb2+mNCJPGEl9Zz@ok9@l>LzObxaE~try@oc~4XLE0D#oz`M(K+6{D3WI6VPEgBy~ z(ma|kDXZkMTCRz%PQNi=3hzNK-rtUkl!~$S+-$dY__H@KU8l%E>M_>7NSx@DeyVC? ze_*b}h>wqg&ezSSe~;&4>X>!WG8Dm3OelWei`w!~jnL>5?04sT>tAu+acQ!#Ndh?= z!5@ycVi^FYamy7d+5|>4zL7FTzmYSUc2Ik`T>nDdQ$u=4 zo}0gAttylJ;BwP{q4td2J^S_s$b_q=&^gu^zab*;=l0t(p*-&G)!3vCLzgLE@S*k) zMgjmeH_I82tXS?f)rQ5P@xef2Bn{01({keMW%XmSGuHW#u|!94)YXuY1cviDg9Vr9 zf(G?G9U-?|bd#vSK7hVJBf+qv4q9ALY?BBrMq1UNu}e`Ts43+}<_s0K-x=XLI?hj+ zAJozCr0&RLSjhNHPYoqAKqTZH#y=WM3ZM8>ZY=p!edkjp{CpQxf1ay2Yh~!r@#$RE z+xh`&hg1t&l5JPriJ&R>c`=QIYPMBY~Dk&xmvLwB=pR~^Q$By@C`Xigy{)ztx z=Jr`C_S*CCOqfQ7*{A*nc(IpjDDT*QZq-dkbt`Lrv0Rfet~M~#1g9o&Z%M99{O+4_ z*FM3~hG+kRGEI!fa4EObSI0j_mXFO_N%a!C7$7`jPrI9=Y+~MF5hkkQwcAGL+p<54 z*hZCESr(Wk+N*8WB@ZpLKdyCSQqj7r;V_Ue_{+4J&L#Y=`*W3i#2d4WJWHBq*(hq% zYf$$UvWV1U^brYTlF_^5Ebgr=rNsM&-6w6`O1T=Cj# z7)b#nO^XN6#ZrIbvv70wf4lBKg!sd|-nV+=8YDCM-SzsozBA^L5t-6|-Y4On@N=sU z?blo=r#^}dbxNcUP12ODjVvUFXqoo^aBzUhu+Cvy`D_m{br$T7?2CLQgzrlso|&qW z1;J@=0Y@b?Gn1@&rNh4GT?lho&$pF~%%iH9QgB!5LL?+tsUNl9Im)M|{d!NRfvyOFSa}KdAUDG(q9TLJsW1*7WK%4fWCSWRb-kK>#6ppas5tf0qlQ|S(X}r6YFd? zUvj+XhscAO_Ar~j0b2-@_B&g?t>rfS-T6Wnhu2OKY7S@1{xE12Q`VR&*5|;Zn&H5t z_IfkEf#Vx9I`^Z&@7?$3n2;swQw-{r?yn?P#euZ%saA)({y`Lx|0OqoNbgzCpD1_x zIv^Bd?fyo2?=HMW3|QGrzqW8zmxYZaxxmP@NzQ`glr|T#TK2|Z-7ggPpWB%SiGY|n z=EtF)`?d%u2JP-idfj3Y^oIV2sP9X_hTHM z_|;(vB6q(TVrbD*+RjlUjK0RP&#$>c^nE7?w+qM*pZTmKLo8ombm=0t)g!*|^uH8B zvq{IsQ4V%WZEW&MG@62st3|^9pYDw z3xtF00x@cVzgPTOI9?7cbGTU;O>$Q7xnIuPG%_5*HapUU&0ALP?TNS={pAcueq%kf zOh1S1s9&pA%$!!cTj*I+M-LkMRSUmBA9uIvEYmequ4nmblokJx^r+XH!E>~TTWB!x z@SH*Bq%RXR$frb3dM(Gx>wat4aT^;pnRIsWJi`AH9-o}#RjUv!c3P3+L4@Y|y_Uxr z>>=N-_LTxZTsvZaiR?4>KWBWlTRpp$_OTQ5x?&>|HHnLVC~T)*{?jsOWEJ}E zVrJhv<5$c^Jb|Ckzw6WKS+?mP*8Tje*hbm2c@Y@=jA5s+f%NXbh*HQp0}NN~o|^XF}U&K;Q`z;=x4V8Y2FYW7A``D)Eb_%J`Ga`;b1F|j|X z#_>zbWrg33Gt2Vo!!K4hf6Ll=Ykj*ddSFLy%=qw&ty4}xf#b?tX)62c7g!d~H40ez zPcR;pL3p}|pd8=x_}e~8anGa9O2(*#^0lg5V&2aaAJFvHX217NW0PX~$mRKK#XV|; zd9jGt6kh<^@vhlrd0rb+O<@y*2&48*oPh=iY@zMD>!){m4f{mQs1&JsJ48L_)_tWh zzVFF2s9%)FpE%amJeQMW@28k*LKxAXwaFNB_sb>t$*f?5CzqpRZKrDPX4_u%o*U(5 z;R@7LD3yfH4>)8 zYduwNjNn-NfMWE!r+=C@Kc8$QP+aQYJ%u5k+H$YQ`yZk?`;^LER@6ZHKZb9Yt;PQ~ z=d!=7nbl|+(qj26Y#wF=Ew9TA1G3o}{S*mjo>(X9lmh_hZp~A;RBj zKi{7}56}+)zq{VmF4n~w@8nh*5>a%(;w#+c#uiSPdaNqPYTCs8E*A_KFlfJzLI|Rh zxMxI=!dh90A<-Ftq1Gd&pB zq7NEG0!JUT2hpH&b}1D@Yjmx0VTvj~mp~!Kjl90RskTz?br}2eIBfV-8YY%V()}zR zu1iNsD(AHppl|nE76Tvu)FkBH4BOj!E?bgWi_*Dw0mxBhx`Ph$gT^1v&w&l_Y-!Sw zz?y#;8`jJ1jvm_$_-kbK6h6mklZM*95Q$DnK5wkrfhbYFwT}WrLy?;sChG~6rR0DQ z7Fyf_W>~)x3B>W9MB_)Dw$p4I;^N?A<92EU{lI#;9OV5w@)s9QHm+orqyP^z@GzMt}X zvKsp7f@$pIe9%cOR2Mp3q@7jbcTxw99LxluDGESm+c#xX10&opy!GJ;jaF0*8aVL| zikEA6RizkO&x18Z)ivoVN2BCN6q&5n>FLz@dTHhXp>KUH@{+5&!Yem&jv%|PpCf#wgLrX=!|f6SOMr$R6_ygV;D zpl--C_Y%EP9As`o<7iwj+j*J(LUMVyUreaSAOQKh6^6UrI9rYlOBk+8skneMRAEcF zh^+=jkLKGAgr+D2(`OBzLLFXGtTja6(=)eT=D8CI7v@IK>Xf7g>%N> zC}+dmv+1TFF(ho$CwQHzYLb7#oWQN(|y^h2$ur0^0!QIlLpKX(Kg(=%3@Xd_U~k(JT78C)mhaBZ41!XyNr! zjqkqZms4)0zsdi<6)G)BF6b^~#-&V7_sVpch1`U#9()#+m6bEoJMCB;V-+SYXtr0Y zK}tS!iDMPgQ7cJmt!*|;^$XhhGH2JshoHCLPo?CGBOGZDJH}6J>M)d3r_T!!l6XFjEK6SFI6Q*WD~1(kF}!Uow2Ci z?mg4*6O0-b-vY_7Gi0Xm{(Y<6xUA@MU|tc;g1Edmc6B@r@hJsQP0`%N%vyBQ^QY4G z-8pXVt>`qJt+o*;Xs@F2 zW-e`H9p-kUYs56>nc^LF`dag2jo}|IDpF~)Bdb<}Y8idDy}F7)0fmg(@l0d7-Y0f= zwlQgFGa8Y}H&)CV9dRk`@%d5hp`8NvN1HmJ)_HGBh37oEGHr*Fs9wEV@yqdKE1a7D zuG!vfy4n21i4 z2O9LgnL-$O!%Q(!f(5bua-Wy*BBTnj-v_Y${?Y=Z%;43$s1o;i^Ljw_d!4N|TXf9} zFC(&JyNe};Tn2Jd9A6niG-w&^>rs!8`@G|vii(Su03lbWt`*TWg3ttk&PR8iG2Yvw zf0{JILRROXinul^=YpzL<(E%d#9bF%6+0OuY*9k6FT=kRYPV5)N*N&J79Hnp^4Q{8 z6!GicA2>4kPXAu$#4pAvEH|HOG!6P~|M?j%3-{L;KdutTtK`g~Fe~M;nf`k_sE-b* zwrs7SF}JwAlx6@D-{T`p+uhKnr$zSNUI9N}_Lax@D?9Fs*mlVL zII^a;_+N_td_QHFXPn(2^b>}}EXw^qZZI&q#iF}L%`QxyC)gKMp-|Szv`82&iNS)I zrolx;MXeAKcOcXJw`qV+K@t?Hv`GK3zq z7}FA^N*^=)e#E^;TJ;&}D#=FoA3R!$XB|0m>+l1=*OEO_XSjyWMQXo~|r4|A);Gm5p- zd>_#)_tGTS)uUs^o(;!(XDbgJLN4_JNbgHtZg&9%ME(d8t&e%K^=?(<2x)W2O^(^p zd8~VM@+$d6n_9>?u_dO2(rUab9Ll(XQP6%m%sU0!j%F~Wch|^Zm1PuZ(BUoniNw+h zm4D9{J5J|s^_0KwLV?KeaJv;GyeNoYcfyM8bi4 zS_VU}wiZ+#5qARJFMPq9$?`&As?M)AUo_;CK4$x05Ls-hHSSa(ex@MEsxAk+@|TSnJa z3_kkw@MyM6D}oT$jgZ;MTzo}PHwum$;R)Z{9h?XB`Y0cqsfXoiq!RGt!@chqDWum# z_1R3Da!v)b`jNuxV_(b1?$k4-x&tKZ77a0{zC=()7iXZ6CMKo^cU~9v`bJZUKbsr!kZNFTMzJAopf&7 zP}y?g--x$1mbQ}=+|PLEt38RA4!I!|E=yqklxfsc{7j_p?+;AUJLk|@ zbzt>~KWvRi032B0^vCfDWDf9|@k*@@Rta4~=9y0bGO1eShPD54A8q;B?asO{T0G2m zFWm+`9UqHn^~3YCdDxsEV`aeTm?8=2A!X98QP%;`G@Fw;`A|nv_J6FZ3W|EPP|D7i zd5>{oIhHv*>?++l3BUXPs6i6ioW}&`s(52Gjx5BZU#m7*gUzk2SIka8mXB&JDBv8H z@)VWp2m0@(pPU9dJv{y-HNb+tsHG|Y7ZeOwRfbXc$k@jNA$BWX%?nNXsjr!?kERwO z4WYxXlG&(#DLsosnKa*Nx@wpre89%9ZEY5H5^3vFusAD^ucUl($}LAn1g|c0t4}K6 z=nM17f$K9xgDY_EwHel7!B1DRe`F^5Tm9E1?zdqLJMFj>Gg54NBy2GWaM7+AQ%~~` zpZ>%#AR`otYeRpv2T=z^xqzX{h}y9QfJ1Y8D{;WVb0^ns+a$4phMv;r*ZEgQS`B@h zRVhg-Jd3AI9s@<^oGi{CrF+I?X4GK*FzC&td4*fZViA3}Oo~n&%kcW*_Bhs!)dzOt2i4u)^V|=3nu4_4H>n!$SFl8&T3>+wkyV}73a0LZ(5mSZJ2a2s77h? zmrw3cE8LjQ*XKs0;DiG!>?0N1W+l-&_0}{Zry&xzjh|~82L*9gLWwU4B!Vg+25@Hn zr0?VKha4q9!0L1oH{NpA8ZCyH2%M2W^VrI_L>|i14$da|E+gi%oL+P~bPwItAj+jX z=IJ0-C$g`|eezMZy~)48@RbXEZ$z3Ey!HE8b2KW3Uanam znr*3ehq^#LW@+;pZuWBZ&hmhC>{^+*b3?6tTX><7aoIun{lFAZVddx1Px2IcULo|^ zQ*15+O9oswUD{@gZT+ccS9n#1%~mu%bKwCYm$xMh!=nWWxPfu$NB~|2$h|L^r%&d# zP2st14?UA)$0OdsX_mbq7GAXH=-cM&CemA63F+1B9v8&A15}uXyoQmy<(_*;+Rt22 z{tfubSiBbshqnMUjYR)?ta2NST`Q<{=ik~J@QRG&#zfXPzwzn6Fjrpsi&XVzKxVuB4_~rd_?_and zCYduy&Y6=lN#>a+F={HZXvoCK0000@UQSBmy|4IBkPzNmcYLK&002m2Cn>4+SyEQg z*}>UW6JlmzC2Qqmug%LI`_ZHzbNoK@36UmKkTUfl$nAHgP&W^O2D=47L^n&%$yt^ zRYZVLtgBAOY*eKL%cqLs_0?cQa=_2z&+oO@!n$@DGCWEb3iFozN|fj%n9B<7aZecE z#}o?DV}0^F^TT#du_1QfZ(A0NgKi>$33k@IEZg(Z@YHD|KFXCVFc#}AXRhi_A@OqNk1q4>?j&xy78 z^Hx_i5r!5xqJb>@u%aJ`D6#*9O&fE`-=(;4!BG3e3Mt>Ekv8L4UOX--I7k}{@h`l5 zkLT7X&y!vgXzeO8edA_QGSpnGWkGL?q#0*?f;Z}Z9x-V$JYwNjZ`&ry@6?@oFnKt6 z=DK5kwlCWZ+SR>kcOBKA=xSCPJazcw=A}*Sh_HiyIh!*aGfZ~la zYb2!S%!V#gn+5-9|DZ#pk|0%k8+IGj%F<0A!0(#LVYPDv+m>xzmUB^ zm<-*5V!z_au!l_tCg!OL_Ez~-TU+Z0lFmq`BcLmt$lf1REGJxq_M*_e^*#Us>8qB*8zY72WTLk;RmWm>{|I_~) z#Lvt-1OTYO@>1ej-Y{oIh^Fbkn+s@ZX{jRAV5!8AFfoTH=U5nuctSo)4u}5r(e4YS zUXL>m$V8kzZ!r@uG!3|u&}55bnq!*-$p?qyOMt>@!)cv+S{`=Jt-Wq8&Q17jOk1Ar z-S++8paO2z`{DV2UgzvnX$4HF(8Hso)jYKKS|KPI^7zuOeGzcjP`1-#5}oZ}U`2+$ zWajYyUyB$GGu}wGRaJF$Nvvi?RcB`|F>h>9<0YiJwsuz)Pg*Km)6$X#83m=q{>ssS z4WvS$jL4ChRammCGkNqKrn}OsmppyB9*@_FRC;(+WhU{g%XV+>Z)@PBH4`&4!BfDh z3i)*!oEaC-68ES|p@{PAY{F5b0edOQ1Du*KHNbnaI^lMqrch&{M3jL^K|x*B|JtSy zo0v2OntfF!O28NH#>}Lmd6JHQdu@<3=fR&;9zFza_$}kLUhc?D?D0T3JKUh(6w>9L zy7pZ+@plj;5Bb};by%XDPOk*&0hzrEvt#X8>lwIt#1#)Rq9ee)^Yto zv4qROW})pgIArji?OKBJVR?m!55Lvj@v*1W+P=}fu`G>@iPWA|#V;eu>Fb{`AQk!r zC{sfb3gUgSx-P2c^2x?@<0VJu+m-$yO6m)#QBG%MtezPHCvo-|aKFL=#Hegr=&xC++mZYA7-)`S{pS)QMZ$syCn604P zA-E9Q2~AOPap4?*Gz`BGZwu3cKkIkr{v8}D2j!Ykvh~C?rkMxRF>;{GK^892?tbEo zsv?X?W9VjNW~vLEKwb6c;oP*&Q#WhPw4_QQ%Ne?2^eVP+Gx>s^nxHVFP)#~)Vd#hc zs^GMQeR#jS`NESnAJeqAuI4}^=?v|RR}+SY%DrHq4J&iBiVOeq-vbor9q`WWtw-|q zBot3*nw)3}ZC5+=J=#^og4<^YI>v2xdcDABf8P$E7`^lWT+Q56*n{BR0-TE?ip<8T zhY>{zO}rIhxZ=~ZuA`Q>mz1@GvR|m-K~sxzkdJO*LHvn{CDJIma|1r(Yl**lK`mIp z0lSx+jJzi{y4^N%5MN7m-tL!WdiQI~oYB&C&(|J*IM#nYRqh|}Mkqz^^N>~Ka_1|U z|A?2w+GsqpbR<^D%E-)>qY2s$r+Nem?~#xz^^?fwCOwtOIZa*t1mD9kd{()0irplnX^|WH*i_0RA=5WH|GY9~ zsepe$no-t6Cc%V&yyNOyoDo0XdbdK(5Fd2wp029_LxUAQTi|K$qO z5iSYIne0lWI%=Ww5K4p%AR3~B1;-!QR9aFpbju9Y{phttAkslpXV_+Z3qbnWLX!il zA~$@M=2T`J(1}tYJ<5YWr}<}OYG;^kfHW;DP4&-;r#c^;m#zxT1#?-cY^?OXp0<(n z*6AEZU*u;beV#xE2h_hu4eK}s8wAIr1(%BW4GR-JdWhi@1OQe(woLt2TZO7K1I>!5 zGltU7h_i5Cl@+o4wfds7{7w&_?40{y41D)V&{a5u5_9}?rrBV#*I$R|d8qukI?HEg z6xlH=V1CKQ#=^JU5LOEO@f))7S~q4A^3F~q6J{%+qtXs9vl65cL-8xsmyf&7XJIT| zIVYAB_O2dsMLYL<qpmZ4s9372q}nDzmGU0dz2Zk2HT{S9Blq1y zuHKfyj$7uN*ao`|7)JbL2_ zISZ^Ooune0%&`zh|Dk?r59!kQ2iojZ%l7)z>Fn8l!%o^4f#8&nbNmA~{q>fWyF&)h z^{P4}AFCSIgY(tFk=H)b@;VK5$$pTmvGbiw4F|2(&y+6ijXU(|$PgSF55gf%ZfbcG z^geBLV5eGEsUi!oc|_X?Fnx$YnRFa#n1-|xsc!9g$ez6ug?QHE-X3#r&wAM9z=PD%X> zR|(jJUmh#Ck1e~^+E-|kqrJIxa6PduKqqN)#t_t7@li1{OQ+flCjybL)h)NG6@0F_ zSTuRg4m>bzvTd7xr1qYpfni->=ZY)BiA(96eBZRf_vtN;`cYc;1Du?mG_^B)HVa-N zbmbcK-@}pkxYIZa1Jjk|`}e={x1j%QNr0hG`bDLFDnoeH!?h!cCEGBfNuD@vq~uw~ zwi~UuOQ@}BT+<#!wF$&I1v?7dN3k@y7ZI=2N;V`GCw>rYJ3aVD1@@PNRQvzM+>eFm z2x6UPxmgEXM9*lcL)?#|QI+>%5V%40uGyDJ@N-745+$aTAwT2GZIJ)?>8L220zMgA__ zWg!zU8X**wwhrl~pOOgj#5!-U^fqgk6XdrDU|ILVXM;np_~^&xY}J zTcL`) zo2v3>nGb1dRBQbpnfz@Y4tfEycq0bC6(<#1&yvI*Pz=azc7C3IR@)*YCOYU0!!a`U(G$RH4l-MGI;!@GoaMSEqY6MhP52biZuEq! zApd(qkBE^_)lE|RTGS>q#(EoWhXq9`oi{>rwbH1L(3k5MPMMREQwFUo_wcn8i0f(Z z2A5$OP@rs`^Ti#Jo-mT|_)Fa44B#C3gl3mxz?JzXa01(9Q7#~%ok#@_q`XrlYaI!Z zC*iXXcFLK*2CuKIxxjiHF4xh#1Z*!oR+}DQ-LM@>JM+IvT~3fx7Ui1iscQKL0 zx4^)t1$*R*>}fNUi(FDqzHISJtbRQ-=g8j1aA&kUo!siH^ATming~m*_$^UAC7t`y z@0C6+lHy%2kxcEi;U)a{fE21zzHr(btVAJ4a_)oxCrb5_mWtiM#y_LU{b9C<>ZQ^{ z0c8uLD41xjnf2h6l+P8Azt)wv$-93de6;C%DFK$()n(@bLMw0O3p5OFMn4?;Ia%kI zA%FIHD?OzbczSV`mf|v4GAkp7V5jA#T9Ghs4fAcW}TM_;A&n@ZEt@Iq1xcSmanj zTR@7_$Mx#+#`fiy)jUFw=30bt6IHO~<;$zxv^Y;7Jiq_=?mka=T0hf6Dqv!`w-y)f zL+~6$DDL6UwqcB3=$1D1lba~?{ly1$nlE_|@D!!8!Wn(sKI<*GkNku@vf-EOB7#t~ z;op?3!(v1)!N=j|L1fb-=q%O{91BNwyI)fQ* z%W9(k=G)&&#&8Mj=uN{PFNv_S@!26*YL@X7pIB9xO{R_-j2bt@BmWj=5IVaQAFPmntD-!E;K;!O=)F zu5-}~BYZiYFhJdrYxQvo24jEj>PTz%>#rC$X^?ZXwO9uw^lhKGN$X_C}nDy#sX({v6UDA3px?@x=Kd527^_ zDo=>|RmG0cx;gzxym!ETll>->xr=!BzBb2X_T0$tbA`uW>rg5-Hw8M=&5`&Sy1{81 z#N?Kti{HJ@yD}ypbU-7VL8OL?isQC@ee3R{;h)oGZLik~+&*?x)F#H;(^{7_vX%eN z7wrR9Qe_Jmv|G1COA+#vi5j^~&iE3z{T=C(M$wsz;_l_+87`$VmapU>HE4o8k8@VW ztGD@7daZOfN&4{`w$s#!(xl^Uv%(0@`kkq#wPd+)buF z;3#$BH&tMx-r7HF2xqKR23#%>2aWIWBn5B|Q-3`z?DXEcFz+~{EjS9ri4!e#1U?B5 zbd*q{;s(J9pOkph5y7eigYKHLHhk0Bh*#THx|5&nclW|7{gS36+6N7i@B+;S`b9Av zHUZ$%oLT7J*~mKpwlVfDN_;ZP&qHj4+j}`5H<4OAUyb&*+oT6glS1ct7>n;nhr<|y zN9}w;x7(n0Veu&M80W)j@BX2v2aLjrhwr<0kzWnSYH(XBQrR2Ly6@VJU((A(g*5>! zBE`kp(zp=f?F?Y|CBgzqVS!6f_g<8y_(DU?(iT_|+%eFAeGCxF(r>zv?!Dpi>7S?i zj_;f0dx3Wd;`o+CB$DDPVA!wcyB!GlA~*4KPu!L3+e7~%PH#iEi{;t!Wr&F2(n-0B zZ-_|YP0NqtgEM3A{;fajX<6{S+1j;kkDm0kmZ(qX^2S@LsbJ(gsw&~~lt#88i^ zD;;#_C%gvQH4hb@59_91Va!aI>1d`1C{QIfu`sMhMn=?bGL_NfSJ2!vKGcv2wjKP2 zp{K1fS7qI`YBs}=Cfmx2{o)YW+)%9tG-iErM3a{Ex)+ydKPa$0qsTkLFeV_cfl_jy z7tdJj?Pn=IN5L^r=7YnEFA8Zduvl(n)qHuSl zu@f$C6avs=d3XOv)|}tgL>)A>0WYOp-NC&E?$Dh`4%WylRdskFL#so!7iD?Ft4o=! z+7<81a*o#OSK-s|D1Pcst$a{$f0K@HfUcxhn2PR?&H}yg0tBYymV(-HmU!7&k;<^% z#p;frqJu*Wm3nV0X*w^QV`71sSla+H1i`F?4yo|b>JENmk)h6uv6YH_ccUpY0ZffD zQLs;ILJGf#XKB-pOzd9!Zv|CgikUiG3qzZH>kLUTTomkkO5;vc@u?%yXwE4d>(tRJ z!Aw`k!);8>5EIWHUwnB`kXfp+Drnj9kmJWcmwz*yEz2yG2j=#;BY~*y$26$Pu79R% zGj|m>%aB0O$%f^9lx8OX1tZsO@kS%_MpIb{?-7e>l`?CgmQZ}C;XRFOK|d8O)6PNb#mGeWKmFqu9)n=4wvJS41g4|eUqczz2L^c|y=mCWVv}h~NWxRQ? zCs_PY(6fIV=L+912sU7M8)JE%^muGE4$WMT?5^>Rt93jBgEIBfQ*$Rec+L15 zMcin+Mc)`4Jh*xQL*pIZ$eGjU(f-Sc46d8Ugp>$yd|GN5 z|L$WGKxLNSWr57y;SrboiDCRb&wp?g=xU-35CFL8*mvnrnVs;ULOJNo9&qI!-2lvE zIlK|oR%h{W^rIW50TkhIitk{??x;${BJ4Jx)6MahEi*7DP9FiWz|Mqtwf1CyC;*-<=9SS?x53;6C zlje-NAQyBs{7(BX!A?8dD7Q&h-H*@Mg0dK%Y6C}yg3Wx|8x@$+M_I7rm)kCfok&gC zIy5?ZY@OsVSc5poxCdZ&C&Ah(^uu=7wtNoO2Vhiy*=#h8aS34DW1h)I|B4}#TZ)Lo zf-LPq3gQeEAlIM+J*F#(OE1ds&$Gsn3M#m`Djo0c&u$jKz%hDtFOsseVf77aEOqHc z^fi0`6Vo3YK^Dt&WuvYA87b4Jh;c7lW-dOrL`B0^6oZk7LRj``25;&|uS-vbg=`Ya z7#;b*v{)x`FfKM)dBHww8WNk6-1(A`2GL} zwa6A9`K96{ zmM+f7ErS?{LXmc7VC4cp(K}hIVTz1LG@*vj#1wwwdhC8H$2s}BX^?V%IH{+KEPt#j z&bdSqbh1M&L>NaeR5LCV1(fil`IP zxFA&KOC2VKwnQ1w2)zIKC<3lH8kh-%g91WsEjJNTVm(S_rXfJ!=A};Q)+L!-4}~Ej#9=*K z`R(s7rN_d1a)P4zhInw|9s-dV2;rP3_sv;w$wCOQ zUfCxtjxxt|+2yDZ+VwB+-Y_G;OHJ-aQrocr!cZRizBDoQA&0DH5~3c8GvJ6w9Jooa z-bx*Ic&7v!+(vne;Nw>A;;}cLmVh_v#N-;n+{%Ty)pwOW1RZjeE%aCFI!%{Anc){b z5APXm{~1WW(tS+fRk3{>b!DgskPsyvtRH$S;e}4ZCT5AdrH8&Q{Y{7qI(`vD$;#Q7 zbG1BZzUHTT@X4x>Q<5Fyt8^AB4tj93Gb*W2_Z~Uh?*Ia>bZEw(2#)cR%*{y(g%}>&q8|)TT*}VsSiGAWt4Et_c?U=> z%5HCUK4iVr(u>=Rysip6unBJLsZo+_kXDwgeOcZ4?T&4}q|JR7+65|GU*g+JKNTEn zo|aXFbT%Q%kIFndQkvP}234^i)X1t#vs=Fz=H;$z_#Ju#GA^R{JT!FKxz8kd`>En} zk5YWXhVl~PPdMPa+1hJ-&;DM}J0x3-CN!s?$2?pZ<%k4?ebd=*?a+>Gec0d--7sTK^YRySlk}YtuOG-rJKq z`AJ?rhWh)!OLn^>;3fd$qjlZTF3RxcD8RHN{yj!mBl=MccYB_W7juO}f+n9h8=AFW<4J z8Z*sqrEGL5G(~m^#+=p?jF3Ex`l*QT*B%N3zkp1~waHv;8HDTpRTdd@-e z2RHBh1Q+*GacPbmDL}qsZ`xtYFrJVh8IRW5k))AOitN{n)fhSvuW(cv&4G3 zvfA=75^y-UoQ(s<8sNqd{D&^ooCn(n8!Dndy~WaBJVBcJ-BGcg&@eiH#R?M*q|4(# zgRmYO4n(&H0i@esHJtF)^7fC1U`*G$Lp_vK6eiE>PrHZd7v5QIYsNP$Y)whilGS6y zq!tne5P%CQA0%$2LmyPC&2AHHJrbqvJ7J=~>k6MO#FezmR0!Vcvw{uNO37BxtJ(4RP*xIH zZRC-MU4Ts$w6!`l_8W5pyfvCChc}Z5k$B7#^3j+|A_Pr%iLSp2QJ2+qT8y?r;}#$K z%~HclMQ8-Osad91D>1^wHSQ<$to1lw^{@k@8TYTIK<%G)V1;!pY8^>`q(Gvw(sbdD zy*2VqzsbX0omTTEJvpAvOuRtvd}~hc5v*F3TO@wDp?ztD?%Utfy+l&)q*^O(4WQ!0 zq(P9cLtYVwp%?f}hUzd+vM z&@;sYznd6mp-a|AcF@~B6fcxjA6Cor1P#p&X5s#^mBY85{y=cAs#xJ}6V@yiHyj2V z@G;=d)ps|4IM?F}8;bt=vzG}BS*a|zeGH?KS`1hYNFPcDirM&o4@%4~Y}-&yax?c=rXx-b&@vuNlT48(_|?Bu_{6!Ow4QuPw1q5lJ6SXos7 literal 0 HcmV?d00001 diff --git a/video_call/ios/Runner/Assets.xcassets/Contents.json b/video_call/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/video_call/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/video_call/ios/Runner/Base.lproj/LaunchScreen.storyboard b/video_call/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..0ab9a4c --- /dev/null +++ b/video_call/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/video_call/ios/Runner/Base.lproj/Main.storyboard b/video_call/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/video_call/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/video_call/ios/Runner/Info.plist b/video_call/ios/Runner/Info.plist new file mode 100644 index 0000000..4d8ba2e --- /dev/null +++ b/video_call/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + video_call + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + NSCameraUsageDescription + To make video calls + NSMicrophoneUsageDescription + To make video calls + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/video_call/ios/Runner/main.m b/video_call/ios/Runner/main.m new file mode 100644 index 0000000..dff6597 --- /dev/null +++ b/video_call/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/video_call/lib/active_call/active_call.dart b/video_call/lib/active_call/active_call.dart new file mode 100644 index 0000000..7e94a22 --- /dev/null +++ b/video_call/lib/active_call/active_call.dart @@ -0,0 +1,5 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'active_call_page.dart'; +export 'active_call_page_arguments.dart'; +export 'bloc/bloc.dart'; diff --git a/video_call/lib/active_call/active_call_page.dart b/video_call/lib/active_call/active_call_page.dart new file mode 100644 index 0000000..e0ecd3b --- /dev/null +++ b/video_call/lib/active_call/active_call_page.dart @@ -0,0 +1,242 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_voximplant/flutter_voximplant.dart'; +import 'package:video_call/active_call/active_call.dart'; +import 'package:video_call/call_failed/call_failed.dart'; +import 'package:video_call/routes.dart'; +import 'package:video_call/theme/voximplant_theme.dart'; +import 'package:video_call/widgets/widgets.dart'; + +import 'bloc/active_call_state.dart'; + +class ActiveCallPage extends StatefulWidget { + @override + State createState() { + return _ActiveCallPageState(); + } +} + +class _ActiveCallPageState extends State { + String callState = 'Connecting'; + VIVideoViewController _localVideoViewController = VIVideoViewController(); + VIVideoViewController _remoteVideoViewController = VIVideoViewController(); + double _localVideoAspectRatio = 1.0; + double _remoteVideoAspectRatio = 1.0; + bool isOnHold = false; + bool isSendingVideo = true; + ActiveCallPageArguments _arguments; + + void _localVideoHasChanged() { + setState(() { + _localVideoAspectRatio = _localVideoViewController.aspectRatio; + }); + } + + void _remoteVideoHasChanged() { + setState(() { + _remoteVideoAspectRatio = _remoteVideoViewController.aspectRatio; + }); + } + + @override + void initState() { + super.initState(); + _localVideoViewController.addListener(_localVideoHasChanged); + _remoteVideoViewController.addListener(_remoteVideoHasChanged); + } + + @override + void didChangeDependencies(){ + super.didChangeDependencies(); + _arguments = + ModalRoute.of(context).settings.arguments; + if (_arguments.isIncoming) { + BlocProvider.of(context).add(AnswerIncomingCall()); + } else { + BlocProvider.of(context) + .add(StartOutgoingCall(callTo: _arguments.callTo)); + } + } + + @override + void dispose() { + _localVideoViewController.removeListener(_localVideoHasChanged); + _remoteVideoViewController.removeListener(_remoteVideoHasChanged); + _localVideoViewController.dispose(); + _remoteVideoViewController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + void _hangup() { + BlocProvider.of(context).add(EndCall()); + } + + void _hold() { + BlocProvider.of(context).add(HoldCall(doHold: !isOnHold)); + } + + void _sendVideo() { + BlocProvider.of(context) + .add(SendVideo(doSend: !isSendingVideo)); + } + + void _switchCamera() { + BlocProvider.of(context).add(SwitchCamera()); + } + + return BlocListener( + listener: (context, state) { + if (state is ActiveCallDisconnected) { + Navigator.of(context).pushReplacementNamed(AppRoutes.makeCall); + } + if (state is ActiveCallFailed) { + Navigator.of(context).pushReplacementNamed(AppRoutes.callFailed, + arguments: CallFailedPageArguments(failureReason: state.errorDescription, + endpoint: state.endpoint ?? _arguments.callTo + ) + ); + } + if (state is ActiveCallConnecting) { + setState(() { + callState = 'Connecting'; + }); + } + if (state is ActiveCallRinging) { + setState(() { + callState = 'Ringing'; + }); + } + if (state is ActiveCallConnected) { + setState(() { + callState = 'Connected'; + }); + } + if (state is ActiveCallVideoStreamAdded) { + if (state.isLocal) { + _localVideoViewController.streamId = state.streamId; + } else { + _remoteVideoViewController.streamId = state.streamId; + } + } + if (state is ActiveCallVideoStreamRemoved) { + if (state.isLocal) { + _localVideoViewController.streamId = null; + } else { + _remoteVideoViewController.streamId = null; + } + } + if (state is ActiveCallHold) { + setState(() { + isOnHold = state.isHeld; + }); + } + if (state is ActiveCallSendVideo) { + setState(() { + isSendingVideo = state.isSendingVideo; + }); + } + }, + child: BlocBuilder( + builder: (context, state) { + return Scaffold( + backgroundColor: VoximplantColors.grey, + body: SafeArea( + child: Column( + children: [ + Expanded( + child: Container( + child: Stack( + children: [ + Align( + alignment: Alignment.center, + child: AspectRatio( + aspectRatio: _remoteVideoAspectRatio, + child: VIVideoView(_remoteVideoViewController), + ), + ), + Align( + alignment: Alignment.topRight, + child: Padding( + padding: EdgeInsets.all(10), + child: Container( + width: MediaQuery.of(context).size.width / 4, + height: MediaQuery.of(context).size.height / 4, + child: Align( + child: AspectRatio( + aspectRatio: _localVideoAspectRatio, + child: VIVideoView(_localVideoViewController), + ), + ), + ), + ) + ), + Align( + alignment: Alignment.topLeft, + child: Padding( + padding: EdgeInsets.only(left: 20, top: 20), + child: Platform.isAndroid ? + Widgets.iconButton( + icon: Icons.switch_camera, + color: VoximplantColors.button, + tooltip: 'Switch camera', + onPressed: _switchCamera, + ) : + Container() + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: Text( + callState, + style: TextStyle(color: VoximplantColors.white), + ), + ) + ], + ), + ), + ), + Container( + height: 80, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Widgets.iconButton( + icon: isSendingVideo + ? Icons.videocam_off + : Icons.videocam, + color: VoximplantColors.button, + tooltip: 'Send video', + onPressed: _sendVideo), + Widgets.iconButton( + icon: Icons.call_end, + color: VoximplantColors.red, + tooltip: 'Hang up', + onPressed: _hangup), + Widgets.iconButton( + icon: isOnHold ? Icons.play_arrow : Icons.pause, + color: VoximplantColors.button, + tooltip: 'Hold', + onPressed: _hold), + ], + ), + ], + ), + ), + ], + ), + ), + ); + }, + ), + ); + } +} diff --git a/video_call/lib/active_call/active_call_page_arguments.dart b/video_call/lib/active_call/active_call_page_arguments.dart new file mode 100644 index 0000000..bed7929 --- /dev/null +++ b/video_call/lib/active_call/active_call_page_arguments.dart @@ -0,0 +1,11 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +class ActiveCallPageArguments { + String callTo; + bool isIncoming; + + ActiveCallPageArguments({ + this.isIncoming, + this.callTo + }); +} diff --git a/video_call/lib/active_call/bloc/active_call_bloc.dart b/video_call/lib/active_call/bloc/active_call_bloc.dart new file mode 100644 index 0000000..1687b29 --- /dev/null +++ b/video_call/lib/active_call/bloc/active_call_bloc.dart @@ -0,0 +1,115 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_voximplant/flutter_voximplant.dart'; +import 'package:video_call/active_call/bloc/active_call_event.dart'; +import 'package:video_call/active_call/bloc/active_call_state.dart'; +import 'package:video_call/services/auth_service.dart'; +import 'package:video_call/services/call_service.dart'; +import 'package:video_call/services/call_state.dart'; + +class ActiveCallBloc extends Bloc { + final AuthService authService; + final CallService callService; + String _callId; + VICameraType _cameraType = VICameraType.Front; + + StreamSubscription _callStateSubscription; + + ActiveCallBloc({@required this.authService, this.callService}); + + @override + ActiveCallState get initialState => ActiveCallConnecting(); + + @override + Stream mapEventToState(ActiveCallEvent event) async* { + if (event is StartOutgoingCall) { + try { + _callId = await callService.makeVideoCall(callTo: event.callTo); + _callStateSubscription = callService + .subscribeToCallStateChanges(_callId) + .listen(onCallStateChanged); + } catch (e) { + yield ActiveCallFailed(errorDescription: e, endpoint: event.callTo); + } + } + if (event is AnswerIncomingCall) { + try { + _callId = await callService.answerVideoCall(); + _callStateSubscription = callService + .subscribeToCallStateChanges(_callId) + .listen(onCallStateChanged); + } catch (e) { + yield ActiveCallFailed(errorDescription: e, endpoint: null); + } + } + if (event is EndCall) { + await callService.endCall(_callId); + } + if (event is HoldCall) { + try { + await callService.holdCall(_callId, event.doHold); + yield ActiveCallHold(isHeld: event.doHold, errorDescription: null); + } on VIException catch (e) { + yield ActiveCallHold( + isHeld: !event.doHold, errorDescription: e.message); + } + } + if (event is SendVideo) { + try { + await callService.sendVideo(_callId, event.doSend); + yield ActiveCallSendVideo( + isSendingVideo: event.doSend, errorDescription: null); + } on VIException catch (e) { + yield ActiveCallSendVideo( + isSendingVideo: !event.doSend, errorDescription: e.message); + } + } + if (event is SwitchCamera) { + VICameraType cameraToSwitch = _cameraType == VICameraType.Front ? + VICameraType.Back : VICameraType.Front; + await Voximplant().getCameraManager().selectCamera(cameraToSwitch); + _cameraType = cameraToSwitch; + } + if (event is UpdateCallState) { + CallState callState = event.callState; + if (callState is CallStateRinging) { + yield ActiveCallRinging(); + } + if (callState is CallStateConnected) { + yield ActiveCallConnected(); + } + if (callState is CallStateDisconnected) { + yield ActiveCallDisconnected(); + } + if (callState is CallStateFailed) { + yield ActiveCallFailed( + errorDescription: callState.errorDescription, + endpoint: callState.endpoint); + } + if (callState is CallStateVideoStreamAdded) { + yield ActiveCallVideoStreamAdded( + streamId: callState.streamId, isLocal: callState.isLocal); + } + if (callState is CallStateVideoStreamRemoved) { + yield ActiveCallVideoStreamRemoved( + streamId: callState.streamId, isLocal: callState.isLocal); + } + } + } + + @override + Future close() { + if (_callStateSubscription != null) { + _callStateSubscription.cancel(); + } + return super.close(); + } + + void onCallStateChanged(CallState state) { + add(UpdateCallState(callState: state)); + } +} diff --git a/video_call/lib/active_call/bloc/active_call_event.dart b/video_call/lib/active_call/bloc/active_call_event.dart new file mode 100644 index 0000000..29d112d --- /dev/null +++ b/video_call/lib/active_call/bloc/active_call_event.dart @@ -0,0 +1,66 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:meta/meta.dart'; +import 'package:equatable/equatable.dart'; +import 'package:video_call/services/call_state.dart'; + +abstract class ActiveCallEvent extends Equatable { + const ActiveCallEvent(); + + @override + List get props => []; +} + +class StartOutgoingCall extends ActiveCallEvent { + final String callTo; + + StartOutgoingCall({@required this.callTo}); + + @override + List get props => [callTo]; + + @override + String toString() => 'StartOutgoingCall: callTo: $callTo'; +} + +class AnswerIncomingCall extends ActiveCallEvent {} + +class EndCall extends ActiveCallEvent {} + +class UpdateCallState extends ActiveCallEvent { + final CallState callState; + + UpdateCallState({@required this.callState}); + + @override + List get props => [callState]; + + @override + String toString() => 'UpdateCallState: callState: $callState'; +} + +class HoldCall extends ActiveCallEvent { + final bool doHold; + + HoldCall({@required this.doHold}); + + @override + List get props => [doHold]; + + @override + String toString() => 'HoldCall: doHold: $doHold'; +} + +class SendVideo extends ActiveCallEvent { + final bool doSend; + + SendVideo({@required this.doSend}); + + @override + List get props => [doSend]; + + @override + String toString() => 'SendVideo: doSend: $doSend'; +} + +class SwitchCamera extends ActiveCallEvent {} diff --git a/video_call/lib/active_call/bloc/active_call_state.dart b/video_call/lib/active_call/bloc/active_call_state.dart new file mode 100644 index 0000000..3786fb9 --- /dev/null +++ b/video_call/lib/active_call/bloc/active_call_state.dart @@ -0,0 +1,87 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:meta/meta.dart'; +import 'package:equatable/equatable.dart'; + +abstract class ActiveCallState extends Equatable { + const ActiveCallState(); + @override + List get props => []; +} + +class ActiveCallConnecting extends ActiveCallState {} + +class ActiveCallRinging extends ActiveCallState {} + +class ActiveCallConnected extends ActiveCallState {} + +class ActiveCallDisconnected extends ActiveCallState {} + +class ActiveCallVideoStreamAdded extends ActiveCallState { + final String streamId; + final bool isLocal; + ActiveCallVideoStreamAdded({@required this.streamId, @required this.isLocal}); + + @override + List get props => [streamId, isLocal]; + + @override + String toString() => + 'ActiveCallVideoStreamAdded: streamId: $streamId, isLocal: $isLocal'; +} + +class ActiveCallVideoStreamRemoved extends ActiveCallState { + final String streamId; + final bool isLocal; + ActiveCallVideoStreamRemoved( + {@required this.streamId, @required this.isLocal}); + + @override + List get props => [streamId, isLocal]; + + @override + String toString() => + 'ActiveCallVideoStreamRemoved: streamId: $streamId, isLocal: $isLocal'; +} + +class ActiveCallFailed extends ActiveCallState { + final String errorDescription; + final String endpoint; + + ActiveCallFailed({@required this.errorDescription, @required this.endpoint}); + + @override + List get props => [errorDescription, endpoint]; + + @override + String toString() => 'CallFailed: errorDescription: $errorDescription'; +} + +class ActiveCallHold extends ActiveCallState { + final bool isHeld; + final String errorDescription; + + ActiveCallHold({@required this.isHeld, @required this.errorDescription}); + + @override + List get props => [isHeld, errorDescription]; + + @override + String toString() => + 'ActiveCallHold: isHeld: $isHeld, errorDescription: $errorDescription'; +} + +class ActiveCallSendVideo extends ActiveCallState { + final bool isSendingVideo; + final String errorDescription; + + ActiveCallSendVideo( + {@required this.isSendingVideo, @required this.errorDescription}); + + @override + List get props => [isSendingVideo, errorDescription]; + + @override + String toString() => 'ActiveCallSendVideo: isSendingVideo: $isSendingVideo,' + ' errorDescription: $errorDescription'; +} diff --git a/video_call/lib/active_call/bloc/bloc.dart b/video_call/lib/active_call/bloc/bloc.dart new file mode 100644 index 0000000..4223ccc --- /dev/null +++ b/video_call/lib/active_call/bloc/bloc.dart @@ -0,0 +1,5 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'active_call_bloc.dart'; +export 'active_call_event.dart'; +export 'active_call_state.dart'; diff --git a/video_call/lib/call_failed/call_failed.dart b/video_call/lib/call_failed/call_failed.dart new file mode 100644 index 0000000..04f93af --- /dev/null +++ b/video_call/lib/call_failed/call_failed.dart @@ -0,0 +1,4 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'call_failed_page.dart'; +export 'call_failed_page_arguments.dart'; diff --git a/video_call/lib/call_failed/call_failed_page.dart b/video_call/lib/call_failed/call_failed_page.dart new file mode 100644 index 0000000..0387c0f --- /dev/null +++ b/video_call/lib/call_failed/call_failed_page.dart @@ -0,0 +1,59 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter/material.dart'; +import 'package:video_call/routes.dart'; +import 'package:video_call/theme/voximplant_theme.dart'; +import 'package:video_call/widgets/widgets.dart'; + +import 'call_failed_page_arguments.dart'; + +class CallFailedPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + final CallFailedPageArguments _arguments = + ModalRoute.of(context).settings.arguments; + + return Scaffold( + backgroundColor: VoximplantColors.primaryDark, + body: SafeArea( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + child: Column( + children: [ + Widgets.textWithPadding( + text: 'Call failed', + textColor: VoximplantColors.white, + fontSize: 40, + ), + Widgets.textWithPadding( + text: '${_arguments.endpoint}', + textColor: VoximplantColors.white, + fontSize: 30, + verticalPadding: 30, + ), + Widgets.textWithPadding( + text: '${_arguments.failureReason}', + textColor: VoximplantColors.white, + fontSize: 25, + ), + ], + ), + ), + Widgets.iconButton( + icon: Icons.close, + color: VoximplantColors.button, + tooltip: 'Close', + onPressed: () { + Navigator.of(context) + .pushReplacementNamed(AppRoutes.makeCall); + }), + ], + ), + ), + ), + ); + } +} diff --git a/video_call/lib/call_failed/call_failed_page_arguments.dart b/video_call/lib/call_failed/call_failed_page_arguments.dart new file mode 100644 index 0000000..3dc9e06 --- /dev/null +++ b/video_call/lib/call_failed/call_failed_page_arguments.dart @@ -0,0 +1,11 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:meta/meta.dart'; + +class CallFailedPageArguments { + final String failureReason; + final String endpoint; + + CallFailedPageArguments( + {@required this.failureReason, @required this.endpoint}); +} diff --git a/video_call/lib/incoming_call/bloc/bloc.dart b/video_call/lib/incoming_call/bloc/bloc.dart new file mode 100644 index 0000000..b975be7 --- /dev/null +++ b/video_call/lib/incoming_call/bloc/bloc.dart @@ -0,0 +1,5 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'incoming_call_bloc.dart'; +export 'incoming_call_event.dart'; +export 'incoming_call_state.dart'; diff --git a/video_call/lib/incoming_call/bloc/incoming_call_bloc.dart b/video_call/lib/incoming_call/bloc/incoming_call_bloc.dart new file mode 100644 index 0000000..4e3ff9b --- /dev/null +++ b/video_call/lib/incoming_call/bloc/incoming_call_bloc.dart @@ -0,0 +1,93 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'dart:async'; +import 'dart:io'; + +import 'package:bloc/bloc.dart'; +import 'package:meta/meta.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:video_call/services/auth_service.dart'; +import 'package:video_call/services/call_service.dart'; +import 'package:video_call/services/call_state.dart'; + +import 'incoming_call_event.dart'; +import 'incoming_call_state.dart'; + +class IncomingCallBloc extends Bloc { + final AuthService authService; + final CallService callService; + + String _callId; + StreamSubscription _callStateSubscription; + + IncomingCallBloc({@required this.authService, this.callService}); + + @override + IncomingCallState get initialState => IncomingCallInitial(); + + @override + Stream mapEventToState(IncomingCallEvent event) async* { + if (event is Load) { + _callId = callService.activeCallId; + _callStateSubscription = callService + .subscribeToCallStateChanges(_callId) + .listen(onCallStateChanged); + } + if (event is CheckPermissions) { + yield* _checkPermissions(); + } + if (event is DeclineCall) { + await callService.declineCall(_callId); + } + if (event is IncomingCallDisconnected) { + yield CallHasEnded(); + } + } + + @override + Future close() { + if (_callStateSubscription != null) { + _callStateSubscription.cancel(); + } + return super.close(); + } + + Stream _checkPermissions() async* { + if (Platform.isAndroid) { + PermissionStatus recordAudio = await PermissionHandler() + .checkPermissionStatus(PermissionGroup.microphone); + PermissionStatus camera = await PermissionHandler() + .checkPermissionStatus(PermissionGroup.camera); + List requestPermissions = List(); + if (recordAudio != PermissionStatus.granted) { + requestPermissions.add(PermissionGroup.microphone); + } + if (camera != PermissionStatus.granted) { + requestPermissions.add(PermissionGroup.camera); + } + if (requestPermissions.isEmpty) { + yield PermissionCheckPass(); + } else { + Map result = + await PermissionHandler().requestPermissions(requestPermissions); + if (result[PermissionGroup.microphone] != PermissionStatus.granted || + result[PermissionGroup.camera] != PermissionStatus.granted) { + yield PermissionCheckFailed(); + } else { + yield PermissionCheckPass(); + } + } + } else if (Platform.isIOS) { + yield PermissionCheckPass(); + } else { + //not supported platforms + yield PermissionCheckFailed(); + } + } + + void onCallStateChanged(CallState state) { + if (state is CallStateDisconnected) { + add(IncomingCallDisconnected()); + } + } +} diff --git a/video_call/lib/incoming_call/bloc/incoming_call_event.dart b/video_call/lib/incoming_call/bloc/incoming_call_event.dart new file mode 100644 index 0000000..891d027 --- /dev/null +++ b/video_call/lib/incoming_call/bloc/incoming_call_event.dart @@ -0,0 +1,18 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:equatable/equatable.dart'; + +abstract class IncomingCallEvent extends Equatable { + const IncomingCallEvent(); + + @override + List get props => []; +} + +class Load extends IncomingCallEvent {} + +class CheckPermissions extends IncomingCallEvent {} + +class DeclineCall extends IncomingCallEvent {} + +class IncomingCallDisconnected extends IncomingCallEvent {} diff --git a/video_call/lib/incoming_call/bloc/incoming_call_state.dart b/video_call/lib/incoming_call/bloc/incoming_call_state.dart new file mode 100644 index 0000000..c0a1744 --- /dev/null +++ b/video_call/lib/incoming_call/bloc/incoming_call_state.dart @@ -0,0 +1,18 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:equatable/equatable.dart'; + +abstract class IncomingCallState extends Equatable { + const IncomingCallState(); + + @override + List get props => []; +} + +class IncomingCallInitial extends IncomingCallState {} + +class PermissionCheckFailed extends IncomingCallState {} + +class PermissionCheckPass extends IncomingCallState {} + +class CallHasEnded extends IncomingCallState {} diff --git a/video_call/lib/incoming_call/incoming_call.dart b/video_call/lib/incoming_call/incoming_call.dart new file mode 100644 index 0000000..a35d6b9 --- /dev/null +++ b/video_call/lib/incoming_call/incoming_call.dart @@ -0,0 +1,5 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'incoming_call_page.dart'; +export 'incoming_call_page_arguments.dart'; +export 'bloc/bloc.dart'; diff --git a/video_call/lib/incoming_call/incoming_call_page.dart b/video_call/lib/incoming_call/incoming_call_page.dart new file mode 100644 index 0000000..943a760 --- /dev/null +++ b/video_call/lib/incoming_call/incoming_call_page.dart @@ -0,0 +1,92 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:video_call/active_call/active_call.dart'; +import 'package:video_call/incoming_call/incoming_call.dart'; +import 'package:video_call/routes.dart'; +import 'package:video_call/theme/voximplant_theme.dart'; +import 'package:video_call/widgets/widgets.dart'; + +import 'bloc/incoming_call_bloc.dart'; + +class IncomingCallPage extends StatefulWidget { + @override + State createState() { + return _IncomingCallPageState(); + } +} + +class _IncomingCallPageState extends State { + void _answerCall() { + BlocProvider.of(context).add(CheckPermissions()); + } + + void _declineCall() { + BlocProvider.of(context).add(DeclineCall()); + } + + @override + Widget build(BuildContext context) { + final IncomingCallPageArguments _arguments = + ModalRoute.of(context).settings.arguments; + + return BlocListener( + listener: (context, state) { + if (state is CallHasEnded) { + Navigator.of(context).pushReplacementNamed(AppRoutes.makeCall); + } + if (state is PermissionCheckPass) { + Navigator.of(context).pushReplacementNamed( + AppRoutes.activeCall, + arguments: ActiveCallPageArguments(isIncoming: true), + ); + } + }, + child: BlocBuilder( + builder: (context, state) { + return Scaffold( + backgroundColor: VoximplantColors.primaryDark, + body: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Widgets.textWithPadding( + text: 'Incoming call from', + textColor: VoximplantColors.white, + fontSize: 30, + verticalPadding: 20, + ), + Widgets.textWithPadding( + text: '${_arguments.caller}', + textColor: VoximplantColors.white, + fontSize: 25, + ), + Padding( + padding: EdgeInsets.only(top: 80), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Widgets.iconButton( + icon: Icons.call, + color: VoximplantColors.button, + tooltip: 'Answer', + onPressed: _answerCall), + Widgets.iconButton( + icon: Icons.call_end, + color: VoximplantColors.red, + tooltip: 'Decline', + onPressed: _declineCall) + ], + ), + ), + ], + ), + ), + ); + }, + ), + ); + } +} diff --git a/video_call/lib/incoming_call/incoming_call_page_arguments.dart b/video_call/lib/incoming_call/incoming_call_page_arguments.dart new file mode 100644 index 0000000..5dabf69 --- /dev/null +++ b/video_call/lib/incoming_call/incoming_call_page_arguments.dart @@ -0,0 +1,7 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +class IncomingCallPageArguments { + String caller; + + IncomingCallPageArguments({this.caller}); +} diff --git a/video_call/lib/login/bloc/bloc.dart b/video_call/lib/login/bloc/bloc.dart new file mode 100644 index 0000000..eabedf6 --- /dev/null +++ b/video_call/lib/login/bloc/bloc.dart @@ -0,0 +1,5 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'login_state.dart'; +export 'login_bloc.dart'; +export 'login_event.dart'; diff --git a/video_call/lib/login/bloc/login_bloc.dart b/video_call/lib/login/bloc/login_bloc.dart new file mode 100644 index 0000000..aaee587 --- /dev/null +++ b/video_call/lib/login/bloc/login_bloc.dart @@ -0,0 +1,45 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:bloc/bloc.dart'; +import 'package:meta/meta.dart'; +import 'package:video_call/login/login.dart'; +import 'package:video_call/services/auth_service.dart'; + +import 'package:flutter_voximplant/flutter_voximplant.dart'; + +class LoginBloc extends Bloc { + final AuthService authService; + + LoginBloc({@required this.authService}); + + @override + LoginState get initialState => LoginInitial(); + + @override + Stream mapEventToState(LoginEvent event) async* { + if (event is LoadLastUser) { + String lastUser = await authService.getUsername(); + yield LoginLastUserLoaded(lastUser: lastUser); + bool canUseAccessToken = await authService.canUseAccessToken(); + if (canUseAccessToken) { + yield LoginInProgress(); + try { + await authService.loginWithAccessToken(); + yield LoginSuccess(); + } on VIException catch (e) { + yield LoginFailure(errorCode: e.code, errorDescription: e.message); + } + } + } + if (event is LoginWithPassword) { + yield LoginInProgress(); + try { + await authService.loginWithPassword( + event.username + '.voximplant.com', event.password); + yield LoginSuccess(); + } on VIException catch (e) { + yield LoginFailure(errorCode: e.code, errorDescription: e.message); + } + } + } +} diff --git a/video_call/lib/login/bloc/login_event.dart b/video_call/lib/login/bloc/login_event.dart new file mode 100644 index 0000000..f38f713 --- /dev/null +++ b/video_call/lib/login/bloc/login_event.dart @@ -0,0 +1,26 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:meta/meta.dart'; +import 'package:equatable/equatable.dart'; + +abstract class LoginEvent extends Equatable { + const LoginEvent(); + @override + List get props => []; +} + +class LoadLastUser extends LoginEvent {} + +class LoginWithPassword extends LoginEvent { + final String username; + final String password; + + LoginWithPassword({@required this.username, @required this.password}); + + @override + List get props => [username, password]; + + @override + String toString() => 'LoginWithPassword: ' + 'username: $username, password: *****'; +} diff --git a/video_call/lib/login/bloc/login_state.dart b/video_call/lib/login/bloc/login_state.dart new file mode 100644 index 0000000..0eda659 --- /dev/null +++ b/video_call/lib/login/bloc/login_state.dart @@ -0,0 +1,43 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:meta/meta.dart'; +import 'package:equatable/equatable.dart'; + +abstract class LoginState extends Equatable { + const LoginState(); + + @override + List get props => []; +} + +class LoginInitial extends LoginState {} + +class LoginLastUserLoaded extends LoginState { + final String lastUser; + const LoginLastUserLoaded({@required this.lastUser}); + + @override + List get props => [lastUser]; + + @override + String toString() => 'LoginLastUserLoaded: user: $lastUser'; +} + +class LoginInProgress extends LoginState {} + +class LoginSuccess extends LoginState {} + +class LoginFailure extends LoginState { + final String errorCode; + final String errorDescription; + + const LoginFailure( + {@required this.errorCode, @required this.errorDescription}); + + @override + List get props => [errorCode, errorDescription]; + + @override + String toString() => + 'LoginStateFailure: errorCode: $errorCode, errorDescription: $errorDescription'; +} diff --git a/video_call/lib/login/login.dart b/video_call/lib/login/login.dart new file mode 100644 index 0000000..267869a --- /dev/null +++ b/video_call/lib/login/login.dart @@ -0,0 +1,5 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'login_form.dart'; +export 'login_page.dart'; +export 'bloc/bloc.dart'; diff --git a/video_call/lib/login/login_form.dart b/video_call/lib/login/login_form.dart new file mode 100644 index 0000000..d3212b7 --- /dev/null +++ b/video_call/lib/login/login_form.dart @@ -0,0 +1,139 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:video_call/login/login.dart'; +import 'package:video_call/routes.dart'; +import 'package:video_call/theme/voximplant_theme.dart'; +import 'package:video_call/widgets/widgets.dart'; + +class LoginForm extends StatefulWidget { + @override + State createState() { + return _LoginFormState(); + } +} + +class _LoginFormState extends State { + final _usernameController = TextEditingController(); + final _passwordController = TextEditingController(); + final _formKey = GlobalKey(); + + bool _isUsernameValid = true; + bool _isPasswordValid = true; + + @override + void initState() { + super.initState(); + BlocProvider.of(context).add(LoadLastUser()); + } + + @override + void dispose() { + _usernameController.dispose(); + _passwordController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + void _login() { + BlocProvider.of(context).add(LoginWithPassword( + username: _usernameController.text, + password: _passwordController.text)); + } + + void _handleLoginFailed(String errorCode, String errorDescription) { + if (errorCode == 'ERROR_INVALID_USERNAME') { + setState(() { + _isUsernameValid = false; + }); + } else if (errorCode == 'ERROR_INVALID_PASSWORD') { + setState(() { + _isPasswordValid = false; + }); + } else { + Scaffold.of(context).showSnackBar(SnackBar( + content: Text('$errorDescription'), + backgroundColor: Colors.red, + )); + } + } + + Widget _loginForm() { + return Center( + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Widgets.textWithPadding( + text: 'Video call', + fontSize: 30, + textColor: VoximplantColors.white, + verticalPadding: 30, + ), + Widgets.textFormField( + controller: _usernameController, + darkBackground: true, + labelText: 'user@app.account', + suffixText: '.voximplant.com', + inputType: TextInputType.emailAddress, + validator: (_) { + return _isUsernameValid ? null : 'Invalid username'; + }), + Widgets.textFormField( + controller: _passwordController, + darkBackground: true, + labelText: 'password', + obscureText: true, + validator: (_) { + return _isPasswordValid ? null : 'Invalid password'; + }), + Widgets.maxWidthRaisedButton( + text: 'Log in', + onPressed: _login, + ), + ], + ))); + } + + Widget _loginInProgress() { + return Center( + child: CircularProgressIndicator(), + ); + } + + return BlocListener( + listener: (context, state) { + if (state is LoginLastUserLoaded) { + _usernameController.text = state.lastUser; + } + if (state is LoginFailure) { + _handleLoginFailed(state.errorCode, state.errorDescription); + } + if (state is LoginSuccess) { + setState(() { + _isUsernameValid = true; + _isPasswordValid = true; + }); + Navigator.of(context).pushReplacementNamed(AppRoutes.makeCall); + } + if (state is! LoginInProgress && state is! LoginSuccess) { + Future.delayed(Duration(milliseconds: 100), + () => _formKey?.currentState?.validate()); + } + }, + child: BlocBuilder( + builder: (context, state) { + if (state is LoginInProgress || state is LoginSuccess) { + return _loginInProgress(); + } else { + return _loginForm(); + } + }, + ), + ); + } +} diff --git a/video_call/lib/login/login_page.dart b/video_call/lib/login/login_page.dart new file mode 100644 index 0000000..135f57a --- /dev/null +++ b/video_call/lib/login/login_page.dart @@ -0,0 +1,17 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter/material.dart'; +import 'package:video_call/login/login.dart'; +import 'package:video_call/theme/voximplant_theme.dart'; + +class LoginPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: VoximplantColors.primary, + body: SafeArea( + child: LoginForm(), + ), + ); + } +} diff --git a/video_call/lib/main.dart b/video_call/lib/main.dart new file mode 100644 index 0000000..85f37da --- /dev/null +++ b/video_call/lib/main.dart @@ -0,0 +1,99 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_voximplant/flutter_voximplant.dart'; +import 'package:video_call/active_call/active_call.dart'; +import 'package:video_call/incoming_call/incoming_call.dart'; +import 'package:video_call/login/login.dart'; +import 'package:video_call/make_call/make_call.dart'; +import 'package:video_call/routes.dart'; +import 'package:video_call/services/auth_service.dart'; +import 'package:video_call/services/call_service.dart'; +import 'package:video_call/theme/voximplant_theme.dart'; + +import 'call_failed/call_failed_page.dart'; + +class SimpleBlocDelegate extends BlocDelegate { + @override + void onEvent(Bloc bloc, Object event) { + super.onEvent(bloc, event); + print(event); + } + + @override + void onTransition(Bloc bloc, Transition transition) { + super.onTransition(bloc, transition); + print(transition); + } + + @override + void onError(Bloc bloc, Object error, StackTrace stacktrace) { + super.onError(bloc, error, stacktrace); + print(error); + } +} + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + BlocSupervisor.delegate = SimpleBlocDelegate(); + + VIClientConfig clientConfig = VIClientConfig(); + VIClient client = Voximplant().getClient(clientConfig); + final AuthService authService = AuthService(client); + final CallService callService = CallService(client); + + runApp( + App(authService: authService, callService: callService), + ); +} + +class App extends StatelessWidget { + final AuthService authService; + final CallService callService; + + App({Key key, @required this.authService, @required this.callService}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData( + primaryColor: VoximplantColors.primary, + primaryColorDark: VoximplantColors.primaryDark, + accentColor: VoximplantColors.accent, + ), + initialRoute: AppRoutes.login, + routes: { + AppRoutes.login: (context) { + return BlocProvider( + create: (context) => LoginBloc(authService: authService), + child: LoginPage(), + ); + }, + AppRoutes.makeCall: (context) { + return BlocProvider( + create: (context) => MakeCallBloc( + authService: authService, callService: callService), + child: MakeCallPage(), + ); + }, + AppRoutes.activeCall: (context) { + return BlocProvider( + create: (context) => ActiveCallBloc( + authService: authService, callService: callService), + child: ActiveCallPage(), + ); + }, + AppRoutes.incomingCall: (context) { + return BlocProvider( + create: (context) => IncomingCallBloc( + authService: authService, callService: callService) + ..add(Load()), + child: IncomingCallPage(), + ); + }, + AppRoutes.callFailed: (context) => CallFailedPage(), + }); + } +} diff --git a/video_call/lib/make_call/bloc/bloc.dart b/video_call/lib/make_call/bloc/bloc.dart new file mode 100644 index 0000000..fb59f32 --- /dev/null +++ b/video_call/lib/make_call/bloc/bloc.dart @@ -0,0 +1,5 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'make_call_bloc.dart'; +export 'make_call_event.dart'; +export 'make_call_state.dart'; diff --git a/video_call/lib/make_call/bloc/make_call_bloc.dart b/video_call/lib/make_call/bloc/make_call_bloc.dart new file mode 100644 index 0000000..414c00b --- /dev/null +++ b/video_call/lib/make_call/bloc/make_call_bloc.dart @@ -0,0 +1,92 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'dart:io'; + +import 'package:bloc/bloc.dart'; +import 'package:flutter_voximplant/flutter_voximplant.dart'; +import 'package:meta/meta.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:video_call/make_call/make_call.dart'; +import 'package:video_call/services/auth_service.dart'; +import 'package:video_call/services/call_service.dart'; + +class MakeCallBloc extends Bloc { + final AuthService authService; + final CallService callService; + + MakeCallBloc({@required this.authService, @required this.callService}) { + callService.onIncomingCall = onIncomingCall; + authService.onDisconnected = onConnectionClosed; + } + + @override + MakeCallState get initialState => + MakeCallInitial(displayName: authService.displayName); + + void onIncomingCall(String callId, String caller) { + add(ReceivedIncomingCall(callId: callId, caller: caller)); + } + + void onConnectionClosed() { + add(ConnectionClosed()); + } + + Stream _checkPermissions() async* { + if (Platform.isAndroid) { + PermissionStatus recordAudio = await PermissionHandler() + .checkPermissionStatus(PermissionGroup.microphone); + PermissionStatus camera = await PermissionHandler() + .checkPermissionStatus(PermissionGroup.camera); + List requestPermissions = List(); + if (recordAudio != PermissionStatus.granted) { + requestPermissions.add(PermissionGroup.microphone); + } + if (camera != PermissionStatus.granted) { + requestPermissions.add(PermissionGroup.camera); + } + if (requestPermissions.isEmpty) { + yield PermissionCheckSuccess(displayName: authService.displayName); + } else { + Map result = + await PermissionHandler().requestPermissions(requestPermissions); + if (result[PermissionGroup.microphone] != PermissionStatus.granted || + result[PermissionGroup.camera] != PermissionStatus.granted) { + yield PermissionCheckFail(displayName: authService.displayName); + } else { + yield PermissionCheckSuccess(displayName: authService.displayName); + } + } + } else if (Platform.isIOS) { + yield PermissionCheckSuccess(displayName: authService.displayName); + } else { + //not supported platforms + yield PermissionCheckFail(displayName: authService.displayName); + } + } + + @override + Stream mapEventToState(MakeCallEvent event) async* { + if (event is CheckPermissionsForCall) { + yield* _checkPermissions(); + } + if (event is LogOut) { + await authService.logout(); + yield LoggedOut(networkIssues: false); + } + if (event is ReceivedIncomingCall) { + yield IncomingCall(caller: event.caller); + } + if (event is ConnectionClosed) { + yield LoggedOut(networkIssues: true); + } + if (event is Reconnect) { + try { + await authService.loginWithAccessToken(); + yield ReconnectSuccess(displayName: authService.displayName); + } on VIException { + authService.onDisconnected = null; + yield ReconnectFailed(); + } + } + } +} diff --git a/video_call/lib/make_call/bloc/make_call_event.dart b/video_call/lib/make_call/bloc/make_call_event.dart new file mode 100644 index 0000000..fc21c10 --- /dev/null +++ b/video_call/lib/make_call/bloc/make_call_event.dart @@ -0,0 +1,29 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:meta/meta.dart'; +import 'package:equatable/equatable.dart'; + +abstract class MakeCallEvent extends Equatable { + const MakeCallEvent(); + + @override + List get props => []; +} + +class CheckPermissionsForCall extends MakeCallEvent {} + +class LogOut extends MakeCallEvent {} + +class ReceivedIncomingCall extends MakeCallEvent { + final String callId; + final String caller; + + ReceivedIncomingCall({@required this.callId, @required this.caller}); + + @override + List get props => [callId, caller]; +} + +class ConnectionClosed extends MakeCallEvent {} + +class Reconnect extends MakeCallEvent {} diff --git a/video_call/lib/make_call/bloc/make_call_state.dart b/video_call/lib/make_call/bloc/make_call_state.dart new file mode 100644 index 0000000..8c9ed25 --- /dev/null +++ b/video_call/lib/make_call/bloc/make_call_state.dart @@ -0,0 +1,48 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:equatable/equatable.dart'; +import 'package:meta/meta.dart'; + +abstract class MakeCallState extends Equatable { + final String displayName; + + const MakeCallState(this.displayName); + + @override + List get props => [displayName]; +} + +class MakeCallInitial extends MakeCallState { + const MakeCallInitial({@required String displayName}) : super(displayName); + + @override + String toString() => 'OutgoingCallInitial: displayName: $displayName'; +} + +class PermissionCheckFail extends MakeCallState { + const PermissionCheckFail({@required String displayName}) + : super(displayName); +} + +class PermissionCheckSuccess extends MakeCallState { + const PermissionCheckSuccess({@required String displayName}) + : super(displayName); +} + +class LoggedOut extends MakeCallState { + final bool networkIssues; + const LoggedOut({@required this.networkIssues}) : super(null); +} + +class IncomingCall extends MakeCallState { + final String caller; + const IncomingCall({@required this.caller}) : super(null); +} + +class ReconnectSuccess extends MakeCallState { + const ReconnectSuccess({@required String displayName}) : super(displayName); +} + +class ReconnectFailed extends MakeCallState { + const ReconnectFailed() : super(null); +} diff --git a/video_call/lib/make_call/make_call.dart b/video_call/lib/make_call/make_call.dart new file mode 100644 index 0000000..1458446 --- /dev/null +++ b/video_call/lib/make_call/make_call.dart @@ -0,0 +1,4 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +export 'make_call_page.dart'; +export 'bloc/bloc.dart'; diff --git a/video_call/lib/make_call/make_call_page.dart b/video_call/lib/make_call/make_call_page.dart new file mode 100644 index 0000000..ee34733 --- /dev/null +++ b/video_call/lib/make_call/make_call_page.dart @@ -0,0 +1,142 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:video_call/active_call/active_call.dart'; +import 'package:video_call/incoming_call/incoming_call.dart'; +import 'package:video_call/routes.dart'; +import 'package:video_call/widgets/widgets.dart'; + +import 'bloc/make_call_bloc.dart'; +import 'bloc/make_call_event.dart'; +import 'bloc/make_call_state.dart'; + +class MakeCallPage extends StatefulWidget { + MakeCallPage({Key key}) : super(key: key); + + @override + State createState() { + return _MakeCallPageState(); + } +} + +class _MakeCallPageState extends State { + final _callToController = TextEditingController(); + + @override + void dispose() { + _callToController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + void _makeVideoCall() { + BlocProvider.of(context).add(CheckPermissionsForCall()); + } + + void _logout() { + BlocProvider.of(context).add(LogOut()); + } + + void _showPermissionCheckError() { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Permissions missing'), + content: Text( + 'Please give "record audio" and "camera" permissions to make calls'), + actions: [ + FlatButton( + child: Text('Close'), + onPressed: () { + Navigator.of(context).pop(); + }, + ) + ], + ); + }, + ); + } + + return BlocListener( + listener: (context, state) { + if (state is LoggedOut) { + if (state.networkIssues) { + BlocProvider.of(context).add(Reconnect()); + } else { + Navigator.of(context).pushReplacementNamed(AppRoutes.login); + } + } + if (state is PermissionCheckSuccess) { + Navigator.of(context).pushReplacementNamed( + AppRoutes.activeCall, + arguments: ActiveCallPageArguments( + isIncoming: false, callTo: _callToController.text), + ); + } + if (state is PermissionCheckFailed) { + _showPermissionCheckError(); + } + if (state is IncomingCall) { + Navigator.of(context).pushReplacementNamed( + AppRoutes.incomingCall, + arguments: IncomingCallPageArguments(caller: state.caller), + ); + } + if (state is ReconnectFailed) { + Navigator.of(context).pushReplacementNamed(AppRoutes.login); + } + }, + child: BlocBuilder( + builder: (context, state) { + return Scaffold( + appBar: AppBar( + title: Text('Voximplant'), + actions: [ + IconButton( + icon: Icon(Icons.exit_to_app), + onPressed: _logout, + ) + ], + ), + body: SafeArea( + child: Stack( + children: [ + Center( + child: Form( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Widgets.textFormField( + controller: _callToController, + darkBackground: false, + labelText: 'user or number'), + Widgets.maxWidthRaisedButton( + text: 'Video call', + onPressed: _makeVideoCall, + ), + ], + ), + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: EdgeInsets.only(bottom: 20), + child: Text( + 'Logged in as ${state.displayName}', + ), + ), + ), + ], + ), + ), + ); + }, + ), + ); + } +} diff --git a/video_call/lib/routes.dart b/video_call/lib/routes.dart new file mode 100644 index 0000000..26771a8 --- /dev/null +++ b/video_call/lib/routes.dart @@ -0,0 +1,9 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +class AppRoutes { + static final String login = '/login'; + static final String makeCall = '/makeCall'; + static final String incomingCall = '/incomingCall'; + static final String activeCall = '/activeCall'; + static final String callFailed = '/callFailed'; +} diff --git a/video_call/lib/services/auth_service.dart b/video_call/lib/services/auth_service.dart new file mode 100644 index 0000000..f6d6984 --- /dev/null +++ b/video_call/lib/services/auth_service.dart @@ -0,0 +1,95 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter_voximplant/flutter_voximplant.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +typedef void Disconnected(); + +class AuthService { + VIClient _client; + String _displayName; + + String get displayName => _displayName; + Disconnected onDisconnected; + + AuthService(VIClient client) { + _client = client; + _client.clientStateStream.listen((state) { + print('AuthService: client state is changed: $state'); + if (state == VIClientState.Disconnected && onDisconnected != null) { + onDisconnected(); + } + }); + } + + Future loginWithPassword(String username, String password) async { + print('AuthService: loginWithPassword'); + VIClientState clientState = await _client.getClientState(); + if (clientState == VIClientState.LoggedIn) { + return _displayName; + } + if (clientState == VIClientState.Disconnected) { + await _client.connect(); + } + VIAuthResult authResult = await _client.login(username, password); + await _saveAuthDetails(username, authResult.loginTokens); + _displayName = authResult.displayName; + return _displayName; + } + + Future loginWithAccessToken([String username]) async { + print('AuthService: loginWithAccessToken'); + VIClientState clientState = await _client.getClientState(); + if (clientState == VIClientState.LoggedIn) { + return _displayName; + } + if (clientState == VIClientState.Disconnected) { + await _client.connect(); + } + SharedPreferences prefs = await SharedPreferences.getInstance(); + VILoginTokens loginTokens = _getAuthDetails(prefs); + String user = username ?? prefs.getString('username'); + + VIAuthResult authResult = + await _client.loginWithAccessToken(user, loginTokens.accessToken); + await _saveAuthDetails(user, authResult.loginTokens); + _displayName = authResult.displayName; + return _displayName; + } + + Future logout() async { + await _client.disconnect(); + VILoginTokens loginTokens = VILoginTokens(); + _saveAuthDetails(null, loginTokens); + } + + Future getUsername() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + return prefs.getString('username')?.replaceAll('.voximplant.com', ''); + } + + Future canUseAccessToken() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + return prefs.getString('accessToken') != null; + } + + Future _saveAuthDetails( + String username, VILoginTokens loginTokens) async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('username', username); + prefs.setString('accessToken', loginTokens.accessToken); + prefs.setString('refreshToken', loginTokens.refreshToken); + prefs.setInt('accessExpire', loginTokens.accessExpire); + prefs.setInt('refreshExpire', loginTokens.refreshExpire); + } + + VILoginTokens _getAuthDetails(SharedPreferences prefs) { + VILoginTokens loginTokens = VILoginTokens(); + loginTokens.accessToken = prefs.getString('accessToken'); + loginTokens.accessExpire = prefs.getInt('accessExpire'); + loginTokens.refreshExpire = prefs.getInt('refreshExpire'); + loginTokens.refreshToken = prefs.getString('refreshToken'); + + return loginTokens; + } +} diff --git a/video_call/lib/services/call_service.dart b/video_call/lib/services/call_service.dart new file mode 100644 index 0000000..5c62266 --- /dev/null +++ b/video_call/lib/services/call_service.dart @@ -0,0 +1,189 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'dart:async'; + +import 'package:meta/meta.dart'; +import 'package:flutter_voximplant/flutter_voximplant.dart'; + +import 'call_state.dart'; + +typedef void OnIncomingCall(String callId, String caller); + +class CallService { + final VIClient _client; + VICall _activeCall; + StreamController _activeStreamController; + OnIncomingCall onIncomingCall; + + String get activeCallId => _activeCall?.callId; + + CallService(this._client) { + _client.onIncomingCall = _onIncomingCall; + } + + Stream subscribeToCallStateChanges(String callId) { + if (_activeCall.callId == callId) { + _activeStreamController?.close(); + _activeStreamController = StreamController.broadcast(); + return _activeStreamController.stream; + } + return null; + } + + Future makeVideoCall({@required String callTo}) async { + if (_activeCall != null) { + throw 'There is already an active call'; + } + VICallSettings callSettings = VICallSettings(); + callSettings.videoFlags = VIVideoFlags(receiveVideo: true, sendVideo: true); + callSettings.preferredVideoCodec = VIVideoCodec.VP8; + _activeCall = await _client.call(callTo, callSettings); + _listenToActiveCallEvents(); + return _activeCall.callId; + } + + Future answerVideoCall() async { + if (_activeCall == null) { + throw 'No active call'; + } + VICallSettings callSettings = VICallSettings(); + callSettings.videoFlags = VIVideoFlags(receiveVideo: true, sendVideo: true); + callSettings.preferredVideoCodec = VIVideoCodec.VP8; + await _activeCall.answer(callSettings); + return _activeCall.callId; + } + + Future endCall(String callId) async { + if (_activeCall.callId == callId) { + await _activeCall.hangup(); + } + } + + Future declineCall(String callId) async { + if (_activeCall.callId == callId) { + await _activeCall.decline(); + } + } + + Future holdCall(String callId, bool doHold) async { + if (_activeCall.callId == callId) { + return _activeCall.hold(doHold); + } else { + throw 'No active call'; + } + } + + Future sendVideo(String callId, bool doSendVideo) async { + if (_activeCall.callId == callId) { + await _activeCall.sendVideo(doSendVideo); + } else { + throw 'No active call'; + } + } + + void _onIncomingCall(VIClient client, VICall call, bool video, + Map headers) async { + if (_activeCall != null) { + await call.decline(); + return; + } + if (onIncomingCall != null) { + _activeCall = call; + _listenToActiveCallEvents(); + onIncomingCall( + _activeCall.callId, _activeCall.endpoints?.first?.displayName); + } + } + + void _listenToActiveCallEvents() { + _activeCall.onCallRinging = _onCallRinging; + _activeCall.onCallConnected = _onCallConnected; + _activeCall.onCallDisconnected = _onCallDisconnected; + _activeCall.onCallFailed = _onCallFailed; + _activeCall.onLocalVideoStreamAdded = _onLocalVideoStreamAdded; + _activeCall.onLocalVideoStreamRemoved = _onLocalVideoStreamRemoved; + _activeCall.onEndpointAdded = _onEndpointAdded; + } + + void _listenToEndpointEvents() { + _activeCall.endpoints?.first?.onRemoteVideoStreamAdded = + _onRemoteVideoStreamAdded; + _activeCall.endpoints?.first?.onRemoteVideoStreamRemoved = + _onRemoteVideoStreamRemoved; + } + + void _onCallDisconnected( + VICall call, Map headers, bool answeredElsewhere) { + if (call.callId == _activeCall.callId) { + print('CallService: onCallDisconnected($headers, $answeredElsewhere)'); + _activeStreamController.add(CallStateDisconnected()); + _activeCall = null; + } + } + + void _onCallFailed( + VICall call, int code, String description, Map headers) { + if (call.callId == _activeCall.callId) { + print('CallService: onCallFailed($code, $description, $headers)'); + _activeStreamController.add(CallStateFailed( + errorDescription: description, + endpoint: _activeCall.endpoints?.first?.displayName)); + _activeCall = null; + } + } + + void _onCallConnected(VICall call, Map headers) { + if (call.callId == _activeCall.callId) { + print('CallService: onCallConnected($headers)'); + _activeStreamController.add(CallStateConnected()); + } + } + + void _onCallRinging(VICall call, Map headers) { + if (call.callId == _activeCall.callId) { + print('CallService: onCallRinging($headers)'); + _activeStreamController.add(CallStateRinging()); + } + } + + void _onEndpointAdded(VICall call, VIEndpoint endpoint) { + if (call.callId == _activeCall.callId) { + print('CallService: onEndpointAdded($endpoint)'); + _listenToEndpointEvents(); + } + } + + void _onLocalVideoStreamAdded(VICall call, VIVideoStream videoStream) { + if (call.callId == _activeCall.callId) { + print( + 'CallService: onLocalVideoStreamAdded: ${videoStream.streamId}'); + _activeStreamController.add(CallStateVideoStreamAdded( + streamId: videoStream.streamId, isLocal: true)); + } + } + + void _onLocalVideoStreamRemoved(VICall call, VIVideoStream videoStream) { + if (call.callId == _activeCall.callId) { + print( + 'CallService: onLocalVideoStreamRemoved: ${videoStream.streamId}'); + _activeStreamController.add(CallStateVideoStreamRemoved( + streamId: videoStream.streamId, isLocal: true)); + } + } + + void _onRemoteVideoStreamAdded( + VIEndpoint endpoint, VIVideoStream videoStream) { + print( + 'CallService: onRemoteVideoStreamAdded: ${videoStream.streamId}'); + _activeStreamController.add(CallStateVideoStreamAdded( + streamId: videoStream.streamId, isLocal: false)); + } + + void _onRemoteVideoStreamRemoved( + VIEndpoint endpoint, VIVideoStream videoStream) { + print( + 'CallService: onRemoteVideoStreamRemoved: ${videoStream.streamId}'); + _activeStreamController.add(CallStateVideoStreamRemoved( + streamId: videoStream.streamId, isLocal: false)); + } +} diff --git a/video_call/lib/services/call_state.dart b/video_call/lib/services/call_state.dart new file mode 100644 index 0000000..b53fd25 --- /dev/null +++ b/video_call/lib/services/call_state.dart @@ -0,0 +1,33 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:meta/meta.dart'; + +abstract class CallState { + const CallState(); +} + +class CallStateRinging extends CallState {} + +class CallStateConnected extends CallState {} + +class CallStateFailed extends CallState { + final String errorDescription; + final String endpoint; + const CallStateFailed( + {@required this.errorDescription, @required this.endpoint}); +} + +class CallStateVideoStreamAdded extends CallState { + final String streamId; + final bool isLocal; + CallStateVideoStreamAdded({@required this.streamId, @required this.isLocal}); +} + +class CallStateVideoStreamRemoved extends CallState { + final String streamId; + final bool isLocal; + CallStateVideoStreamRemoved( + {@required this.streamId, @required this.isLocal}); +} + +class CallStateDisconnected extends CallState {} diff --git a/video_call/lib/theme/voximplant_theme.dart b/video_call/lib/theme/voximplant_theme.dart new file mode 100644 index 0000000..3623279 --- /dev/null +++ b/video_call/lib/theme/voximplant_theme.dart @@ -0,0 +1,13 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter/material.dart'; + +class VoximplantColors { + static const Color primary = const Color(0xff1c0b43); + static const Color primaryDark = const Color(0xff392b5b); + static const Color accent = const Color(0xff8b61ff); + static const Color button = const Color(0xff662eff); + static const Color white = const Color(0xffffffff); + static const Color red = const Color(0xfff54b5e); + static const Color grey = const Color(0xff212121); +} diff --git a/video_call/lib/widgets/widgets.dart b/video_call/lib/widgets/widgets.dart new file mode 100644 index 0000000..3014f38 --- /dev/null +++ b/video_call/lib/widgets/widgets.dart @@ -0,0 +1,106 @@ +/// Copyright (c) 2011-2020, Zingaya, Inc. All rights reserved. + +import 'package:flutter/material.dart'; +import 'package:video_call/theme/voximplant_theme.dart'; + +class Widgets { + static Widget textFormField( + {@required TextEditingController controller, + @required bool darkBackground, + String labelText, + String suffixText, + bool obscureText = false, + TextInputType inputType = TextInputType.text, + FormFieldValidator validator}) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20), + child: Theme( + data: ThemeData( + primaryColor: + darkBackground ? VoximplantColors.white : VoximplantColors.button, + cursorColor: + darkBackground ? VoximplantColors.white : VoximplantColors.button, + hintColor: + darkBackground ? VoximplantColors.white : VoximplantColors.button, + ), + child: TextFormField( + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: BorderSide( + color: darkBackground + ? VoximplantColors.white + : VoximplantColors.button)), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: darkBackground + ? VoximplantColors.white + : VoximplantColors.button)), + labelText: labelText, + suffixText: suffixText), + keyboardType: inputType, + controller: controller, + autocorrect: false, + obscureText: obscureText, + style: + TextStyle(color: darkBackground ? VoximplantColors.white : null), + validator: validator, + ), + ), + ); + } + + static Widget maxWidthRaisedButton( + {@required String text, @required VoidCallback onPressed}) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20), + child: SizedBox( + width: double.infinity, + height: 50, + child: RaisedButton( + textColor: VoximplantColors.white, + color: VoximplantColors.button, + onPressed: onPressed, + child: Text(text), + ), + ), + ); + } + + static Widget textWithPadding( + {@required String text, + Color textColor, + double fontSize, + double verticalPadding = 0.0, + double horizontalPadding = 0.0}) { + return Padding( + padding: EdgeInsets.symmetric( + vertical: verticalPadding, horizontal: horizontalPadding), + child: Text( + text, + style: TextStyle(color: textColor, fontSize: fontSize), + ), + ); + } + + static Widget iconButton( + {@required IconData icon, + @required Color color, + @required String tooltip, + @required VoidCallback onPressed}) { + return Ink( + decoration: ShapeDecoration( + color: VoximplantColors.white, + shape: CircleBorder(), + ), + child: IconButton( + onPressed: onPressed, + iconSize: 40, + icon: Icon( + icon, + color: color, + ), + tooltip: tooltip, + ), + ); + } +} diff --git a/video_call/pubspec.lock b/video_call/pubspec.lock new file mode 100644 index 0000000..adebd03 --- /dev/null +++ b/video_call/pubspec.lock @@ -0,0 +1,285 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.2" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" + bloc: + dependency: "direct main" + description: + name: bloc + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + equatable: + dependency: "direct main" + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_voximplant: + dependency: "direct main" + description: + name: flutter_voximplant + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.6" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.8" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.4" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0+1" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" + provider: + dependency: transitive + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.23.1" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.6" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+3" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2+2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.11" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "3.5.0" +sdks: + dart: ">=2.6.0 <3.0.0" + flutter: ">=1.12.13+hotfix.4 <2.0.0" diff --git a/video_call/pubspec.yaml b/video_call/pubspec.yaml new file mode 100644 index 0000000..0297f24 --- /dev/null +++ b/video_call/pubspec.yaml @@ -0,0 +1,39 @@ +name: video_call +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + bloc: 3.0.0 + flutter_bloc: 3.1.0 + equatable: 1.0.2 + flutter_voximplant: 2.0.0 + shared_preferences: 0.5.6 + permission_handler: 3.2.0 + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true + diff --git a/video_call/test/widget_test.dart b/video_call/test/widget_test.dart new file mode 100644 index 0000000..7a91322 --- /dev/null +++ b/video_call/test/widget_test.dart @@ -0,0 +1,35 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_voximplant/flutter_voximplant.dart'; + +import 'package:video_call/main.dart'; +import 'package:video_call/services/auth_service.dart'; +import 'package:video_call/services/call_service.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + VIClient client = Voximplant().getClient(); + await tester.pumpWidget(App( + authService: AuthService(client), callService: CallService(client))); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +}