From 0fceca8f3ec3054e6047d06a66b61f6e49e5f2ba Mon Sep 17 00:00:00 2001 From: jammal Date: Sun, 18 Oct 2020 11:43:12 +0300 Subject: [PATCH 1/2] fix ios issues --- ios/Podfile | 87 -- ios/Podfile.lock | 310 ----- .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 91 ++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + ios/Runner/AppDelegate.swift | 13 + ios/Runner/Info.plist | 12 +- ios/Runner/Runner-Bridging-Header.h | 1 + .../components/DocAvailableAppointments.dart | 2 +- .../Covid-DriveThru/Covid-TimeSlots.dart | 2 +- lib/pages/conference/conference_page.dart | 776 ++++++------ lib/pages/conference/conference_room.dart | 1042 ++++++++--------- lib/pages/landing/home_page.dart | 20 +- lib/pages/landing/landing_page.dart | 74 +- lib/pages/livecare/incoming_call.dart | 14 +- pubspec.yaml | 2 +- 19 files changed, 1120 insertions(+), 1365 deletions(-) delete mode 100644 ios/Podfile delete mode 100644 ios/Podfile.lock create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/Runner/AppDelegate.swift create mode 100644 ios/Runner/Runner-Bridging-Header.h diff --git a/ios/Podfile b/ios/Podfile deleted file mode 100644 index 9712eaff..00000000 --- a/ios/Podfile +++ /dev/null @@ -1,87 +0,0 @@ -# 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 - use_frameworks! - use_modular_headers! - - # 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 - -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/ios/Podfile.lock b/ios/Podfile.lock deleted file mode 100644 index 005fe83c..00000000 --- a/ios/Podfile.lock +++ /dev/null @@ -1,310 +0,0 @@ -PODS: - - barcode_scan (0.0.1): - - Flutter - - MTBBarcodeScanner - - SwiftProtobuf - - connectivity (0.0.1): - - Flutter - - Reachability - - connectivity_for_web (0.1.0): - - Flutter - - connectivity_macos (0.0.1): - - Flutter - - device_info (0.0.1): - - Flutter - - Firebase/Core (6.23.0): - - Firebase/CoreOnly - - FirebaseAnalytics (= 6.4.2) - - Firebase/CoreOnly (6.23.0): - - FirebaseCore (= 6.6.7) - - Firebase/Messaging (6.23.0): - - Firebase/CoreOnly - - FirebaseMessaging (~> 4.3.1) - - firebase_messaging (0.0.1): - - Firebase/Core - - Firebase/Messaging - - Flutter - - FirebaseAnalytics (6.4.2): - - FirebaseCore (~> 6.6) - - FirebaseInstallations (~> 1.2) - - GoogleAppMeasurement (= 6.4.2) - - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - - GoogleUtilities/MethodSwizzler (~> 6.0) - - GoogleUtilities/Network (~> 6.0) - - "GoogleUtilities/NSData+zlib (~> 6.0)" - - nanopb (= 0.3.9011) - - FirebaseAnalyticsInterop (1.5.0) - - FirebaseCore (6.6.7): - - FirebaseCoreDiagnostics (~> 1.2) - - FirebaseCoreDiagnosticsInterop (~> 1.2) - - GoogleUtilities/Environment (~> 6.5) - - GoogleUtilities/Logger (~> 6.5) - - FirebaseCoreDiagnostics (1.2.4): - - FirebaseCoreDiagnosticsInterop (~> 1.2) - - GoogleDataTransportCCTSupport (~> 3.0) - - GoogleUtilities/Environment (~> 6.5) - - GoogleUtilities/Logger (~> 6.5) - - nanopb (~> 0.3.901) - - FirebaseCoreDiagnosticsInterop (1.2.0) - - FirebaseInstallations (1.2.0): - - FirebaseCore (~> 6.6) - - GoogleUtilities/Environment (~> 6.6) - - GoogleUtilities/UserDefaults (~> 6.6) - - PromisesObjC (~> 1.2) - - FirebaseInstanceID (4.3.4): - - FirebaseCore (~> 6.6) - - FirebaseInstallations (~> 1.0) - - GoogleUtilities/Environment (~> 6.5) - - GoogleUtilities/UserDefaults (~> 6.5) - - FirebaseMessaging (4.3.1): - - 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_flexible_toast (0.0.1): - - Flutter - - flutter_inappwebview (0.0.1): - - Flutter - - flutter_local_notifications (0.0.1): - - Flutter - - flutter_plugin_android_lifecycle (0.0.1): - - Flutter - - GoogleAppMeasurement (6.4.2): - - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - - GoogleUtilities/MethodSwizzler (~> 6.0) - - GoogleUtilities/Network (~> 6.0) - - "GoogleUtilities/NSData+zlib (~> 6.0)" - - nanopb (= 0.3.9011) - - GoogleDataTransport (6.0.0) - - GoogleDataTransportCCTSupport (3.0.0): - - GoogleDataTransport (~> 6.0) - - nanopb (~> 0.3.901) - - GoogleUtilities/AppDelegateSwizzler (6.6.0): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (6.6.0): - - PromisesObjC (~> 1.2) - - GoogleUtilities/Logger (6.6.0): - - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.6.0): - - GoogleUtilities/Logger - - GoogleUtilities/Network (6.6.0): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.6.0)" - - GoogleUtilities/Reachability (6.6.0): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.6.0): - - GoogleUtilities/Logger - - hexcolor (0.0.1): - - Flutter - - image_cropper (0.0.2): - - Flutter - - TOCropViewController (~> 2.5.2) - - image_picker (0.0.1): - - Flutter - - local_auth (0.0.1): - - Flutter - - manage_calendar_events (0.0.1): - - Flutter - - map_launcher (0.0.1): - - Flutter - - MTBBarcodeScanner (5.0.11) - - nanopb (0.3.9011): - - nanopb/decode (= 0.3.9011) - - nanopb/encode (= 0.3.9011) - - nanopb/decode (0.3.9011) - - nanopb/encode (0.3.9011) - - path_provider_linux (0.0.1): - - Flutter - - "permission_handler (5.0.1+1)": - - Flutter - - PromisesObjC (1.2.8) - - Protobuf (3.11.4) - - Reachability (3.2) - - shared_preferences (0.0.1): - - Flutter - - shared_preferences_linux (0.0.1): - - Flutter - - shared_preferences_macos (0.0.1): - - Flutter - - shared_preferences_web (0.0.1): - - Flutter - - SwiftProtobuf (1.10.2) - - TOCropViewController (2.5.4) - - url_launcher (0.0.1): - - Flutter - - url_launcher_linux (0.0.1): - - Flutter - - url_launcher_macos (0.0.1): - - Flutter - - url_launcher_web (0.0.1): - - Flutter - -DEPENDENCIES: - - barcode_scan (from `.symlinks/plugins/barcode_scan/ios`) - - connectivity (from `.symlinks/plugins/connectivity/ios`) - - connectivity_for_web (from `.symlinks/plugins/connectivity_for_web/ios`) - - connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`) - - device_info (from `.symlinks/plugins/device_info/ios`) - - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - - Flutter (from `Flutter`) - - flutter_flexible_toast (from `.symlinks/plugins/flutter_flexible_toast/ios`) - - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) - - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - - flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`) - - hexcolor (from `.symlinks/plugins/hexcolor/ios`) - - image_cropper (from `.symlinks/plugins/image_cropper/ios`) - - image_picker (from `.symlinks/plugins/image_picker/ios`) - - local_auth (from `.symlinks/plugins/local_auth/ios`) - - manage_calendar_events (from `.symlinks/plugins/manage_calendar_events/ios`) - - map_launcher (from `.symlinks/plugins/map_launcher/ios`) - - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) - - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - - shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`) - - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`) - - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) - - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - - url_launcher_linux (from `.symlinks/plugins/url_launcher_linux/ios`) - - url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`) - - url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`) - -SPEC REPOS: - trunk: - - Firebase - - FirebaseAnalytics - - FirebaseAnalyticsInterop - - FirebaseCore - - FirebaseCoreDiagnostics - - FirebaseCoreDiagnosticsInterop - - FirebaseInstallations - - FirebaseInstanceID - - FirebaseMessaging - - GoogleAppMeasurement - - GoogleDataTransport - - GoogleDataTransportCCTSupport - - GoogleUtilities - - MTBBarcodeScanner - - nanopb - - PromisesObjC - - Protobuf - - Reachability - - SwiftProtobuf - - TOCropViewController - -EXTERNAL SOURCES: - barcode_scan: - :path: ".symlinks/plugins/barcode_scan/ios" - connectivity: - :path: ".symlinks/plugins/connectivity/ios" - connectivity_for_web: - :path: ".symlinks/plugins/connectivity_for_web/ios" - connectivity_macos: - :path: ".symlinks/plugins/connectivity_macos/ios" - device_info: - :path: ".symlinks/plugins/device_info/ios" - firebase_messaging: - :path: ".symlinks/plugins/firebase_messaging/ios" - Flutter: - :path: Flutter - flutter_flexible_toast: - :path: ".symlinks/plugins/flutter_flexible_toast/ios" - flutter_inappwebview: - :path: ".symlinks/plugins/flutter_inappwebview/ios" - flutter_local_notifications: - :path: ".symlinks/plugins/flutter_local_notifications/ios" - flutter_plugin_android_lifecycle: - :path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios" - hexcolor: - :path: ".symlinks/plugins/hexcolor/ios" - image_cropper: - :path: ".symlinks/plugins/image_cropper/ios" - image_picker: - :path: ".symlinks/plugins/image_picker/ios" - local_auth: - :path: ".symlinks/plugins/local_auth/ios" - manage_calendar_events: - :path: ".symlinks/plugins/manage_calendar_events/ios" - map_launcher: - :path: ".symlinks/plugins/map_launcher/ios" - path_provider_linux: - :path: ".symlinks/plugins/path_provider_linux/ios" - permission_handler: - :path: ".symlinks/plugins/permission_handler/ios" - shared_preferences: - :path: ".symlinks/plugins/shared_preferences/ios" - shared_preferences_linux: - :path: ".symlinks/plugins/shared_preferences_linux/ios" - shared_preferences_macos: - :path: ".symlinks/plugins/shared_preferences_macos/ios" - shared_preferences_web: - :path: ".symlinks/plugins/shared_preferences_web/ios" - url_launcher: - :path: ".symlinks/plugins/url_launcher/ios" - url_launcher_linux: - :path: ".symlinks/plugins/url_launcher_linux/ios" - url_launcher_macos: - :path: ".symlinks/plugins/url_launcher_macos/ios" - url_launcher_web: - :path: ".symlinks/plugins/url_launcher_web/ios" - -SPEC CHECKSUMS: - barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479 - connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 - connectivity_for_web: 2b8584556930d4bd490d82b836bcf45067ce345b - connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191 - device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 - Firebase: 585ae467b3edda6a5444e788fda6888f024d8d6f - firebase_messaging: 21344b3b3a7d9d325d63a70e3750c0c798fe1e03 - FirebaseAnalytics: 558f7a03d19de451093032c806f39d5f9dff096e - FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae - FirebaseCore: a2788a0d5f6c1dff17b8f79b4a73654a8d4bfdbd - FirebaseCoreDiagnostics: b59c024493a409f8aecba02c99928d0d8431d159 - FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850 - FirebaseInstallations: 2119fb3e46b0a88bfdbf12562f855ee3252462fa - FirebaseInstanceID: cef67c4967c7cecb56ea65d8acbb4834825c587b - FirebaseMessaging: 828e66eb357a893e3cebd9ee0f6bc1941447cc94 - Flutter: 0e3d915762c693b495b44d77113d4970485de6ec - flutter_flexible_toast: 0547e740cae0c33bb7c51bcd931233f4584e1143 - flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189 - flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 - flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 - GoogleAppMeasurement: 2253e99c1f22638cf234c059144660c338ad76c3 - GoogleDataTransport: 061fe7d9b476710e3cd8ea51e8e07d8b67c2b420 - GoogleDataTransportCCTSupport: 0f39025e8cf51f168711bd3fb773938d7e62ddb5 - GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1 - hexcolor: fdfb9c4258ad96e949c2dbcdf790a62194b8aa89 - image_cropper: 3c16d7651730ffe85897f5a1c4e2547e6b54989a - image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09 - local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd - manage_calendar_events: 0338d505ea26cdfd20cd883279bc28afa11eca34 - map_launcher: e325db1261d029ff33e08e03baccffe09593ffea - MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb - nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd - path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 - permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6 - PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6 - Protobuf: 176220c526ad8bd09ab1fb40a978eac3fef665f7 - Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 - shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d - shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78 - shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 - shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 - SwiftProtobuf: bec1ae7d686ff73dd09d79866154f4970b891410 - TOCropViewController: 2a1ae1242600b1f2d996fd91a5268b2309a33b5c - url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef - url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0 - url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313 - url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c - -PODFILE CHECKSUM: 2609452b760cd11039b14039a86564367a3d8ab9 - -COCOAPODS: 1.9.1 diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..f9b0d7c5 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..a28140cf --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..f9b0d7c5 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 00000000..70693e4a --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 792eb95e..da3b2626 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -22,12 +22,20 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS - NSCalendarsUsageDescription - We Need to access the calender to add reminder for you UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main + NSMicrophoneUsageDescription + Need microphone access for uploading videos + NSCameraUsageDescription + Need camera access for uploading images + NSLocationUsageDescription + Need location access for updating nearby friends + NSLocationWhenInUseUsageDescription + This app will use your location to show cool stuffs near you. + NSPhotoLibraryUsageDescription + Need photo library access for uploading images UISupportedInterfaceOrientations UIInterfaceOrientationPortrait diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 00000000..308a2a56 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart index 88116cd9..74cba568 100644 --- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart +++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart @@ -235,7 +235,7 @@ class _DocAvailableAppointmentsState extends State return children; }, ), - onDaySelected: (date, events) { + onDaySelected: (date, events,holidays) { _onDaySelected(date, events); _animationController.forward(from: 0.0); }, diff --git a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart index 060a8132..264f828a 100644 --- a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart +++ b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart @@ -348,7 +348,7 @@ class _CovidTimeSlotsState extends State return children; }, ), - onDaySelected: (date, events) { + onDaySelected: (date, events,holidays) { _onDaySelected(date, events); _animationController.forward(from: 0.0); }, diff --git a/lib/pages/conference/conference_page.dart b/lib/pages/conference/conference_page.dart index 7848d4f7..aec5d418 100644 --- a/lib/pages/conference/conference_page.dart +++ b/lib/pages/conference/conference_page.dart @@ -1,388 +1,388 @@ -import 'dart:async'; - -import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart'; -import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart'; -import 'package:diplomaticquarterapp/pages/conference/conference_room.dart'; -import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart'; -import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; -import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; -import 'package:diplomaticquarterapp/pages/conference/widgets/platform_alert_dialog.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:wakelock/wakelock.dart'; - -class ConferencePage extends StatefulWidget { - final RoomModel roomModel; - - const ConferencePage({Key key, this.roomModel}) : super(key: key); - - @override - _ConferencePageState createState() => _ConferencePageState(); -} - -class _ConferencePageState extends State { - final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); - final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); - ConferenceRoom _conferenceRoom; - StreamSubscription _onConferenceRoomException; - - @override - void initState() { - super.initState(); - _lockInPortrait(); - _connectToRoom(); - _wakeLock(true); - } - - void _connectToRoom() async { - try { - final conferenceRoom = ConferenceRoom( - name: widget.roomModel.name, - token: widget.roomModel.token, - identity: widget.roomModel.identity, - ); - await conferenceRoom.connect(); - setState(() { - _conferenceRoom = conferenceRoom; - _onConferenceRoomException = _conferenceRoom.onException.listen((err) async { - await PlatformAlertDialog( - title: err is PlatformException ? err.message : 'An error occured', - content: err is PlatformException ? err.details : err.toString(), - defaultActionText: 'OK', - ).show(context); - }); - _conferenceRoom.addListener(_conferenceRoomUpdated); - }); - } catch (err) { - print(err); - await PlatformAlertDialog( - title: err is PlatformException ? err.message : 'An error occured', - content: err is PlatformException ? err.details : err.toString(), - defaultActionText: 'OK', - ).show(context); - - Navigator.of(context).pop(); - } - } - - Future _lockInPortrait() async { - await SystemChrome.setPreferredOrientations([ - DeviceOrientation.portraitUp, - DeviceOrientation.portraitDown, - ]); - } - - @override - void dispose() { - _freePortraitLock(); - _wakeLock(false); - _disposeStreamsAndSubscriptions(); - if (_conferenceRoom != null) _conferenceRoom.removeListener(_conferenceRoomUpdated); - super.dispose(); - } - - Future _freePortraitLock() async { - await SystemChrome.setPreferredOrientations([ - DeviceOrientation.landscapeRight, - DeviceOrientation.landscapeLeft, - DeviceOrientation.portraitUp, - DeviceOrientation.portraitDown, - ]); - } - - Future _disposeStreamsAndSubscriptions() async { - if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); - if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); - if (_onConferenceRoomException != null) await _onConferenceRoomException.cancel(); - } - - @override - Widget build(BuildContext context) { - return WillPopScope( - onWillPop: () async => false, - child: Scaffold( - backgroundColor: Colors.black, - body: _conferenceRoom == null ? showProgress() : buildLayout(), - ), - ); - } - - LayoutBuilder buildLayout() { - return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return Stack( - children: [ - _buildParticipants(context, constraints.biggest, _conferenceRoom), - ConferenceButtonBar( - audioEnabled: _conferenceRoom.onAudioEnabled, - videoEnabled: _conferenceRoom.onVideoEnabled, - onAudioEnabled: _conferenceRoom.toggleAudioEnabled, - onVideoEnabled: _conferenceRoom.toggleVideoEnabled, - onHangup: _onHangup, - onSwitchCamera: _conferenceRoom.switchCamera, - onPersonAdd: _onPersonAdd, - onPersonRemove: _onPersonRemove, - onHeight: _onHeightBar, - onShow: _onShowBar, - onHide: _onHideBar, - ), - ], - ); - }, - ); - } - - Widget showProgress() { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Center(child: CircularProgressIndicator()), - SizedBox( - height: 10, - ), - Text( - 'Connecting to the call...', - style: TextStyle(color: Colors.white), - ), - ], - ); - } - - Future _onHangup() async { - print('onHangup'); - await _conferenceRoom.disconnect(); - Navigator.of(context).pop(); - } - - void _onPersonAdd() { - print('onPersonAdd'); - try { - _conferenceRoom.addDummy( - child: Stack( - children: [ - const Placeholder(), - Center( - child: Text( - (_conferenceRoom.participants.length + 1).toString(), - style: const TextStyle( - shadows: [ - Shadow( - blurRadius: 3.0, - color: Color.fromARGB(255, 0, 0, 0), - ), - Shadow( - blurRadius: 8.0, - color: Color.fromARGB(255, 255, 255, 255), - ), - ], - fontSize: 80, - ), - ), - ), - ], - ), - ); - } on PlatformException catch (err) { - PlatformAlertDialog( - title: err.message, - content: err.details, - defaultActionText: 'OK', - ).show(context); - } - } - - void _onPersonRemove() { - print('onPersonRemove'); - _conferenceRoom.removeDummy(); - } - - Widget _buildParticipants(BuildContext context, Size size, ConferenceRoom conferenceRoom) { - final children = []; - final length = conferenceRoom.participants.length; - - if (length <= 2) { - _buildOverlayLayout(context, size, children); - return Stack(children: children); - } - - void buildInCols(bool removeLocalBeforeChunking, bool moveLastOfEachRowToNextRow, int columns) { - _buildLayoutInGrid( - context, - size, - children, - removeLocalBeforeChunking: removeLocalBeforeChunking, - moveLastOfEachRowToNextRow: moveLastOfEachRowToNextRow, - columns: columns, - ); - } - -// if (length <= 3) { -// buildInCols(true, false, 1); -// } else if (length == 5) { -// buildInCols(false, true, 2); -// } else if (length <= 6 || length == 8) { -// buildInCols(false, false, 2); -// } else if (length == 7 || length == 9) { -// buildInCols(true, false, 2); -// } else if (length == 10) { -// buildInCols(false, true, 3); -// } else if (length == 13 || length == 16) { -// buildInCols(true, false, 3); -// } else if (length <= 18) { -// buildInCols(false, false, 3); -// } - - return Column( - children: children, - ); - } - - void _buildOverlayLayout(BuildContext context, Size size, List children) { - final participants = _conferenceRoom.participants; - if (participants.length == 1) { - children.add(_buildNoiseBox()); - } else { - final remoteParticipant = participants.firstWhere((ParticipantWidget participant) => participant.isRemote, orElse: () => null); - if (remoteParticipant != null) { - children.add(remoteParticipant); - } - } - - final localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); - if (localParticipant != null) { - children.add(DraggablePublisher( - key: Key('publisher'), - child: localParticipant, - availableScreenSize: size, - onButtonBarVisible: _onButtonBarVisibleStreamController.stream, - onButtonBarHeight: _onButtonBarHeightStreamController.stream, - )); - } - } - - void _buildLayoutInGrid( - BuildContext context, - Size size, - List children, { - bool removeLocalBeforeChunking = false, - bool moveLastOfEachRowToNextRow = false, - int columns = 2, - }) { - final participants = _conferenceRoom.participants; - ParticipantWidget localParticipant; - if (removeLocalBeforeChunking) { - localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); - if (localParticipant != null) { - participants.remove(localParticipant); - } - } - final chunkedParticipants = chunk(array: participants, size: columns); - if (localParticipant != null) { - chunkedParticipants.last.add(localParticipant); - participants.add(localParticipant); - } - - if (moveLastOfEachRowToNextRow) { - for (var i = 0; i < chunkedParticipants.length - 1; i++) { - var participant = chunkedParticipants[i].removeLast(); - chunkedParticipants[i + 1].insert(0, participant); - } - } - - for (final participantChunk in chunkedParticipants) { - final rowChildren = []; - for (final participant in participantChunk) { - rowChildren.add( - Container( - width: size.width / participantChunk.length, - height: size.height / chunkedParticipants.length, - child: participant, - ), - ); - } - children.add( - Container( - height: size.height / chunkedParticipants.length, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: rowChildren, - ), - ), - ); - } - } - - NoiseBox _buildNoiseBox() { - return NoiseBox( - density: NoiseBoxDensity.xLow, - backgroundColor: Colors.grey.shade900, - child: Center( - child: Container( - color: Colors.black54, - width: double.infinity, - height: 40, - child: Center( - child: Text( - 'Waiting for another participant to connect to the call...', - key: Key('text-wait'), - textAlign: TextAlign.center, - style: TextStyle(color: Colors.white), - ), - ), - ), - ), - ); - } - - List> chunk({@required List array, @required int size}) { - final result = >[]; - if (array.isEmpty || size <= 0) { - return result; - } - var first = 0; - var last = size; - final totalLoop = array.length % size == 0 ? array.length ~/ size : array.length ~/ size + 1; - for (var i = 0; i < totalLoop; i++) { - if (last > array.length) { - result.add(array.sublist(first, array.length)); - } else { - result.add(array.sublist(first, last)); - } - first = last; - last = last + size; - } - return result; - } - - void _onHeightBar(double height) { - _onButtonBarHeightStreamController.add(height); - } - - void _onShowBar() { - setState(() { - SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]); - }); - _onButtonBarVisibleStreamController.add(true); - } - - void _onHideBar() { - setState(() { - SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); - }); - _onButtonBarVisibleStreamController.add(false); - } - - Future _wakeLock(bool enable) async { - try { - return await (enable ? Wakelock.enable() : Wakelock.disable()); - } catch (err) { - print('Unable to change the Wakelock and set it to $enable'); - print(err); - } - } - - void _conferenceRoomUpdated() { - setState(() {}); - } -} +// import 'dart:async'; +// +// import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart'; +// import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart'; +// import 'package:diplomaticquarterapp/pages/conference/conference_room.dart'; +// import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart'; +// import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; +// import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; +// import 'package:diplomaticquarterapp/pages/conference/widgets/platform_alert_dialog.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'package:wakelock/wakelock.dart'; +// +// class ConferencePage extends StatefulWidget { +// final RoomModel roomModel; +// +// const ConferencePage({Key key, this.roomModel}) : super(key: key); +// +// @override +// _ConferencePageState createState() => _ConferencePageState(); +// } +// +// class _ConferencePageState extends State { +// final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); +// final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); +// ConferenceRoom _conferenceRoom; +// StreamSubscription _onConferenceRoomException; +// +// @override +// void initState() { +// super.initState(); +// _lockInPortrait(); +// // _connectToRoom(); +// _wakeLock(true); +// } +// +// // void _connectToRoom() async { +// // try { +// // final conferenceRoom = ConferenceRoom( +// // name: widget.roomModel.name, +// // token: widget.roomModel.token, +// // identity: widget.roomModel.identity, +// // ); +// // await conferenceRoom.connect(); +// // setState(() { +// // _conferenceRoom = conferenceRoom; +// // _onConferenceRoomException = _conferenceRoom.onException.listen((err) async { +// // await PlatformAlertDialog( +// // title: err is PlatformException ? err.message : 'An error occured', +// // content: err is PlatformException ? err.details : err.toString(), +// // defaultActionText: 'OK', +// // ).show(context); +// // }); +// // _conferenceRoom.addListener(_conferenceRoomUpdated); +// // }); +// // } catch (err) { +// // print(err); +// // await PlatformAlertDialog( +// // title: err is PlatformException ? err.message : 'An error occured', +// // content: err is PlatformException ? err.details : err.toString(), +// // defaultActionText: 'OK', +// // ).show(context); +// // +// // Navigator.of(context).pop(); +// // } +// // } +// +// Future _lockInPortrait() async { +// await SystemChrome.setPreferredOrientations([ +// DeviceOrientation.portraitUp, +// DeviceOrientation.portraitDown, +// ]); +// } +// +// @override +// void dispose() { +// _freePortraitLock(); +// _wakeLock(false); +// _disposeStreamsAndSubscriptions(); +// if (_conferenceRoom != null) _conferenceRoom.removeListener(_conferenceRoomUpdated); +// super.dispose(); +// } +// +// Future _freePortraitLock() async { +// await SystemChrome.setPreferredOrientations([ +// DeviceOrientation.landscapeRight, +// DeviceOrientation.landscapeLeft, +// DeviceOrientation.portraitUp, +// DeviceOrientation.portraitDown, +// ]); +// } +// +// Future _disposeStreamsAndSubscriptions() async { +// if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); +// if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); +// if (_onConferenceRoomException != null) await _onConferenceRoomException.cancel(); +// } +// +// @override +// Widget build(BuildContext context) { +// return WillPopScope( +// onWillPop: () async => false, +// child: Scaffold( +// backgroundColor: Colors.black, +// body: _conferenceRoom == null ? showProgress() : buildLayout(), +// ), +// ); +// } +// +// LayoutBuilder buildLayout() { +// return LayoutBuilder( +// builder: (BuildContext context, BoxConstraints constraints) { +// return Stack( +// children: [ +// _buildParticipants(context, constraints.biggest, _conferenceRoom), +// ConferenceButtonBar( +// audioEnabled: _conferenceRoom.onAudioEnabled, +// videoEnabled: _conferenceRoom.onVideoEnabled, +// onAudioEnabled: _conferenceRoom.toggleAudioEnabled, +// onVideoEnabled: _conferenceRoom.toggleVideoEnabled, +// onHangup: _onHangup, +// onSwitchCamera: _conferenceRoom.switchCamera, +// onPersonAdd: _onPersonAdd, +// onPersonRemove: _onPersonRemove, +// onHeight: _onHeightBar, +// onShow: _onShowBar, +// onHide: _onHideBar, +// ), +// ], +// ); +// }, +// ); +// } +// +// Widget showProgress() { +// return Column( +// mainAxisAlignment: MainAxisAlignment.center, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Center(child: CircularProgressIndicator()), +// SizedBox( +// height: 10, +// ), +// Text( +// 'Connecting to the call...', +// style: TextStyle(color: Colors.white), +// ), +// ], +// ); +// } +// +// Future _onHangup() async { +// print('onHangup'); +// await _conferenceRoom.disconnect(); +// Navigator.of(context).pop(); +// } +// +// void _onPersonAdd() { +// print('onPersonAdd'); +// try { +// _conferenceRoom.addDummy( +// child: Stack( +// children: [ +// const Placeholder(), +// Center( +// child: Text( +// (_conferenceRoom.participants.length + 1).toString(), +// style: const TextStyle( +// shadows: [ +// Shadow( +// blurRadius: 3.0, +// color: Color.fromARGB(255, 0, 0, 0), +// ), +// Shadow( +// blurRadius: 8.0, +// color: Color.fromARGB(255, 255, 255, 255), +// ), +// ], +// fontSize: 80, +// ), +// ), +// ), +// ], +// ), +// ); +// } on PlatformException catch (err) { +// PlatformAlertDialog( +// title: err.message, +// content: err.details, +// defaultActionText: 'OK', +// ).show(context); +// } +// } +// +// void _onPersonRemove() { +// print('onPersonRemove'); +// _conferenceRoom.removeDummy(); +// } +// +// Widget _buildParticipants(BuildContext context, Size size, ConferenceRoom conferenceRoom) { +// final children = []; +// final length = conferenceRoom.participants.length; +// +// if (length <= 2) { +// _buildOverlayLayout(context, size, children); +// return Stack(children: children); +// } +// +// void buildInCols(bool removeLocalBeforeChunking, bool moveLastOfEachRowToNextRow, int columns) { +// _buildLayoutInGrid( +// context, +// size, +// children, +// removeLocalBeforeChunking: removeLocalBeforeChunking, +// moveLastOfEachRowToNextRow: moveLastOfEachRowToNextRow, +// columns: columns, +// ); +// } +// +// // if (length <= 3) { +// // buildInCols(true, false, 1); +// // } else if (length == 5) { +// // buildInCols(false, true, 2); +// // } else if (length <= 6 || length == 8) { +// // buildInCols(false, false, 2); +// // } else if (length == 7 || length == 9) { +// // buildInCols(true, false, 2); +// // } else if (length == 10) { +// // buildInCols(false, true, 3); +// // } else if (length == 13 || length == 16) { +// // buildInCols(true, false, 3); +// // } else if (length <= 18) { +// // buildInCols(false, false, 3); +// // } +// +// return Column( +// children: children, +// ); +// } +// +// void _buildOverlayLayout(BuildContext context, Size size, List children) { +// final participants = _conferenceRoom.participants; +// if (participants.length == 1) { +// children.add(_buildNoiseBox()); +// } else { +// final remoteParticipant = participants.firstWhere((ParticipantWidget participant) => participant.isRemote, orElse: () => null); +// if (remoteParticipant != null) { +// children.add(remoteParticipant); +// } +// } +// +// final localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); +// if (localParticipant != null) { +// children.add(DraggablePublisher( +// key: Key('publisher'), +// child: localParticipant, +// availableScreenSize: size, +// onButtonBarVisible: _onButtonBarVisibleStreamController.stream, +// onButtonBarHeight: _onButtonBarHeightStreamController.stream, +// )); +// } +// } +// +// void _buildLayoutInGrid( +// BuildContext context, +// Size size, +// List children, { +// bool removeLocalBeforeChunking = false, +// bool moveLastOfEachRowToNextRow = false, +// int columns = 2, +// }) { +// final participants = _conferenceRoom.participants; +// ParticipantWidget localParticipant; +// if (removeLocalBeforeChunking) { +// localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); +// if (localParticipant != null) { +// participants.remove(localParticipant); +// } +// } +// final chunkedParticipants = chunk(array: participants, size: columns); +// if (localParticipant != null) { +// chunkedParticipants.last.add(localParticipant); +// participants.add(localParticipant); +// } +// +// if (moveLastOfEachRowToNextRow) { +// for (var i = 0; i < chunkedParticipants.length - 1; i++) { +// var participant = chunkedParticipants[i].removeLast(); +// chunkedParticipants[i + 1].insert(0, participant); +// } +// } +// +// for (final participantChunk in chunkedParticipants) { +// final rowChildren = []; +// for (final participant in participantChunk) { +// rowChildren.add( +// Container( +// width: size.width / participantChunk.length, +// height: size.height / chunkedParticipants.length, +// child: participant, +// ), +// ); +// } +// children.add( +// Container( +// height: size.height / chunkedParticipants.length, +// child: Row( +// mainAxisAlignment: MainAxisAlignment.spaceEvenly, +// children: rowChildren, +// ), +// ), +// ); +// } +// } +// +// NoiseBox _buildNoiseBox() { +// return NoiseBox( +// density: NoiseBoxDensity.xLow, +// backgroundColor: Colors.grey.shade900, +// child: Center( +// child: Container( +// color: Colors.black54, +// width: double.infinity, +// height: 40, +// child: Center( +// child: Text( +// 'Waiting for another participant to connect to the call...', +// key: Key('text-wait'), +// textAlign: TextAlign.center, +// style: TextStyle(color: Colors.white), +// ), +// ), +// ), +// ), +// ); +// } +// +// List> chunk({@required List array, @required int size}) { +// final result = >[]; +// if (array.isEmpty || size <= 0) { +// return result; +// } +// var first = 0; +// var last = size; +// final totalLoop = array.length % size == 0 ? array.length ~/ size : array.length ~/ size + 1; +// for (var i = 0; i < totalLoop; i++) { +// if (last > array.length) { +// result.add(array.sublist(first, array.length)); +// } else { +// result.add(array.sublist(first, last)); +// } +// first = last; +// last = last + size; +// } +// return result; +// } +// +// void _onHeightBar(double height) { +// _onButtonBarHeightStreamController.add(height); +// } +// +// void _onShowBar() { +// setState(() { +// SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]); +// }); +// _onButtonBarVisibleStreamController.add(true); +// } +// +// void _onHideBar() { +// setState(() { +// SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); +// }); +// _onButtonBarVisibleStreamController.add(false); +// } +// +// Future _wakeLock(bool enable) async { +// try { +// return await (enable ? Wakelock.enable() : Wakelock.disable()); +// } catch (err) { +// print('Unable to change the Wakelock and set it to $enable'); +// print(err); +// } +// } +// +// void _conferenceRoomUpdated() { +// setState(() {}); +// } +// } diff --git a/lib/pages/conference/conference_room.dart b/lib/pages/conference/conference_room.dart index 9c8c1c9a..a88c3bdb 100644 --- a/lib/pages/conference/conference_room.dart +++ b/lib/pages/conference/conference_room.dart @@ -4,527 +4,527 @@ import 'dart:typed_data'; import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:twilio_programmable_video/twilio_programmable_video.dart'; +// import 'package:twilio_programmable_video/twilio_programmable_video.dart'; class ConferenceRoom with ChangeNotifier { - final String name; - final String token; - final String identity; - - final StreamController _onAudioEnabledStreamController = StreamController.broadcast(); - Stream onAudioEnabled; - final StreamController _onVideoEnabledStreamController = StreamController.broadcast(); - Stream onVideoEnabled; - final StreamController _onExceptionStreamController = StreamController.broadcast(); - Stream onException; - - final Completer _completer = Completer(); - - final List _participants = []; - final List _participantBuffer = []; - final List _streamSubscriptions = []; - final List _dataTracks = []; - final List _messages = []; - - CameraCapturer _cameraCapturer; - Room _room; - Timer _timer; - - ConferenceRoom({ - @required this.name, - @required this.token, - @required this.identity, - }) { - onAudioEnabled = _onAudioEnabledStreamController.stream; - onVideoEnabled = _onVideoEnabledStreamController.stream; - onException = _onExceptionStreamController.stream; - } - - List get participants { - return [..._participants]; - } - - Future connect() async { - print('ConferenceRoom.connect()'); - try { - await TwilioProgrammableVideo.debug(dart: true, native: true); - await TwilioProgrammableVideo.setSpeakerphoneOn(true); - - _cameraCapturer = CameraCapturer(CameraSource.FRONT_CAMERA); - var connectOptions = ConnectOptions( - token, - roomName: name, - preferredAudioCodecs: [OpusCodec()], - audioTracks: [LocalAudioTrack(true)], - dataTracks: [LocalDataTrack()], - videoTracks: [LocalVideoTrack(true, _cameraCapturer)], - enableDominantSpeaker: true, - ); - - _room = await TwilioProgrammableVideo.connect(connectOptions); - - _streamSubscriptions.add(_room.onConnected.listen(_onConnected)); - _streamSubscriptions.add(_room.onConnectFailure.listen(_onConnectFailure)); - - return _completer.future; - } catch (err) { - print(err); - rethrow; - } - } - - Future disconnect() async { - print('ConferenceRoom.disconnect()'); - if (_timer != null) { - _timer.cancel(); - } - await _room.disconnect(); - } - - @override - void dispose() { - print('ConferenceRoom.dispose()'); - _disposeStreamsAndSubscriptions(); - super.dispose(); - } - - Future _disposeStreamsAndSubscriptions() async { - await _onAudioEnabledStreamController.close(); - await _onVideoEnabledStreamController.close(); - await _onExceptionStreamController.close(); - for (var streamSubscription in _streamSubscriptions) { - await streamSubscription.cancel(); - } - } - - Future sendMessage(String message) async { - final tracks = _room.localParticipant.localDataTracks; - final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; - if (localDataTrack == null || _messages.isNotEmpty) { - print('ConferenceRoom.sendMessage => Track is not available yet, buffering message.'); - _messages.add(message); - return; - } - await localDataTrack.send(message); - } - - Future sendBufferMessage(ByteBuffer message) async { - final tracks = _room.localParticipant.localDataTracks; - final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; - if (localDataTrack == null) { - return; - } - await localDataTrack.sendBuffer(message); - } - - Future toggleVideoEnabled() async { - final tracks = _room.localParticipant.localVideoTracks; - final localVideoTrack = tracks.isEmpty ? null : tracks[0].localVideoTrack; - if (localVideoTrack == null) { - print('ConferenceRoom.toggleVideoEnabled() => Track is not available yet!'); - return; - } - await localVideoTrack.enable(!localVideoTrack.isEnabled); - - var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); - if (index < 0) { - return; - } - var participant = _participants[index]; - _participants.replaceRange( - index, - index + 1, - [ - participant.copyWith(videoEnabled: localVideoTrack.isEnabled), - ], - ); - print('ConferenceRoom.toggleVideoEnabled() => ${localVideoTrack.isEnabled}'); - _onVideoEnabledStreamController.add(localVideoTrack.isEnabled); - notifyListeners(); - } - - Future toggleAudioEnabled() async { - final tracks = _room.localParticipant.localAudioTracks; - final localAudioTrack = tracks.isEmpty ? null : tracks[0].localAudioTrack; - if (localAudioTrack == null) { - print('ConferenceRoom.toggleAudioEnabled() => Track is not available yet!'); - return; - } - await localAudioTrack.enable(!localAudioTrack.isEnabled); - - var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); - if (index < 0) { - return; - } - var participant = _participants[index]; - _participants.replaceRange( - index, - index + 1, - [ - participant.copyWith(audioEnabled: localAudioTrack.isEnabled), - ], - ); - print('ConferenceRoom.toggleAudioEnabled() => ${localAudioTrack.isEnabled}'); - _onAudioEnabledStreamController.add(localAudioTrack.isEnabled); - notifyListeners(); - } - - Future switchCamera() async { - print('ConferenceRoom.switchCamera()'); - try { - await _cameraCapturer.switchCamera(); - } on FormatException catch (e) { - print( - 'ConferenceRoom.switchCamera() failed because of FormatException with message: ${e.message}', - ); - } - } - - void addDummy({Widget child}) { - print('ConferenceRoom.addDummy()'); - if (_participants.length >= 18) { - throw PlatformException( - code: 'ConferenceRoom.maximumReached', - message: 'Maximum reached', - details: 'Currently the lay-out can only render a maximum of 18 participants', - ); - } - _participants.insert( - 0, - ParticipantWidget( - id: (_participants.length + 1).toString(), - child: child, - isRemote: true, - audioEnabled: true, - videoEnabled: true, - isDummy: true, - ), - ); - notifyListeners(); - } - - void removeDummy() { - print('ConferenceRoom.removeDummy()'); - var dummy = _participants.firstWhere((participant) => participant.isDummy, orElse: () => null); - if (dummy != null) { - _participants.remove(dummy); - notifyListeners(); - } - } - - void _onConnected(Room room) { - print('ConferenceRoom._onConnected => state: ${room.state}'); - - // When connected for the first time, add remote participant listeners - _streamSubscriptions.add(_room.onParticipantConnected.listen(_onParticipantConnected)); - _streamSubscriptions.add(_room.onParticipantDisconnected.listen(_onParticipantDisconnected)); - _streamSubscriptions.add(_room.onDominantSpeakerChange.listen(_onDominantSpeakerChanged)); - // Only add ourselves when connected for the first time too. - _participants.add( - _buildParticipant( - child: room.localParticipant.localVideoTracks[0].localVideoTrack.widget(), - id: identity, - audioEnabled: true, - videoEnabled: true, - ), - ); - for (final remoteParticipant in room.remoteParticipants) { - var participant = _participants.firstWhere((participant) => participant.id == remoteParticipant.sid, orElse: () => null); - if (participant == null) { - print('Adding participant that was already present in the room ${remoteParticipant.sid}, before I connected'); - _addRemoteParticipantListeners(remoteParticipant); - } - } - // We have to listen for the [onDataTrackPublished] event on the [LocalParticipant] in - // order to be able to use the [send] method. - _streamSubscriptions.add(room.localParticipant.onDataTrackPublished.listen(_onLocalDataTrackPublished)); - notifyListeners(); - _completer.complete(room); - - _timer = Timer.periodic(const Duration(minutes: 1), (_) { - // Let's see if we can send some data over the DataTrack API - sendMessage('And another minute has passed since I connected...'); - // Also try the ByteBuffer way of sending data - final list = 'This data has been sent over the ByteBuffer channel of the DataTrack API'.codeUnits; - var bytes = Uint8List.fromList(list); - sendBufferMessage(bytes.buffer); - }); - } - - void _onLocalDataTrackPublished(LocalDataTrackPublishedEvent event) { - // Send buffered messages, if any... - while (_messages.isNotEmpty) { - var message = _messages.removeAt(0); - print('Sending buffered message: $message'); - event.localDataTrackPublication.localDataTrack.send(message); - } - } - - void _onConnectFailure(RoomConnectFailureEvent event) { - print('ConferenceRoom._onConnectFailure: ${event.exception}'); - _completer.completeError(event.exception); - } - - void _onDominantSpeakerChanged(DominantSpeakerChangedEvent event) { - print('ConferenceRoom._onDominantSpeakerChanged: ${event.remoteParticipant.identity}'); - var oldDominantParticipant = _participants.firstWhere((p) => p.isDominant, orElse: () => null); - if (oldDominantParticipant != null) { - var oldDominantParticipantIndex = _participants.indexOf(oldDominantParticipant); - _participants.replaceRange(oldDominantParticipantIndex, oldDominantParticipantIndex + 1, [oldDominantParticipant.copyWith(isDominant: false)]); - } - - var newDominantParticipant = _participants.firstWhere((p) => p.id == event.remoteParticipant.sid); - var newDominantParticipantIndex = _participants.indexOf(newDominantParticipant); - _participants.replaceRange(newDominantParticipantIndex, newDominantParticipantIndex + 1, [newDominantParticipant.copyWith(isDominant: true)]); - notifyListeners(); - } - - void _onParticipantConnected(RoomParticipantConnectedEvent event) { - print('ConferenceRoom._onParticipantConnected, ${event.remoteParticipant.sid}'); - _addRemoteParticipantListeners(event.remoteParticipant); - } - - void _onParticipantDisconnected(RoomParticipantDisconnectedEvent event) { - print('ConferenceRoom._onParticipantDisconnected: ${event.remoteParticipant.sid}'); - _participants.removeWhere((ParticipantWidget p) => p.id == event.remoteParticipant.sid); - notifyListeners(); - } - - ParticipantWidget _buildParticipant({ - @required Widget child, - @required String id, - @required bool audioEnabled, - @required bool videoEnabled, - RemoteParticipant remoteParticipant, - }) { - return ParticipantWidget( - id: remoteParticipant?.sid, - isRemote: remoteParticipant != null, - child: child, - audioEnabled: audioEnabled, - videoEnabled: videoEnabled, - ); - } - - void _addRemoteParticipantListeners(RemoteParticipant remoteParticipant) { - print('ConferenceRoom._addRemoteParticipantListeners() => Adding listeners to remoteParticipant ${remoteParticipant.sid}'); - _streamSubscriptions.add(remoteParticipant.onAudioTrackDisabled.listen(_onAudioTrackDisabled)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackEnabled.listen(_onAudioTrackEnabled)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackPublished.listen(_onAudioTrackPublished)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscribed.listen(_onAudioTrackSubscribed)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscriptionFailed.listen(_onAudioTrackSubscriptionFailed)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackUnpublished.listen(_onAudioTrackUnpublished)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackUnsubscribed.listen(_onAudioTrackUnsubscribed)); - - _streamSubscriptions.add(remoteParticipant.onDataTrackPublished.listen(_onDataTrackPublished)); - _streamSubscriptions.add(remoteParticipant.onDataTrackSubscribed.listen(_onDataTrackSubscribed)); - _streamSubscriptions.add(remoteParticipant.onDataTrackSubscriptionFailed.listen(_onDataTrackSubscriptionFailed)); - _streamSubscriptions.add(remoteParticipant.onDataTrackUnpublished.listen(_onDataTrackUnpublished)); - _streamSubscriptions.add(remoteParticipant.onDataTrackUnsubscribed.listen(_onDataTrackUnsubscribed)); - - _streamSubscriptions.add(remoteParticipant.onVideoTrackDisabled.listen(_onVideoTrackDisabled)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackEnabled.listen(_onVideoTrackEnabled)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackPublished.listen(_onVideoTrackPublished)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscribed.listen(_onVideoTrackSubscribed)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscriptionFailed.listen(_onVideoTrackSubscriptionFailed)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackUnpublished.listen(_onVideoTrackUnpublished)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackUnsubscribed.listen(_onVideoTrackUnsubscribed)); - } - - void _onAudioTrackDisabled(RemoteAudioTrackEvent event) { - print('ConferenceRoom._onAudioTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); - _setRemoteAudioEnabled(event); - } - - void _onAudioTrackEnabled(RemoteAudioTrackEvent event) { - print('ConferenceRoom._onAudioTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); - _setRemoteAudioEnabled(event); - } - - void _onAudioTrackPublished(RemoteAudioTrackEvent event) { - print('ConferenceRoom._onAudioTrackPublished(), ${event.remoteParticipant.sid}}'); - } - - void _onAudioTrackSubscribed(RemoteAudioTrackSubscriptionEvent event) { - print('ConferenceRoom._onAudioTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - _addOrUpdateParticipant(event); - } - - void _onAudioTrackSubscriptionFailed(RemoteAudioTrackSubscriptionFailedEvent event) { - print('ConferenceRoom._onAudioTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - _onExceptionStreamController.add( - PlatformException( - code: 'ConferenceRoom.audioTrackSubscriptionFailed', - message: 'AudioTrack Subscription Failed', - details: event.exception.toString(), - ), - ); - } - - void _onAudioTrackUnpublished(RemoteAudioTrackEvent event) { - print('ConferenceRoom._onAudioTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - } - - void _onAudioTrackUnsubscribed(RemoteAudioTrackSubscriptionEvent event) { - print('ConferenceRoom._onAudioTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrack.sid}'); - } - - void _onDataTrackPublished(RemoteDataTrackEvent event) { - print('ConferenceRoom._onDataTrackPublished(), ${event.remoteParticipant.sid}}'); - } - - void _onDataTrackSubscribed(RemoteDataTrackSubscriptionEvent event) { - print('ConferenceRoom._onDataTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - final dataTrack = event.remoteDataTrackPublication.remoteDataTrack; - _dataTracks.add(dataTrack); - _streamSubscriptions.add(dataTrack.onMessage.listen(_onMessage)); - _streamSubscriptions.add(dataTrack.onBufferMessage.listen(_onBufferMessage)); - } - - void _onDataTrackSubscriptionFailed(RemoteDataTrackSubscriptionFailedEvent event) { - print('ConferenceRoom._onDataTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - _onExceptionStreamController.add( - PlatformException( - code: 'ConferenceRoom.dataTrackSubscriptionFailed', - message: 'DataTrack Subscription Failed', - details: event.exception.toString(), - ), - ); - } - - void _onDataTrackUnpublished(RemoteDataTrackEvent event) { - print('ConferenceRoom._onDataTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - } - - void _onDataTrackUnsubscribed(RemoteDataTrackSubscriptionEvent event) { - print('ConferenceRoom._onDataTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrack.sid}'); - } - - void _onVideoTrackDisabled(RemoteVideoTrackEvent event) { - print('ConferenceRoom._onVideoTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); - _setRemoteVideoEnabled(event); - } - - void _onVideoTrackEnabled(RemoteVideoTrackEvent event) { - print('ConferenceRoom._onVideoTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); - _setRemoteVideoEnabled(event); - } - - void _onVideoTrackPublished(RemoteVideoTrackEvent event) { - print('ConferenceRoom._onVideoTrackPublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - } - - void _onVideoTrackSubscribed(RemoteVideoTrackSubscriptionEvent event) { - print('ConferenceRoom._onVideoTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); - _addOrUpdateParticipant(event); - } - - void _onVideoTrackSubscriptionFailed(RemoteVideoTrackSubscriptionFailedEvent event) { - print('ConferenceRoom._onVideoTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - _onExceptionStreamController.add( - PlatformException( - code: 'ConferenceRoom.videoTrackSubscriptionFailed', - message: 'VideoTrack Subscription Failed', - details: event.exception.toString(), - ), - ); - } - - void _onVideoTrackUnpublished(RemoteVideoTrackEvent event) { - print('ConferenceRoom._onVideoTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - } - - void _onVideoTrackUnsubscribed(RemoteVideoTrackSubscriptionEvent event) { - print('ConferenceRoom._onVideoTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); - } - - void _onMessage(RemoteDataTrackStringMessageEvent event) { - print('onMessage => ${event.remoteDataTrack.sid}, ${event.message}'); - } - - void _onBufferMessage(RemoteDataTrackBufferMessageEvent event) { - print('onBufferMessage => ${event.remoteDataTrack.sid}, ${String.fromCharCodes(event.message.asUint8List())}'); - } - - void _setRemoteAudioEnabled(RemoteAudioTrackEvent event) { - if (event.remoteAudioTrackPublication == null) { - return; - } - var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); - if (index < 0) { - return; - } - var participant = _participants[index]; - _participants.replaceRange( - index, - index + 1, - [ - participant.copyWith(audioEnabled: event.remoteAudioTrackPublication.isTrackEnabled), - ], - ); - notifyListeners(); - } - - void _setRemoteVideoEnabled(RemoteVideoTrackEvent event) { - if (event.remoteVideoTrackPublication == null) { - return; - } - var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); - if (index < 0) { - return; - } - var participant = _participants[index]; - _participants.replaceRange( - index, - index + 1, - [ - participant.copyWith(videoEnabled: event.remoteVideoTrackPublication.isTrackEnabled), - ], - ); - notifyListeners(); - } - - void _addOrUpdateParticipant(RemoteParticipantEvent event) { - print('ConferenceRoom._addOrUpdateParticipant(), ${event.remoteParticipant.sid}'); - final participant = _participants.firstWhere( - (ParticipantWidget participant) => participant.id == event.remoteParticipant.sid, - orElse: () => null, - ); - if (participant != null) { - print('Participant found: ${participant.id}, updating A/V enabled values'); - _setRemoteVideoEnabled(event); - _setRemoteAudioEnabled(event); - } else { - final bufferedParticipant = _participantBuffer.firstWhere( - (ParticipantBuffer participant) => participant.id == event.remoteParticipant.sid, - orElse: () => null, - ); - if (bufferedParticipant != null) { - _participantBuffer.remove(bufferedParticipant); - } else if (event is RemoteAudioTrackEvent) { - print('Audio subscription came first, waiting for the video subscription...'); - _participantBuffer.add( - ParticipantBuffer( - id: event.remoteParticipant.sid, - audioEnabled: event.remoteAudioTrackPublication?.remoteAudioTrack?.isEnabled ?? true, - ), - ); - return; - } - if (event is RemoteVideoTrackSubscriptionEvent) { - print('New participant, adding: ${event.remoteParticipant.sid}'); - _participants.insert( - 0, - _buildParticipant( - child: event.remoteVideoTrack.widget(), - id: event.remoteParticipant.sid, - remoteParticipant: event.remoteParticipant, - audioEnabled: bufferedParticipant?.audioEnabled ?? true, - videoEnabled: event.remoteVideoTrackPublication?.remoteVideoTrack?.isEnabled ?? true, - ), - ); - } - notifyListeners(); - } - } + // final String name; + // final String token; + // final String identity; + // + // final StreamController _onAudioEnabledStreamController = StreamController.broadcast(); + // Stream onAudioEnabled; + // final StreamController _onVideoEnabledStreamController = StreamController.broadcast(); + // Stream onVideoEnabled; + // final StreamController _onExceptionStreamController = StreamController.broadcast(); + // Stream onException; + // + // final Completer _completer = Completer(); + // + // final List _participants = []; + // final List _participantBuffer = []; + // final List _streamSubscriptions = []; + // final List _dataTracks = []; + // final List _messages = []; + // + // CameraCapturer _cameraCapturer; + // Room _room; + // Timer _timer; + // + // ConferenceRoom({ + // @required this.name, + // @required this.token, + // @required this.identity, + // }) { + // onAudioEnabled = _onAudioEnabledStreamController.stream; + // onVideoEnabled = _onVideoEnabledStreamController.stream; + // onException = _onExceptionStreamController.stream; + // } + // + // List get participants { + // return [..._participants]; + // } + // + // Future connect() async { + // print('ConferenceRoom.connect()'); + // try { + // await TwilioProgrammableVideo.debug(dart: true, native: true); + // await TwilioProgrammableVideo.setSpeakerphoneOn(true); + // + // _cameraCapturer = CameraCapturer(CameraSource.FRONT_CAMERA); + // var connectOptions = ConnectOptions( + // token, + // roomName: name, + // preferredAudioCodecs: [OpusCodec()], + // audioTracks: [LocalAudioTrack(true)], + // dataTracks: [LocalDataTrack()], + // videoTracks: [LocalVideoTrack(true, _cameraCapturer)], + // enableDominantSpeaker: true, + // ); + // + // _room = await TwilioProgrammableVideo.connect(connectOptions); + // + // _streamSubscriptions.add(_room.onConnected.listen(_onConnected)); + // _streamSubscriptions.add(_room.onConnectFailure.listen(_onConnectFailure)); + // + // return _completer.future; + // } catch (err) { + // print(err); + // rethrow; + // } + // } + // + // Future disconnect() async { + // print('ConferenceRoom.disconnect()'); + // if (_timer != null) { + // _timer.cancel(); + // } + // await _room.disconnect(); + // } + // + // @override + // void dispose() { + // print('ConferenceRoom.dispose()'); + // _disposeStreamsAndSubscriptions(); + // super.dispose(); + // } + // + // Future _disposeStreamsAndSubscriptions() async { + // await _onAudioEnabledStreamController.close(); + // await _onVideoEnabledStreamController.close(); + // await _onExceptionStreamController.close(); + // for (var streamSubscription in _streamSubscriptions) { + // await streamSubscription.cancel(); + // } + // } + // + // Future sendMessage(String message) async { + // final tracks = _room.localParticipant.localDataTracks; + // final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; + // if (localDataTrack == null || _messages.isNotEmpty) { + // print('ConferenceRoom.sendMessage => Track is not available yet, buffering message.'); + // _messages.add(message); + // return; + // } + // await localDataTrack.send(message); + // } + // + // Future sendBufferMessage(ByteBuffer message) async { + // final tracks = _room.localParticipant.localDataTracks; + // final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; + // if (localDataTrack == null) { + // return; + // } + // await localDataTrack.sendBuffer(message); + // } + // + // Future toggleVideoEnabled() async { + // final tracks = _room.localParticipant.localVideoTracks; + // final localVideoTrack = tracks.isEmpty ? null : tracks[0].localVideoTrack; + // if (localVideoTrack == null) { + // print('ConferenceRoom.toggleVideoEnabled() => Track is not available yet!'); + // return; + // } + // await localVideoTrack.enable(!localVideoTrack.isEnabled); + // + // var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); + // if (index < 0) { + // return; + // } + // var participant = _participants[index]; + // _participants.replaceRange( + // index, + // index + 1, + // [ + // participant.copyWith(videoEnabled: localVideoTrack.isEnabled), + // ], + // ); + // print('ConferenceRoom.toggleVideoEnabled() => ${localVideoTrack.isEnabled}'); + // _onVideoEnabledStreamController.add(localVideoTrack.isEnabled); + // notifyListeners(); + // } + // + // Future toggleAudioEnabled() async { + // final tracks = _room.localParticipant.localAudioTracks; + // final localAudioTrack = tracks.isEmpty ? null : tracks[0].localAudioTrack; + // if (localAudioTrack == null) { + // print('ConferenceRoom.toggleAudioEnabled() => Track is not available yet!'); + // return; + // } + // await localAudioTrack.enable(!localAudioTrack.isEnabled); + // + // var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); + // if (index < 0) { + // return; + // } + // var participant = _participants[index]; + // _participants.replaceRange( + // index, + // index + 1, + // [ + // participant.copyWith(audioEnabled: localAudioTrack.isEnabled), + // ], + // ); + // print('ConferenceRoom.toggleAudioEnabled() => ${localAudioTrack.isEnabled}'); + // _onAudioEnabledStreamController.add(localAudioTrack.isEnabled); + // notifyListeners(); + // } + // + // Future switchCamera() async { + // print('ConferenceRoom.switchCamera()'); + // try { + // await _cameraCapturer.switchCamera(); + // } on FormatException catch (e) { + // print( + // 'ConferenceRoom.switchCamera() failed because of FormatException with message: ${e.message}', + // ); + // } + // } + // + // void addDummy({Widget child}) { + // print('ConferenceRoom.addDummy()'); + // if (_participants.length >= 18) { + // throw PlatformException( + // code: 'ConferenceRoom.maximumReached', + // message: 'Maximum reached', + // details: 'Currently the lay-out can only render a maximum of 18 participants', + // ); + // } + // _participants.insert( + // 0, + // ParticipantWidget( + // id: (_participants.length + 1).toString(), + // child: child, + // isRemote: true, + // audioEnabled: true, + // videoEnabled: true, + // isDummy: true, + // ), + // ); + // notifyListeners(); + // } + // + // void removeDummy() { + // print('ConferenceRoom.removeDummy()'); + // var dummy = _participants.firstWhere((participant) => participant.isDummy, orElse: () => null); + // if (dummy != null) { + // _participants.remove(dummy); + // notifyListeners(); + // } + // } + // + // void _onConnected(Room room) { + // print('ConferenceRoom._onConnected => state: ${room.state}'); + // + // // When connected for the first time, add remote participant listeners + // _streamSubscriptions.add(_room.onParticipantConnected.listen(_onParticipantConnected)); + // _streamSubscriptions.add(_room.onParticipantDisconnected.listen(_onParticipantDisconnected)); + // _streamSubscriptions.add(_room.onDominantSpeakerChange.listen(_onDominantSpeakerChanged)); + // // Only add ourselves when connected for the first time too. + // _participants.add( + // _buildParticipant( + // child: room.localParticipant.localVideoTracks[0].localVideoTrack.widget(), + // id: identity, + // audioEnabled: true, + // videoEnabled: true, + // ), + // ); + // for (final remoteParticipant in room.remoteParticipants) { + // var participant = _participants.firstWhere((participant) => participant.id == remoteParticipant.sid, orElse: () => null); + // if (participant == null) { + // print('Adding participant that was already present in the room ${remoteParticipant.sid}, before I connected'); + // _addRemoteParticipantListeners(remoteParticipant); + // } + // } + // // We have to listen for the [onDataTrackPublished] event on the [LocalParticipant] in + // // order to be able to use the [send] method. + // _streamSubscriptions.add(room.localParticipant.onDataTrackPublished.listen(_onLocalDataTrackPublished)); + // notifyListeners(); + // _completer.complete(room); + // + // _timer = Timer.periodic(const Duration(minutes: 1), (_) { + // // Let's see if we can send some data over the DataTrack API + // sendMessage('And another minute has passed since I connected...'); + // // Also try the ByteBuffer way of sending data + // final list = 'This data has been sent over the ByteBuffer channel of the DataTrack API'.codeUnits; + // var bytes = Uint8List.fromList(list); + // sendBufferMessage(bytes.buffer); + // }); + // } + // + // void _onLocalDataTrackPublished(LocalDataTrackPublishedEvent event) { + // // Send buffered messages, if any... + // while (_messages.isNotEmpty) { + // var message = _messages.removeAt(0); + // print('Sending buffered message: $message'); + // event.localDataTrackPublication.localDataTrack.send(message); + // } + // } + // + // void _onConnectFailure(RoomConnectFailureEvent event) { + // print('ConferenceRoom._onConnectFailure: ${event.exception}'); + // _completer.completeError(event.exception); + // } + // + // void _onDominantSpeakerChanged(DominantSpeakerChangedEvent event) { + // print('ConferenceRoom._onDominantSpeakerChanged: ${event.remoteParticipant.identity}'); + // var oldDominantParticipant = _participants.firstWhere((p) => p.isDominant, orElse: () => null); + // if (oldDominantParticipant != null) { + // var oldDominantParticipantIndex = _participants.indexOf(oldDominantParticipant); + // _participants.replaceRange(oldDominantParticipantIndex, oldDominantParticipantIndex + 1, [oldDominantParticipant.copyWith(isDominant: false)]); + // } + // + // var newDominantParticipant = _participants.firstWhere((p) => p.id == event.remoteParticipant.sid); + // var newDominantParticipantIndex = _participants.indexOf(newDominantParticipant); + // _participants.replaceRange(newDominantParticipantIndex, newDominantParticipantIndex + 1, [newDominantParticipant.copyWith(isDominant: true)]); + // notifyListeners(); + // } + // + // void _onParticipantConnected(RoomParticipantConnectedEvent event) { + // print('ConferenceRoom._onParticipantConnected, ${event.remoteParticipant.sid}'); + // _addRemoteParticipantListeners(event.remoteParticipant); + // } + // + // void _onParticipantDisconnected(RoomParticipantDisconnectedEvent event) { + // print('ConferenceRoom._onParticipantDisconnected: ${event.remoteParticipant.sid}'); + // _participants.removeWhere((ParticipantWidget p) => p.id == event.remoteParticipant.sid); + // notifyListeners(); + // } + // + // ParticipantWidget _buildParticipant({ + // @required Widget child, + // @required String id, + // @required bool audioEnabled, + // @required bool videoEnabled, + // RemoteParticipant remoteParticipant, + // }) { + // return ParticipantWidget( + // id: remoteParticipant?.sid, + // isRemote: remoteParticipant != null, + // child: child, + // audioEnabled: audioEnabled, + // videoEnabled: videoEnabled, + // ); + // } + // + // void _addRemoteParticipantListeners(RemoteParticipant remoteParticipant) { + // print('ConferenceRoom._addRemoteParticipantListeners() => Adding listeners to remoteParticipant ${remoteParticipant.sid}'); + // _streamSubscriptions.add(remoteParticipant.onAudioTrackDisabled.listen(_onAudioTrackDisabled)); + // _streamSubscriptions.add(remoteParticipant.onAudioTrackEnabled.listen(_onAudioTrackEnabled)); + // _streamSubscriptions.add(remoteParticipant.onAudioTrackPublished.listen(_onAudioTrackPublished)); + // _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscribed.listen(_onAudioTrackSubscribed)); + // _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscriptionFailed.listen(_onAudioTrackSubscriptionFailed)); + // _streamSubscriptions.add(remoteParticipant.onAudioTrackUnpublished.listen(_onAudioTrackUnpublished)); + // _streamSubscriptions.add(remoteParticipant.onAudioTrackUnsubscribed.listen(_onAudioTrackUnsubscribed)); + // + // _streamSubscriptions.add(remoteParticipant.onDataTrackPublished.listen(_onDataTrackPublished)); + // _streamSubscriptions.add(remoteParticipant.onDataTrackSubscribed.listen(_onDataTrackSubscribed)); + // _streamSubscriptions.add(remoteParticipant.onDataTrackSubscriptionFailed.listen(_onDataTrackSubscriptionFailed)); + // _streamSubscriptions.add(remoteParticipant.onDataTrackUnpublished.listen(_onDataTrackUnpublished)); + // _streamSubscriptions.add(remoteParticipant.onDataTrackUnsubscribed.listen(_onDataTrackUnsubscribed)); + // + // _streamSubscriptions.add(remoteParticipant.onVideoTrackDisabled.listen(_onVideoTrackDisabled)); + // _streamSubscriptions.add(remoteParticipant.onVideoTrackEnabled.listen(_onVideoTrackEnabled)); + // _streamSubscriptions.add(remoteParticipant.onVideoTrackPublished.listen(_onVideoTrackPublished)); + // _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscribed.listen(_onVideoTrackSubscribed)); + // _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscriptionFailed.listen(_onVideoTrackSubscriptionFailed)); + // _streamSubscriptions.add(remoteParticipant.onVideoTrackUnpublished.listen(_onVideoTrackUnpublished)); + // _streamSubscriptions.add(remoteParticipant.onVideoTrackUnsubscribed.listen(_onVideoTrackUnsubscribed)); + // } + // + // void _onAudioTrackDisabled(RemoteAudioTrackEvent event) { + // print('ConferenceRoom._onAudioTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); + // _setRemoteAudioEnabled(event); + // } + // + // void _onAudioTrackEnabled(RemoteAudioTrackEvent event) { + // print('ConferenceRoom._onAudioTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); + // _setRemoteAudioEnabled(event); + // } + // + // void _onAudioTrackPublished(RemoteAudioTrackEvent event) { + // print('ConferenceRoom._onAudioTrackPublished(), ${event.remoteParticipant.sid}}'); + // } + // + // void _onAudioTrackSubscribed(RemoteAudioTrackSubscriptionEvent event) { + // print('ConferenceRoom._onAudioTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); + // _addOrUpdateParticipant(event); + // } + // + // void _onAudioTrackSubscriptionFailed(RemoteAudioTrackSubscriptionFailedEvent event) { + // print('ConferenceRoom._onAudioTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); + // _onExceptionStreamController.add( + // PlatformException( + // code: 'ConferenceRoom.audioTrackSubscriptionFailed', + // message: 'AudioTrack Subscription Failed', + // details: event.exception.toString(), + // ), + // ); + // } + // + // void _onAudioTrackUnpublished(RemoteAudioTrackEvent event) { + // print('ConferenceRoom._onAudioTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); + // } + // + // void _onAudioTrackUnsubscribed(RemoteAudioTrackSubscriptionEvent event) { + // print('ConferenceRoom._onAudioTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrack.sid}'); + // } + // + // void _onDataTrackPublished(RemoteDataTrackEvent event) { + // print('ConferenceRoom._onDataTrackPublished(), ${event.remoteParticipant.sid}}'); + // } + // + // void _onDataTrackSubscribed(RemoteDataTrackSubscriptionEvent event) { + // print('ConferenceRoom._onDataTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); + // final dataTrack = event.remoteDataTrackPublication.remoteDataTrack; + // _dataTracks.add(dataTrack); + // _streamSubscriptions.add(dataTrack.onMessage.listen(_onMessage)); + // _streamSubscriptions.add(dataTrack.onBufferMessage.listen(_onBufferMessage)); + // } + // + // void _onDataTrackSubscriptionFailed(RemoteDataTrackSubscriptionFailedEvent event) { + // print('ConferenceRoom._onDataTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); + // _onExceptionStreamController.add( + // PlatformException( + // code: 'ConferenceRoom.dataTrackSubscriptionFailed', + // message: 'DataTrack Subscription Failed', + // details: event.exception.toString(), + // ), + // ); + // } + // + // void _onDataTrackUnpublished(RemoteDataTrackEvent event) { + // print('ConferenceRoom._onDataTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); + // } + // + // void _onDataTrackUnsubscribed(RemoteDataTrackSubscriptionEvent event) { + // print('ConferenceRoom._onDataTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrack.sid}'); + // } + // + // void _onVideoTrackDisabled(RemoteVideoTrackEvent event) { + // print('ConferenceRoom._onVideoTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); + // _setRemoteVideoEnabled(event); + // } + // + // void _onVideoTrackEnabled(RemoteVideoTrackEvent event) { + // print('ConferenceRoom._onVideoTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); + // _setRemoteVideoEnabled(event); + // } + // + // void _onVideoTrackPublished(RemoteVideoTrackEvent event) { + // print('ConferenceRoom._onVideoTrackPublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); + // } + // + // void _onVideoTrackSubscribed(RemoteVideoTrackSubscriptionEvent event) { + // print('ConferenceRoom._onVideoTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); + // _addOrUpdateParticipant(event); + // } + // + // void _onVideoTrackSubscriptionFailed(RemoteVideoTrackSubscriptionFailedEvent event) { + // print('ConferenceRoom._onVideoTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); + // _onExceptionStreamController.add( + // PlatformException( + // code: 'ConferenceRoom.videoTrackSubscriptionFailed', + // message: 'VideoTrack Subscription Failed', + // details: event.exception.toString(), + // ), + // ); + // } + // + // void _onVideoTrackUnpublished(RemoteVideoTrackEvent event) { + // print('ConferenceRoom._onVideoTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); + // } + // + // void _onVideoTrackUnsubscribed(RemoteVideoTrackSubscriptionEvent event) { + // print('ConferenceRoom._onVideoTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); + // } + // + // void _onMessage(RemoteDataTrackStringMessageEvent event) { + // print('onMessage => ${event.remoteDataTrack.sid}, ${event.message}'); + // } + // + // void _onBufferMessage(RemoteDataTrackBufferMessageEvent event) { + // print('onBufferMessage => ${event.remoteDataTrack.sid}, ${String.fromCharCodes(event.message.asUint8List())}'); + // } + // + // void _setRemoteAudioEnabled(RemoteAudioTrackEvent event) { + // if (event.remoteAudioTrackPublication == null) { + // return; + // } + // var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); + // if (index < 0) { + // return; + // } + // var participant = _participants[index]; + // _participants.replaceRange( + // index, + // index + 1, + // [ + // participant.copyWith(audioEnabled: event.remoteAudioTrackPublication.isTrackEnabled), + // ], + // ); + // notifyListeners(); + // } + // + // void _setRemoteVideoEnabled(RemoteVideoTrackEvent event) { + // if (event.remoteVideoTrackPublication == null) { + // return; + // } + // var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); + // if (index < 0) { + // return; + // } + // var participant = _participants[index]; + // _participants.replaceRange( + // index, + // index + 1, + // [ + // participant.copyWith(videoEnabled: event.remoteVideoTrackPublication.isTrackEnabled), + // ], + // ); + // notifyListeners(); + // } + // + // void _addOrUpdateParticipant(RemoteParticipantEvent event) { + // print('ConferenceRoom._addOrUpdateParticipant(), ${event.remoteParticipant.sid}'); + // final participant = _participants.firstWhere( + // (ParticipantWidget participant) => participant.id == event.remoteParticipant.sid, + // orElse: () => null, + // ); + // if (participant != null) { + // print('Participant found: ${participant.id}, updating A/V enabled values'); + // _setRemoteVideoEnabled(event); + // _setRemoteAudioEnabled(event); + // } else { + // final bufferedParticipant = _participantBuffer.firstWhere( + // (ParticipantBuffer participant) => participant.id == event.remoteParticipant.sid, + // orElse: () => null, + // ); + // if (bufferedParticipant != null) { + // _participantBuffer.remove(bufferedParticipant); + // } else if (event is RemoteAudioTrackEvent) { + // print('Audio subscription came first, waiting for the video subscription...'); + // _participantBuffer.add( + // ParticipantBuffer( + // id: event.remoteParticipant.sid, + // audioEnabled: event.remoteAudioTrackPublication?.remoteAudioTrack?.isEnabled ?? true, + // ), + // ); + // return; + // } + // if (event is RemoteVideoTrackSubscriptionEvent) { + // print('New participant, adding: ${event.remoteParticipant.sid}'); + // _participants.insert( + // 0, + // _buildParticipant( + // child: event.remoteVideoTrack.widget(), + // id: event.remoteParticipant.sid, + // remoteParticipant: event.remoteParticipant, + // audioEnabled: bufferedParticipant?.audioEnabled ?? true, + // videoEnabled: event.remoteVideoTrackPublication?.remoteVideoTrack?.isEnabled ?? true, + // ), + // ); + // } + // notifyListeners(); + // } + // } } diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index ebb0305a..cafd1f06 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -96,10 +96,10 @@ class _HomePageState extends State { Container( margin: EdgeInsets.only( top: 15.0, left: 3.5, right: 3.5), - child: SvgPicture.asset( - 'assets/images/new-design/covid-19-car.svg', - width: 45.0, - height: 45.0), + // child: SvgPicture.asset( + // 'assets/images/new-design/covid-19-car.svg', + // width: 45.0, + // height: 45.0), ), Container( margin: EdgeInsets.only( @@ -173,11 +173,11 @@ class _HomePageState extends State { .withOpacity(0.3), borderRadius: BorderRadius.all( Radius.circular(5))), - child: SvgPicture.asset( - projectViewModel.isArabic - ? 'assets/images/new-design/livecare_arabic_logo.svg' - : 'assets/images/new-design/liveCare_white_logo.svg', - ), + // child: SvgPicture.asset( + // projectViewModel.isArabic + // ? 'assets/images/new-design/livecare_arabic_logo.svg' + // : 'assets/images/new-design/liveCare_white_logo.svg', + // ), ), ), ), @@ -686,7 +686,7 @@ class _HomePageState extends State { ), ), height: 100, - imageName: 'hmg_services_bg.png', + imageName: 'contact_us_bg.png', opacity: 0.5, color: Colors.grey[700], width: MediaQuery.of(context).size.width * 0.45, diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index dcfa3ba8..638e07ab 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -78,35 +78,35 @@ class _LandingPageState extends State with WidgetsBindingObserver { print(route.settings.name); } - setState(() { - print("didChangeAppLifecycleState"); - print('state = $state'); - AppGlobal.context = context; - if (state == AppLifecycleState.resumed) { - print(LandingPage.isOpenCallPage); - if (LandingPage.isOpenCallPage) { - if (!isPageNavigated) { - isPageNavigated = true; - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => IncomingCall( - incomingCallData: LandingPage.incomingCallData))) - .then((value) { - isPageNavigated = false; - }); - } - } - } - - if (state == AppLifecycleState.paused) { - isPageNavigated = false; - } - - if (state == AppLifecycleState.inactive) { - isPageNavigated = false; - } - }); + // setState(() { + // print("didChangeAppLifecycleState"); + // print('state = $state'); + // AppGlobal.context = context; + // if (state == AppLifecycleState.resumed) { + // print(LandingPage.isOpenCallPage); + // if (LandingPage.isOpenCallPage) { + // if (!isPageNavigated) { + // isPageNavigated = true; + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => IncomingCall( + // incomingCallData: LandingPage.incomingCallData))) + // .then((value) { + // isPageNavigated = false; + // }); + // } + // } + // } + // + // if (state == AppLifecycleState.paused) { + // isPageNavigated = false; + // } + // + // if (state == AppLifecycleState.inactive) { + // isPageNavigated = false; + // } + // }); } @override @@ -346,14 +346,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { }, ), actions: [ - IconButton( - iconSize: 70, - icon: SvgPicture.asset('assets/images/svg/robort_svg.svg', - height: 100, width: 100, fit: BoxFit.cover), - onPressed: () { - triggerRobot(); - } //do something, - ) + // IconButton( + // iconSize: 70, + // icon: SvgPicture.asset('assets/images/svg/robort_svg.svg', + // height: 100, width: 100, fit: BoxFit.cover), + // onPressed: () { + // triggerRobot(); + // } //do something, + // ) ], centerTitle: true, ), diff --git a/lib/pages/livecare/incoming_call.dart b/lib/pages/livecare/incoming_call.dart index de80b4ae..0f9208ea 100644 --- a/lib/pages/livecare/incoming_call.dart +++ b/lib/pages/livecare/incoming_call.dart @@ -213,13 +213,13 @@ class _IncomingCallState extends State token: widget.incomingCallData.sessionId, identity: widget.incomingCallData.identity); - await Navigator.of(context).push( - MaterialPageRoute( - fullscreenDialog: true, - builder: (BuildContext context) => - ConferencePage(roomModel: roomModel), - ), - ); + // await Navigator.of(context).push( + // MaterialPageRoute( + // fullscreenDialog: true, + // builder: (BuildContext context) => + // ConferencePage(roomModel: roomModel), + // ), + // ); } catch (err) { print(err); await PlatformExceptionAlertDialog( diff --git a/pubspec.yaml b/pubspec.yaml index f7e1e67a..0f46e89f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -144,7 +144,7 @@ dependencies: # recase: ^3.0.0 wakelock: ^0.1.4 after_layout: ^1.0.7 - twilio_programmable_video: ^0.5.0+3 + #twilio_programmable_video: ^0.5.0+3 flutter_tts: ^1.2.6 speech_to_text: From 57f938aa090c282e65eb6c6dd24621f68462242b Mon Sep 17 00:00:00 2001 From: jammal Date: Sun, 18 Oct 2020 14:47:33 +0300 Subject: [PATCH 2/2] fix ios issues --- ios/Podfile | 91 ++ ios/Runner/Base.lproj/Main.storyboard | 13 +- ios/Runner/Info.plist | 2 + lib/pages/conference/conference_page.dart | 776 +++++++-------- lib/pages/conference/conference_room.dart | 1042 ++++++++++----------- lib/pages/landing/landing_page.dart | 58 +- lib/pages/livecare/incoming_call.dart | 14 +- pubspec.yaml | 2 +- 8 files changed, 1047 insertions(+), 951 deletions(-) create mode 100644 ios/Podfile diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 00000000..c2702b3e --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,91 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '11.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +# pod 'FBSDKCoreKit' +# pod 'FBSDKLoginKit' + +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 + use_frameworks! + use_modular_headers! + + # 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 + +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/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index f3c28516..00abc512 100644 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -1,8 +1,10 @@ - - + + + - + + @@ -14,13 +16,14 @@ - + - + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index da3b2626..b807d9c6 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -22,6 +22,8 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + io.flutter.embedded_views_preview + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/lib/pages/conference/conference_page.dart b/lib/pages/conference/conference_page.dart index aec5d418..7848d4f7 100644 --- a/lib/pages/conference/conference_page.dart +++ b/lib/pages/conference/conference_page.dart @@ -1,388 +1,388 @@ -// import 'dart:async'; -// -// import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart'; -// import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart'; -// import 'package:diplomaticquarterapp/pages/conference/conference_room.dart'; -// import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart'; -// import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; -// import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; -// import 'package:diplomaticquarterapp/pages/conference/widgets/platform_alert_dialog.dart'; -// import 'package:flutter/material.dart'; -// import 'package:flutter/services.dart'; -// import 'package:wakelock/wakelock.dart'; -// -// class ConferencePage extends StatefulWidget { -// final RoomModel roomModel; -// -// const ConferencePage({Key key, this.roomModel}) : super(key: key); -// -// @override -// _ConferencePageState createState() => _ConferencePageState(); -// } -// -// class _ConferencePageState extends State { -// final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); -// final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); -// ConferenceRoom _conferenceRoom; -// StreamSubscription _onConferenceRoomException; -// -// @override -// void initState() { -// super.initState(); -// _lockInPortrait(); -// // _connectToRoom(); -// _wakeLock(true); -// } -// -// // void _connectToRoom() async { -// // try { -// // final conferenceRoom = ConferenceRoom( -// // name: widget.roomModel.name, -// // token: widget.roomModel.token, -// // identity: widget.roomModel.identity, -// // ); -// // await conferenceRoom.connect(); -// // setState(() { -// // _conferenceRoom = conferenceRoom; -// // _onConferenceRoomException = _conferenceRoom.onException.listen((err) async { -// // await PlatformAlertDialog( -// // title: err is PlatformException ? err.message : 'An error occured', -// // content: err is PlatformException ? err.details : err.toString(), -// // defaultActionText: 'OK', -// // ).show(context); -// // }); -// // _conferenceRoom.addListener(_conferenceRoomUpdated); -// // }); -// // } catch (err) { -// // print(err); -// // await PlatformAlertDialog( -// // title: err is PlatformException ? err.message : 'An error occured', -// // content: err is PlatformException ? err.details : err.toString(), -// // defaultActionText: 'OK', -// // ).show(context); -// // -// // Navigator.of(context).pop(); -// // } -// // } -// -// Future _lockInPortrait() async { -// await SystemChrome.setPreferredOrientations([ -// DeviceOrientation.portraitUp, -// DeviceOrientation.portraitDown, -// ]); -// } -// -// @override -// void dispose() { -// _freePortraitLock(); -// _wakeLock(false); -// _disposeStreamsAndSubscriptions(); -// if (_conferenceRoom != null) _conferenceRoom.removeListener(_conferenceRoomUpdated); -// super.dispose(); -// } -// -// Future _freePortraitLock() async { -// await SystemChrome.setPreferredOrientations([ -// DeviceOrientation.landscapeRight, -// DeviceOrientation.landscapeLeft, -// DeviceOrientation.portraitUp, -// DeviceOrientation.portraitDown, -// ]); -// } -// -// Future _disposeStreamsAndSubscriptions() async { -// if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); -// if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); -// if (_onConferenceRoomException != null) await _onConferenceRoomException.cancel(); -// } -// -// @override -// Widget build(BuildContext context) { -// return WillPopScope( -// onWillPop: () async => false, -// child: Scaffold( -// backgroundColor: Colors.black, -// body: _conferenceRoom == null ? showProgress() : buildLayout(), -// ), -// ); -// } -// -// LayoutBuilder buildLayout() { -// return LayoutBuilder( -// builder: (BuildContext context, BoxConstraints constraints) { -// return Stack( -// children: [ -// _buildParticipants(context, constraints.biggest, _conferenceRoom), -// ConferenceButtonBar( -// audioEnabled: _conferenceRoom.onAudioEnabled, -// videoEnabled: _conferenceRoom.onVideoEnabled, -// onAudioEnabled: _conferenceRoom.toggleAudioEnabled, -// onVideoEnabled: _conferenceRoom.toggleVideoEnabled, -// onHangup: _onHangup, -// onSwitchCamera: _conferenceRoom.switchCamera, -// onPersonAdd: _onPersonAdd, -// onPersonRemove: _onPersonRemove, -// onHeight: _onHeightBar, -// onShow: _onShowBar, -// onHide: _onHideBar, -// ), -// ], -// ); -// }, -// ); -// } -// -// Widget showProgress() { -// return Column( -// mainAxisAlignment: MainAxisAlignment.center, -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// Center(child: CircularProgressIndicator()), -// SizedBox( -// height: 10, -// ), -// Text( -// 'Connecting to the call...', -// style: TextStyle(color: Colors.white), -// ), -// ], -// ); -// } -// -// Future _onHangup() async { -// print('onHangup'); -// await _conferenceRoom.disconnect(); -// Navigator.of(context).pop(); -// } -// -// void _onPersonAdd() { -// print('onPersonAdd'); -// try { -// _conferenceRoom.addDummy( -// child: Stack( -// children: [ -// const Placeholder(), -// Center( -// child: Text( -// (_conferenceRoom.participants.length + 1).toString(), -// style: const TextStyle( -// shadows: [ -// Shadow( -// blurRadius: 3.0, -// color: Color.fromARGB(255, 0, 0, 0), -// ), -// Shadow( -// blurRadius: 8.0, -// color: Color.fromARGB(255, 255, 255, 255), -// ), -// ], -// fontSize: 80, -// ), -// ), -// ), -// ], -// ), -// ); -// } on PlatformException catch (err) { -// PlatformAlertDialog( -// title: err.message, -// content: err.details, -// defaultActionText: 'OK', -// ).show(context); -// } -// } -// -// void _onPersonRemove() { -// print('onPersonRemove'); -// _conferenceRoom.removeDummy(); -// } -// -// Widget _buildParticipants(BuildContext context, Size size, ConferenceRoom conferenceRoom) { -// final children = []; -// final length = conferenceRoom.participants.length; -// -// if (length <= 2) { -// _buildOverlayLayout(context, size, children); -// return Stack(children: children); -// } -// -// void buildInCols(bool removeLocalBeforeChunking, bool moveLastOfEachRowToNextRow, int columns) { -// _buildLayoutInGrid( -// context, -// size, -// children, -// removeLocalBeforeChunking: removeLocalBeforeChunking, -// moveLastOfEachRowToNextRow: moveLastOfEachRowToNextRow, -// columns: columns, -// ); -// } -// -// // if (length <= 3) { -// // buildInCols(true, false, 1); -// // } else if (length == 5) { -// // buildInCols(false, true, 2); -// // } else if (length <= 6 || length == 8) { -// // buildInCols(false, false, 2); -// // } else if (length == 7 || length == 9) { -// // buildInCols(true, false, 2); -// // } else if (length == 10) { -// // buildInCols(false, true, 3); -// // } else if (length == 13 || length == 16) { -// // buildInCols(true, false, 3); -// // } else if (length <= 18) { -// // buildInCols(false, false, 3); -// // } -// -// return Column( -// children: children, -// ); -// } -// -// void _buildOverlayLayout(BuildContext context, Size size, List children) { -// final participants = _conferenceRoom.participants; -// if (participants.length == 1) { -// children.add(_buildNoiseBox()); -// } else { -// final remoteParticipant = participants.firstWhere((ParticipantWidget participant) => participant.isRemote, orElse: () => null); -// if (remoteParticipant != null) { -// children.add(remoteParticipant); -// } -// } -// -// final localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); -// if (localParticipant != null) { -// children.add(DraggablePublisher( -// key: Key('publisher'), -// child: localParticipant, -// availableScreenSize: size, -// onButtonBarVisible: _onButtonBarVisibleStreamController.stream, -// onButtonBarHeight: _onButtonBarHeightStreamController.stream, -// )); -// } -// } -// -// void _buildLayoutInGrid( -// BuildContext context, -// Size size, -// List children, { -// bool removeLocalBeforeChunking = false, -// bool moveLastOfEachRowToNextRow = false, -// int columns = 2, -// }) { -// final participants = _conferenceRoom.participants; -// ParticipantWidget localParticipant; -// if (removeLocalBeforeChunking) { -// localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); -// if (localParticipant != null) { -// participants.remove(localParticipant); -// } -// } -// final chunkedParticipants = chunk(array: participants, size: columns); -// if (localParticipant != null) { -// chunkedParticipants.last.add(localParticipant); -// participants.add(localParticipant); -// } -// -// if (moveLastOfEachRowToNextRow) { -// for (var i = 0; i < chunkedParticipants.length - 1; i++) { -// var participant = chunkedParticipants[i].removeLast(); -// chunkedParticipants[i + 1].insert(0, participant); -// } -// } -// -// for (final participantChunk in chunkedParticipants) { -// final rowChildren = []; -// for (final participant in participantChunk) { -// rowChildren.add( -// Container( -// width: size.width / participantChunk.length, -// height: size.height / chunkedParticipants.length, -// child: participant, -// ), -// ); -// } -// children.add( -// Container( -// height: size.height / chunkedParticipants.length, -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceEvenly, -// children: rowChildren, -// ), -// ), -// ); -// } -// } -// -// NoiseBox _buildNoiseBox() { -// return NoiseBox( -// density: NoiseBoxDensity.xLow, -// backgroundColor: Colors.grey.shade900, -// child: Center( -// child: Container( -// color: Colors.black54, -// width: double.infinity, -// height: 40, -// child: Center( -// child: Text( -// 'Waiting for another participant to connect to the call...', -// key: Key('text-wait'), -// textAlign: TextAlign.center, -// style: TextStyle(color: Colors.white), -// ), -// ), -// ), -// ), -// ); -// } -// -// List> chunk({@required List array, @required int size}) { -// final result = >[]; -// if (array.isEmpty || size <= 0) { -// return result; -// } -// var first = 0; -// var last = size; -// final totalLoop = array.length % size == 0 ? array.length ~/ size : array.length ~/ size + 1; -// for (var i = 0; i < totalLoop; i++) { -// if (last > array.length) { -// result.add(array.sublist(first, array.length)); -// } else { -// result.add(array.sublist(first, last)); -// } -// first = last; -// last = last + size; -// } -// return result; -// } -// -// void _onHeightBar(double height) { -// _onButtonBarHeightStreamController.add(height); -// } -// -// void _onShowBar() { -// setState(() { -// SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]); -// }); -// _onButtonBarVisibleStreamController.add(true); -// } -// -// void _onHideBar() { -// setState(() { -// SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); -// }); -// _onButtonBarVisibleStreamController.add(false); -// } -// -// Future _wakeLock(bool enable) async { -// try { -// return await (enable ? Wakelock.enable() : Wakelock.disable()); -// } catch (err) { -// print('Unable to change the Wakelock and set it to $enable'); -// print(err); -// } -// } -// -// void _conferenceRoomUpdated() { -// setState(() {}); -// } -// } +import 'dart:async'; + +import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart'; +import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart'; +import 'package:diplomaticquarterapp/pages/conference/conference_room.dart'; +import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart'; +import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; +import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; +import 'package:diplomaticquarterapp/pages/conference/widgets/platform_alert_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:wakelock/wakelock.dart'; + +class ConferencePage extends StatefulWidget { + final RoomModel roomModel; + + const ConferencePage({Key key, this.roomModel}) : super(key: key); + + @override + _ConferencePageState createState() => _ConferencePageState(); +} + +class _ConferencePageState extends State { + final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); + final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); + ConferenceRoom _conferenceRoom; + StreamSubscription _onConferenceRoomException; + + @override + void initState() { + super.initState(); + _lockInPortrait(); + _connectToRoom(); + _wakeLock(true); + } + + void _connectToRoom() async { + try { + final conferenceRoom = ConferenceRoom( + name: widget.roomModel.name, + token: widget.roomModel.token, + identity: widget.roomModel.identity, + ); + await conferenceRoom.connect(); + setState(() { + _conferenceRoom = conferenceRoom; + _onConferenceRoomException = _conferenceRoom.onException.listen((err) async { + await PlatformAlertDialog( + title: err is PlatformException ? err.message : 'An error occured', + content: err is PlatformException ? err.details : err.toString(), + defaultActionText: 'OK', + ).show(context); + }); + _conferenceRoom.addListener(_conferenceRoomUpdated); + }); + } catch (err) { + print(err); + await PlatformAlertDialog( + title: err is PlatformException ? err.message : 'An error occured', + content: err is PlatformException ? err.details : err.toString(), + defaultActionText: 'OK', + ).show(context); + + Navigator.of(context).pop(); + } + } + + Future _lockInPortrait() async { + await SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); + } + + @override + void dispose() { + _freePortraitLock(); + _wakeLock(false); + _disposeStreamsAndSubscriptions(); + if (_conferenceRoom != null) _conferenceRoom.removeListener(_conferenceRoomUpdated); + super.dispose(); + } + + Future _freePortraitLock() async { + await SystemChrome.setPreferredOrientations([ + DeviceOrientation.landscapeRight, + DeviceOrientation.landscapeLeft, + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); + } + + Future _disposeStreamsAndSubscriptions() async { + if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); + if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); + if (_onConferenceRoomException != null) await _onConferenceRoomException.cancel(); + } + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async => false, + child: Scaffold( + backgroundColor: Colors.black, + body: _conferenceRoom == null ? showProgress() : buildLayout(), + ), + ); + } + + LayoutBuilder buildLayout() { + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return Stack( + children: [ + _buildParticipants(context, constraints.biggest, _conferenceRoom), + ConferenceButtonBar( + audioEnabled: _conferenceRoom.onAudioEnabled, + videoEnabled: _conferenceRoom.onVideoEnabled, + onAudioEnabled: _conferenceRoom.toggleAudioEnabled, + onVideoEnabled: _conferenceRoom.toggleVideoEnabled, + onHangup: _onHangup, + onSwitchCamera: _conferenceRoom.switchCamera, + onPersonAdd: _onPersonAdd, + onPersonRemove: _onPersonRemove, + onHeight: _onHeightBar, + onShow: _onShowBar, + onHide: _onHideBar, + ), + ], + ); + }, + ); + } + + Widget showProgress() { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Center(child: CircularProgressIndicator()), + SizedBox( + height: 10, + ), + Text( + 'Connecting to the call...', + style: TextStyle(color: Colors.white), + ), + ], + ); + } + + Future _onHangup() async { + print('onHangup'); + await _conferenceRoom.disconnect(); + Navigator.of(context).pop(); + } + + void _onPersonAdd() { + print('onPersonAdd'); + try { + _conferenceRoom.addDummy( + child: Stack( + children: [ + const Placeholder(), + Center( + child: Text( + (_conferenceRoom.participants.length + 1).toString(), + style: const TextStyle( + shadows: [ + Shadow( + blurRadius: 3.0, + color: Color.fromARGB(255, 0, 0, 0), + ), + Shadow( + blurRadius: 8.0, + color: Color.fromARGB(255, 255, 255, 255), + ), + ], + fontSize: 80, + ), + ), + ), + ], + ), + ); + } on PlatformException catch (err) { + PlatformAlertDialog( + title: err.message, + content: err.details, + defaultActionText: 'OK', + ).show(context); + } + } + + void _onPersonRemove() { + print('onPersonRemove'); + _conferenceRoom.removeDummy(); + } + + Widget _buildParticipants(BuildContext context, Size size, ConferenceRoom conferenceRoom) { + final children = []; + final length = conferenceRoom.participants.length; + + if (length <= 2) { + _buildOverlayLayout(context, size, children); + return Stack(children: children); + } + + void buildInCols(bool removeLocalBeforeChunking, bool moveLastOfEachRowToNextRow, int columns) { + _buildLayoutInGrid( + context, + size, + children, + removeLocalBeforeChunking: removeLocalBeforeChunking, + moveLastOfEachRowToNextRow: moveLastOfEachRowToNextRow, + columns: columns, + ); + } + +// if (length <= 3) { +// buildInCols(true, false, 1); +// } else if (length == 5) { +// buildInCols(false, true, 2); +// } else if (length <= 6 || length == 8) { +// buildInCols(false, false, 2); +// } else if (length == 7 || length == 9) { +// buildInCols(true, false, 2); +// } else if (length == 10) { +// buildInCols(false, true, 3); +// } else if (length == 13 || length == 16) { +// buildInCols(true, false, 3); +// } else if (length <= 18) { +// buildInCols(false, false, 3); +// } + + return Column( + children: children, + ); + } + + void _buildOverlayLayout(BuildContext context, Size size, List children) { + final participants = _conferenceRoom.participants; + if (participants.length == 1) { + children.add(_buildNoiseBox()); + } else { + final remoteParticipant = participants.firstWhere((ParticipantWidget participant) => participant.isRemote, orElse: () => null); + if (remoteParticipant != null) { + children.add(remoteParticipant); + } + } + + final localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); + if (localParticipant != null) { + children.add(DraggablePublisher( + key: Key('publisher'), + child: localParticipant, + availableScreenSize: size, + onButtonBarVisible: _onButtonBarVisibleStreamController.stream, + onButtonBarHeight: _onButtonBarHeightStreamController.stream, + )); + } + } + + void _buildLayoutInGrid( + BuildContext context, + Size size, + List children, { + bool removeLocalBeforeChunking = false, + bool moveLastOfEachRowToNextRow = false, + int columns = 2, + }) { + final participants = _conferenceRoom.participants; + ParticipantWidget localParticipant; + if (removeLocalBeforeChunking) { + localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); + if (localParticipant != null) { + participants.remove(localParticipant); + } + } + final chunkedParticipants = chunk(array: participants, size: columns); + if (localParticipant != null) { + chunkedParticipants.last.add(localParticipant); + participants.add(localParticipant); + } + + if (moveLastOfEachRowToNextRow) { + for (var i = 0; i < chunkedParticipants.length - 1; i++) { + var participant = chunkedParticipants[i].removeLast(); + chunkedParticipants[i + 1].insert(0, participant); + } + } + + for (final participantChunk in chunkedParticipants) { + final rowChildren = []; + for (final participant in participantChunk) { + rowChildren.add( + Container( + width: size.width / participantChunk.length, + height: size.height / chunkedParticipants.length, + child: participant, + ), + ); + } + children.add( + Container( + height: size.height / chunkedParticipants.length, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: rowChildren, + ), + ), + ); + } + } + + NoiseBox _buildNoiseBox() { + return NoiseBox( + density: NoiseBoxDensity.xLow, + backgroundColor: Colors.grey.shade900, + child: Center( + child: Container( + color: Colors.black54, + width: double.infinity, + height: 40, + child: Center( + child: Text( + 'Waiting for another participant to connect to the call...', + key: Key('text-wait'), + textAlign: TextAlign.center, + style: TextStyle(color: Colors.white), + ), + ), + ), + ), + ); + } + + List> chunk({@required List array, @required int size}) { + final result = >[]; + if (array.isEmpty || size <= 0) { + return result; + } + var first = 0; + var last = size; + final totalLoop = array.length % size == 0 ? array.length ~/ size : array.length ~/ size + 1; + for (var i = 0; i < totalLoop; i++) { + if (last > array.length) { + result.add(array.sublist(first, array.length)); + } else { + result.add(array.sublist(first, last)); + } + first = last; + last = last + size; + } + return result; + } + + void _onHeightBar(double height) { + _onButtonBarHeightStreamController.add(height); + } + + void _onShowBar() { + setState(() { + SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]); + }); + _onButtonBarVisibleStreamController.add(true); + } + + void _onHideBar() { + setState(() { + SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); + }); + _onButtonBarVisibleStreamController.add(false); + } + + Future _wakeLock(bool enable) async { + try { + return await (enable ? Wakelock.enable() : Wakelock.disable()); + } catch (err) { + print('Unable to change the Wakelock and set it to $enable'); + print(err); + } + } + + void _conferenceRoomUpdated() { + setState(() {}); + } +} diff --git a/lib/pages/conference/conference_room.dart b/lib/pages/conference/conference_room.dart index a88c3bdb..9c8c1c9a 100644 --- a/lib/pages/conference/conference_room.dart +++ b/lib/pages/conference/conference_room.dart @@ -4,527 +4,527 @@ import 'dart:typed_data'; import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -// import 'package:twilio_programmable_video/twilio_programmable_video.dart'; +import 'package:twilio_programmable_video/twilio_programmable_video.dart'; class ConferenceRoom with ChangeNotifier { - // final String name; - // final String token; - // final String identity; - // - // final StreamController _onAudioEnabledStreamController = StreamController.broadcast(); - // Stream onAudioEnabled; - // final StreamController _onVideoEnabledStreamController = StreamController.broadcast(); - // Stream onVideoEnabled; - // final StreamController _onExceptionStreamController = StreamController.broadcast(); - // Stream onException; - // - // final Completer _completer = Completer(); - // - // final List _participants = []; - // final List _participantBuffer = []; - // final List _streamSubscriptions = []; - // final List _dataTracks = []; - // final List _messages = []; - // - // CameraCapturer _cameraCapturer; - // Room _room; - // Timer _timer; - // - // ConferenceRoom({ - // @required this.name, - // @required this.token, - // @required this.identity, - // }) { - // onAudioEnabled = _onAudioEnabledStreamController.stream; - // onVideoEnabled = _onVideoEnabledStreamController.stream; - // onException = _onExceptionStreamController.stream; - // } - // - // List get participants { - // return [..._participants]; - // } - // - // Future connect() async { - // print('ConferenceRoom.connect()'); - // try { - // await TwilioProgrammableVideo.debug(dart: true, native: true); - // await TwilioProgrammableVideo.setSpeakerphoneOn(true); - // - // _cameraCapturer = CameraCapturer(CameraSource.FRONT_CAMERA); - // var connectOptions = ConnectOptions( - // token, - // roomName: name, - // preferredAudioCodecs: [OpusCodec()], - // audioTracks: [LocalAudioTrack(true)], - // dataTracks: [LocalDataTrack()], - // videoTracks: [LocalVideoTrack(true, _cameraCapturer)], - // enableDominantSpeaker: true, - // ); - // - // _room = await TwilioProgrammableVideo.connect(connectOptions); - // - // _streamSubscriptions.add(_room.onConnected.listen(_onConnected)); - // _streamSubscriptions.add(_room.onConnectFailure.listen(_onConnectFailure)); - // - // return _completer.future; - // } catch (err) { - // print(err); - // rethrow; - // } - // } - // - // Future disconnect() async { - // print('ConferenceRoom.disconnect()'); - // if (_timer != null) { - // _timer.cancel(); - // } - // await _room.disconnect(); - // } - // - // @override - // void dispose() { - // print('ConferenceRoom.dispose()'); - // _disposeStreamsAndSubscriptions(); - // super.dispose(); - // } - // - // Future _disposeStreamsAndSubscriptions() async { - // await _onAudioEnabledStreamController.close(); - // await _onVideoEnabledStreamController.close(); - // await _onExceptionStreamController.close(); - // for (var streamSubscription in _streamSubscriptions) { - // await streamSubscription.cancel(); - // } - // } - // - // Future sendMessage(String message) async { - // final tracks = _room.localParticipant.localDataTracks; - // final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; - // if (localDataTrack == null || _messages.isNotEmpty) { - // print('ConferenceRoom.sendMessage => Track is not available yet, buffering message.'); - // _messages.add(message); - // return; - // } - // await localDataTrack.send(message); - // } - // - // Future sendBufferMessage(ByteBuffer message) async { - // final tracks = _room.localParticipant.localDataTracks; - // final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; - // if (localDataTrack == null) { - // return; - // } - // await localDataTrack.sendBuffer(message); - // } - // - // Future toggleVideoEnabled() async { - // final tracks = _room.localParticipant.localVideoTracks; - // final localVideoTrack = tracks.isEmpty ? null : tracks[0].localVideoTrack; - // if (localVideoTrack == null) { - // print('ConferenceRoom.toggleVideoEnabled() => Track is not available yet!'); - // return; - // } - // await localVideoTrack.enable(!localVideoTrack.isEnabled); - // - // var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); - // if (index < 0) { - // return; - // } - // var participant = _participants[index]; - // _participants.replaceRange( - // index, - // index + 1, - // [ - // participant.copyWith(videoEnabled: localVideoTrack.isEnabled), - // ], - // ); - // print('ConferenceRoom.toggleVideoEnabled() => ${localVideoTrack.isEnabled}'); - // _onVideoEnabledStreamController.add(localVideoTrack.isEnabled); - // notifyListeners(); - // } - // - // Future toggleAudioEnabled() async { - // final tracks = _room.localParticipant.localAudioTracks; - // final localAudioTrack = tracks.isEmpty ? null : tracks[0].localAudioTrack; - // if (localAudioTrack == null) { - // print('ConferenceRoom.toggleAudioEnabled() => Track is not available yet!'); - // return; - // } - // await localAudioTrack.enable(!localAudioTrack.isEnabled); - // - // var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); - // if (index < 0) { - // return; - // } - // var participant = _participants[index]; - // _participants.replaceRange( - // index, - // index + 1, - // [ - // participant.copyWith(audioEnabled: localAudioTrack.isEnabled), - // ], - // ); - // print('ConferenceRoom.toggleAudioEnabled() => ${localAudioTrack.isEnabled}'); - // _onAudioEnabledStreamController.add(localAudioTrack.isEnabled); - // notifyListeners(); - // } - // - // Future switchCamera() async { - // print('ConferenceRoom.switchCamera()'); - // try { - // await _cameraCapturer.switchCamera(); - // } on FormatException catch (e) { - // print( - // 'ConferenceRoom.switchCamera() failed because of FormatException with message: ${e.message}', - // ); - // } - // } - // - // void addDummy({Widget child}) { - // print('ConferenceRoom.addDummy()'); - // if (_participants.length >= 18) { - // throw PlatformException( - // code: 'ConferenceRoom.maximumReached', - // message: 'Maximum reached', - // details: 'Currently the lay-out can only render a maximum of 18 participants', - // ); - // } - // _participants.insert( - // 0, - // ParticipantWidget( - // id: (_participants.length + 1).toString(), - // child: child, - // isRemote: true, - // audioEnabled: true, - // videoEnabled: true, - // isDummy: true, - // ), - // ); - // notifyListeners(); - // } - // - // void removeDummy() { - // print('ConferenceRoom.removeDummy()'); - // var dummy = _participants.firstWhere((participant) => participant.isDummy, orElse: () => null); - // if (dummy != null) { - // _participants.remove(dummy); - // notifyListeners(); - // } - // } - // - // void _onConnected(Room room) { - // print('ConferenceRoom._onConnected => state: ${room.state}'); - // - // // When connected for the first time, add remote participant listeners - // _streamSubscriptions.add(_room.onParticipantConnected.listen(_onParticipantConnected)); - // _streamSubscriptions.add(_room.onParticipantDisconnected.listen(_onParticipantDisconnected)); - // _streamSubscriptions.add(_room.onDominantSpeakerChange.listen(_onDominantSpeakerChanged)); - // // Only add ourselves when connected for the first time too. - // _participants.add( - // _buildParticipant( - // child: room.localParticipant.localVideoTracks[0].localVideoTrack.widget(), - // id: identity, - // audioEnabled: true, - // videoEnabled: true, - // ), - // ); - // for (final remoteParticipant in room.remoteParticipants) { - // var participant = _participants.firstWhere((participant) => participant.id == remoteParticipant.sid, orElse: () => null); - // if (participant == null) { - // print('Adding participant that was already present in the room ${remoteParticipant.sid}, before I connected'); - // _addRemoteParticipantListeners(remoteParticipant); - // } - // } - // // We have to listen for the [onDataTrackPublished] event on the [LocalParticipant] in - // // order to be able to use the [send] method. - // _streamSubscriptions.add(room.localParticipant.onDataTrackPublished.listen(_onLocalDataTrackPublished)); - // notifyListeners(); - // _completer.complete(room); - // - // _timer = Timer.periodic(const Duration(minutes: 1), (_) { - // // Let's see if we can send some data over the DataTrack API - // sendMessage('And another minute has passed since I connected...'); - // // Also try the ByteBuffer way of sending data - // final list = 'This data has been sent over the ByteBuffer channel of the DataTrack API'.codeUnits; - // var bytes = Uint8List.fromList(list); - // sendBufferMessage(bytes.buffer); - // }); - // } - // - // void _onLocalDataTrackPublished(LocalDataTrackPublishedEvent event) { - // // Send buffered messages, if any... - // while (_messages.isNotEmpty) { - // var message = _messages.removeAt(0); - // print('Sending buffered message: $message'); - // event.localDataTrackPublication.localDataTrack.send(message); - // } - // } - // - // void _onConnectFailure(RoomConnectFailureEvent event) { - // print('ConferenceRoom._onConnectFailure: ${event.exception}'); - // _completer.completeError(event.exception); - // } - // - // void _onDominantSpeakerChanged(DominantSpeakerChangedEvent event) { - // print('ConferenceRoom._onDominantSpeakerChanged: ${event.remoteParticipant.identity}'); - // var oldDominantParticipant = _participants.firstWhere((p) => p.isDominant, orElse: () => null); - // if (oldDominantParticipant != null) { - // var oldDominantParticipantIndex = _participants.indexOf(oldDominantParticipant); - // _participants.replaceRange(oldDominantParticipantIndex, oldDominantParticipantIndex + 1, [oldDominantParticipant.copyWith(isDominant: false)]); - // } - // - // var newDominantParticipant = _participants.firstWhere((p) => p.id == event.remoteParticipant.sid); - // var newDominantParticipantIndex = _participants.indexOf(newDominantParticipant); - // _participants.replaceRange(newDominantParticipantIndex, newDominantParticipantIndex + 1, [newDominantParticipant.copyWith(isDominant: true)]); - // notifyListeners(); - // } - // - // void _onParticipantConnected(RoomParticipantConnectedEvent event) { - // print('ConferenceRoom._onParticipantConnected, ${event.remoteParticipant.sid}'); - // _addRemoteParticipantListeners(event.remoteParticipant); - // } - // - // void _onParticipantDisconnected(RoomParticipantDisconnectedEvent event) { - // print('ConferenceRoom._onParticipantDisconnected: ${event.remoteParticipant.sid}'); - // _participants.removeWhere((ParticipantWidget p) => p.id == event.remoteParticipant.sid); - // notifyListeners(); - // } - // - // ParticipantWidget _buildParticipant({ - // @required Widget child, - // @required String id, - // @required bool audioEnabled, - // @required bool videoEnabled, - // RemoteParticipant remoteParticipant, - // }) { - // return ParticipantWidget( - // id: remoteParticipant?.sid, - // isRemote: remoteParticipant != null, - // child: child, - // audioEnabled: audioEnabled, - // videoEnabled: videoEnabled, - // ); - // } - // - // void _addRemoteParticipantListeners(RemoteParticipant remoteParticipant) { - // print('ConferenceRoom._addRemoteParticipantListeners() => Adding listeners to remoteParticipant ${remoteParticipant.sid}'); - // _streamSubscriptions.add(remoteParticipant.onAudioTrackDisabled.listen(_onAudioTrackDisabled)); - // _streamSubscriptions.add(remoteParticipant.onAudioTrackEnabled.listen(_onAudioTrackEnabled)); - // _streamSubscriptions.add(remoteParticipant.onAudioTrackPublished.listen(_onAudioTrackPublished)); - // _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscribed.listen(_onAudioTrackSubscribed)); - // _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscriptionFailed.listen(_onAudioTrackSubscriptionFailed)); - // _streamSubscriptions.add(remoteParticipant.onAudioTrackUnpublished.listen(_onAudioTrackUnpublished)); - // _streamSubscriptions.add(remoteParticipant.onAudioTrackUnsubscribed.listen(_onAudioTrackUnsubscribed)); - // - // _streamSubscriptions.add(remoteParticipant.onDataTrackPublished.listen(_onDataTrackPublished)); - // _streamSubscriptions.add(remoteParticipant.onDataTrackSubscribed.listen(_onDataTrackSubscribed)); - // _streamSubscriptions.add(remoteParticipant.onDataTrackSubscriptionFailed.listen(_onDataTrackSubscriptionFailed)); - // _streamSubscriptions.add(remoteParticipant.onDataTrackUnpublished.listen(_onDataTrackUnpublished)); - // _streamSubscriptions.add(remoteParticipant.onDataTrackUnsubscribed.listen(_onDataTrackUnsubscribed)); - // - // _streamSubscriptions.add(remoteParticipant.onVideoTrackDisabled.listen(_onVideoTrackDisabled)); - // _streamSubscriptions.add(remoteParticipant.onVideoTrackEnabled.listen(_onVideoTrackEnabled)); - // _streamSubscriptions.add(remoteParticipant.onVideoTrackPublished.listen(_onVideoTrackPublished)); - // _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscribed.listen(_onVideoTrackSubscribed)); - // _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscriptionFailed.listen(_onVideoTrackSubscriptionFailed)); - // _streamSubscriptions.add(remoteParticipant.onVideoTrackUnpublished.listen(_onVideoTrackUnpublished)); - // _streamSubscriptions.add(remoteParticipant.onVideoTrackUnsubscribed.listen(_onVideoTrackUnsubscribed)); - // } - // - // void _onAudioTrackDisabled(RemoteAudioTrackEvent event) { - // print('ConferenceRoom._onAudioTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); - // _setRemoteAudioEnabled(event); - // } - // - // void _onAudioTrackEnabled(RemoteAudioTrackEvent event) { - // print('ConferenceRoom._onAudioTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); - // _setRemoteAudioEnabled(event); - // } - // - // void _onAudioTrackPublished(RemoteAudioTrackEvent event) { - // print('ConferenceRoom._onAudioTrackPublished(), ${event.remoteParticipant.sid}}'); - // } - // - // void _onAudioTrackSubscribed(RemoteAudioTrackSubscriptionEvent event) { - // print('ConferenceRoom._onAudioTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - // _addOrUpdateParticipant(event); - // } - // - // void _onAudioTrackSubscriptionFailed(RemoteAudioTrackSubscriptionFailedEvent event) { - // print('ConferenceRoom._onAudioTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - // _onExceptionStreamController.add( - // PlatformException( - // code: 'ConferenceRoom.audioTrackSubscriptionFailed', - // message: 'AudioTrack Subscription Failed', - // details: event.exception.toString(), - // ), - // ); - // } - // - // void _onAudioTrackUnpublished(RemoteAudioTrackEvent event) { - // print('ConferenceRoom._onAudioTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - // } - // - // void _onAudioTrackUnsubscribed(RemoteAudioTrackSubscriptionEvent event) { - // print('ConferenceRoom._onAudioTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrack.sid}'); - // } - // - // void _onDataTrackPublished(RemoteDataTrackEvent event) { - // print('ConferenceRoom._onDataTrackPublished(), ${event.remoteParticipant.sid}}'); - // } - // - // void _onDataTrackSubscribed(RemoteDataTrackSubscriptionEvent event) { - // print('ConferenceRoom._onDataTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - // final dataTrack = event.remoteDataTrackPublication.remoteDataTrack; - // _dataTracks.add(dataTrack); - // _streamSubscriptions.add(dataTrack.onMessage.listen(_onMessage)); - // _streamSubscriptions.add(dataTrack.onBufferMessage.listen(_onBufferMessage)); - // } - // - // void _onDataTrackSubscriptionFailed(RemoteDataTrackSubscriptionFailedEvent event) { - // print('ConferenceRoom._onDataTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - // _onExceptionStreamController.add( - // PlatformException( - // code: 'ConferenceRoom.dataTrackSubscriptionFailed', - // message: 'DataTrack Subscription Failed', - // details: event.exception.toString(), - // ), - // ); - // } - // - // void _onDataTrackUnpublished(RemoteDataTrackEvent event) { - // print('ConferenceRoom._onDataTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - // } - // - // void _onDataTrackUnsubscribed(RemoteDataTrackSubscriptionEvent event) { - // print('ConferenceRoom._onDataTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrack.sid}'); - // } - // - // void _onVideoTrackDisabled(RemoteVideoTrackEvent event) { - // print('ConferenceRoom._onVideoTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); - // _setRemoteVideoEnabled(event); - // } - // - // void _onVideoTrackEnabled(RemoteVideoTrackEvent event) { - // print('ConferenceRoom._onVideoTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); - // _setRemoteVideoEnabled(event); - // } - // - // void _onVideoTrackPublished(RemoteVideoTrackEvent event) { - // print('ConferenceRoom._onVideoTrackPublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - // } - // - // void _onVideoTrackSubscribed(RemoteVideoTrackSubscriptionEvent event) { - // print('ConferenceRoom._onVideoTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); - // _addOrUpdateParticipant(event); - // } - // - // void _onVideoTrackSubscriptionFailed(RemoteVideoTrackSubscriptionFailedEvent event) { - // print('ConferenceRoom._onVideoTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - // _onExceptionStreamController.add( - // PlatformException( - // code: 'ConferenceRoom.videoTrackSubscriptionFailed', - // message: 'VideoTrack Subscription Failed', - // details: event.exception.toString(), - // ), - // ); - // } - // - // void _onVideoTrackUnpublished(RemoteVideoTrackEvent event) { - // print('ConferenceRoom._onVideoTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - // } - // - // void _onVideoTrackUnsubscribed(RemoteVideoTrackSubscriptionEvent event) { - // print('ConferenceRoom._onVideoTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); - // } - // - // void _onMessage(RemoteDataTrackStringMessageEvent event) { - // print('onMessage => ${event.remoteDataTrack.sid}, ${event.message}'); - // } - // - // void _onBufferMessage(RemoteDataTrackBufferMessageEvent event) { - // print('onBufferMessage => ${event.remoteDataTrack.sid}, ${String.fromCharCodes(event.message.asUint8List())}'); - // } - // - // void _setRemoteAudioEnabled(RemoteAudioTrackEvent event) { - // if (event.remoteAudioTrackPublication == null) { - // return; - // } - // var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); - // if (index < 0) { - // return; - // } - // var participant = _participants[index]; - // _participants.replaceRange( - // index, - // index + 1, - // [ - // participant.copyWith(audioEnabled: event.remoteAudioTrackPublication.isTrackEnabled), - // ], - // ); - // notifyListeners(); - // } - // - // void _setRemoteVideoEnabled(RemoteVideoTrackEvent event) { - // if (event.remoteVideoTrackPublication == null) { - // return; - // } - // var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); - // if (index < 0) { - // return; - // } - // var participant = _participants[index]; - // _participants.replaceRange( - // index, - // index + 1, - // [ - // participant.copyWith(videoEnabled: event.remoteVideoTrackPublication.isTrackEnabled), - // ], - // ); - // notifyListeners(); - // } - // - // void _addOrUpdateParticipant(RemoteParticipantEvent event) { - // print('ConferenceRoom._addOrUpdateParticipant(), ${event.remoteParticipant.sid}'); - // final participant = _participants.firstWhere( - // (ParticipantWidget participant) => participant.id == event.remoteParticipant.sid, - // orElse: () => null, - // ); - // if (participant != null) { - // print('Participant found: ${participant.id}, updating A/V enabled values'); - // _setRemoteVideoEnabled(event); - // _setRemoteAudioEnabled(event); - // } else { - // final bufferedParticipant = _participantBuffer.firstWhere( - // (ParticipantBuffer participant) => participant.id == event.remoteParticipant.sid, - // orElse: () => null, - // ); - // if (bufferedParticipant != null) { - // _participantBuffer.remove(bufferedParticipant); - // } else if (event is RemoteAudioTrackEvent) { - // print('Audio subscription came first, waiting for the video subscription...'); - // _participantBuffer.add( - // ParticipantBuffer( - // id: event.remoteParticipant.sid, - // audioEnabled: event.remoteAudioTrackPublication?.remoteAudioTrack?.isEnabled ?? true, - // ), - // ); - // return; - // } - // if (event is RemoteVideoTrackSubscriptionEvent) { - // print('New participant, adding: ${event.remoteParticipant.sid}'); - // _participants.insert( - // 0, - // _buildParticipant( - // child: event.remoteVideoTrack.widget(), - // id: event.remoteParticipant.sid, - // remoteParticipant: event.remoteParticipant, - // audioEnabled: bufferedParticipant?.audioEnabled ?? true, - // videoEnabled: event.remoteVideoTrackPublication?.remoteVideoTrack?.isEnabled ?? true, - // ), - // ); - // } - // notifyListeners(); - // } - // } + final String name; + final String token; + final String identity; + + final StreamController _onAudioEnabledStreamController = StreamController.broadcast(); + Stream onAudioEnabled; + final StreamController _onVideoEnabledStreamController = StreamController.broadcast(); + Stream onVideoEnabled; + final StreamController _onExceptionStreamController = StreamController.broadcast(); + Stream onException; + + final Completer _completer = Completer(); + + final List _participants = []; + final List _participantBuffer = []; + final List _streamSubscriptions = []; + final List _dataTracks = []; + final List _messages = []; + + CameraCapturer _cameraCapturer; + Room _room; + Timer _timer; + + ConferenceRoom({ + @required this.name, + @required this.token, + @required this.identity, + }) { + onAudioEnabled = _onAudioEnabledStreamController.stream; + onVideoEnabled = _onVideoEnabledStreamController.stream; + onException = _onExceptionStreamController.stream; + } + + List get participants { + return [..._participants]; + } + + Future connect() async { + print('ConferenceRoom.connect()'); + try { + await TwilioProgrammableVideo.debug(dart: true, native: true); + await TwilioProgrammableVideo.setSpeakerphoneOn(true); + + _cameraCapturer = CameraCapturer(CameraSource.FRONT_CAMERA); + var connectOptions = ConnectOptions( + token, + roomName: name, + preferredAudioCodecs: [OpusCodec()], + audioTracks: [LocalAudioTrack(true)], + dataTracks: [LocalDataTrack()], + videoTracks: [LocalVideoTrack(true, _cameraCapturer)], + enableDominantSpeaker: true, + ); + + _room = await TwilioProgrammableVideo.connect(connectOptions); + + _streamSubscriptions.add(_room.onConnected.listen(_onConnected)); + _streamSubscriptions.add(_room.onConnectFailure.listen(_onConnectFailure)); + + return _completer.future; + } catch (err) { + print(err); + rethrow; + } + } + + Future disconnect() async { + print('ConferenceRoom.disconnect()'); + if (_timer != null) { + _timer.cancel(); + } + await _room.disconnect(); + } + + @override + void dispose() { + print('ConferenceRoom.dispose()'); + _disposeStreamsAndSubscriptions(); + super.dispose(); + } + + Future _disposeStreamsAndSubscriptions() async { + await _onAudioEnabledStreamController.close(); + await _onVideoEnabledStreamController.close(); + await _onExceptionStreamController.close(); + for (var streamSubscription in _streamSubscriptions) { + await streamSubscription.cancel(); + } + } + + Future sendMessage(String message) async { + final tracks = _room.localParticipant.localDataTracks; + final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; + if (localDataTrack == null || _messages.isNotEmpty) { + print('ConferenceRoom.sendMessage => Track is not available yet, buffering message.'); + _messages.add(message); + return; + } + await localDataTrack.send(message); + } + + Future sendBufferMessage(ByteBuffer message) async { + final tracks = _room.localParticipant.localDataTracks; + final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; + if (localDataTrack == null) { + return; + } + await localDataTrack.sendBuffer(message); + } + + Future toggleVideoEnabled() async { + final tracks = _room.localParticipant.localVideoTracks; + final localVideoTrack = tracks.isEmpty ? null : tracks[0].localVideoTrack; + if (localVideoTrack == null) { + print('ConferenceRoom.toggleVideoEnabled() => Track is not available yet!'); + return; + } + await localVideoTrack.enable(!localVideoTrack.isEnabled); + + var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); + if (index < 0) { + return; + } + var participant = _participants[index]; + _participants.replaceRange( + index, + index + 1, + [ + participant.copyWith(videoEnabled: localVideoTrack.isEnabled), + ], + ); + print('ConferenceRoom.toggleVideoEnabled() => ${localVideoTrack.isEnabled}'); + _onVideoEnabledStreamController.add(localVideoTrack.isEnabled); + notifyListeners(); + } + + Future toggleAudioEnabled() async { + final tracks = _room.localParticipant.localAudioTracks; + final localAudioTrack = tracks.isEmpty ? null : tracks[0].localAudioTrack; + if (localAudioTrack == null) { + print('ConferenceRoom.toggleAudioEnabled() => Track is not available yet!'); + return; + } + await localAudioTrack.enable(!localAudioTrack.isEnabled); + + var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); + if (index < 0) { + return; + } + var participant = _participants[index]; + _participants.replaceRange( + index, + index + 1, + [ + participant.copyWith(audioEnabled: localAudioTrack.isEnabled), + ], + ); + print('ConferenceRoom.toggleAudioEnabled() => ${localAudioTrack.isEnabled}'); + _onAudioEnabledStreamController.add(localAudioTrack.isEnabled); + notifyListeners(); + } + + Future switchCamera() async { + print('ConferenceRoom.switchCamera()'); + try { + await _cameraCapturer.switchCamera(); + } on FormatException catch (e) { + print( + 'ConferenceRoom.switchCamera() failed because of FormatException with message: ${e.message}', + ); + } + } + + void addDummy({Widget child}) { + print('ConferenceRoom.addDummy()'); + if (_participants.length >= 18) { + throw PlatformException( + code: 'ConferenceRoom.maximumReached', + message: 'Maximum reached', + details: 'Currently the lay-out can only render a maximum of 18 participants', + ); + } + _participants.insert( + 0, + ParticipantWidget( + id: (_participants.length + 1).toString(), + child: child, + isRemote: true, + audioEnabled: true, + videoEnabled: true, + isDummy: true, + ), + ); + notifyListeners(); + } + + void removeDummy() { + print('ConferenceRoom.removeDummy()'); + var dummy = _participants.firstWhere((participant) => participant.isDummy, orElse: () => null); + if (dummy != null) { + _participants.remove(dummy); + notifyListeners(); + } + } + + void _onConnected(Room room) { + print('ConferenceRoom._onConnected => state: ${room.state}'); + + // When connected for the first time, add remote participant listeners + _streamSubscriptions.add(_room.onParticipantConnected.listen(_onParticipantConnected)); + _streamSubscriptions.add(_room.onParticipantDisconnected.listen(_onParticipantDisconnected)); + _streamSubscriptions.add(_room.onDominantSpeakerChange.listen(_onDominantSpeakerChanged)); + // Only add ourselves when connected for the first time too. + _participants.add( + _buildParticipant( + child: room.localParticipant.localVideoTracks[0].localVideoTrack.widget(), + id: identity, + audioEnabled: true, + videoEnabled: true, + ), + ); + for (final remoteParticipant in room.remoteParticipants) { + var participant = _participants.firstWhere((participant) => participant.id == remoteParticipant.sid, orElse: () => null); + if (participant == null) { + print('Adding participant that was already present in the room ${remoteParticipant.sid}, before I connected'); + _addRemoteParticipantListeners(remoteParticipant); + } + } + // We have to listen for the [onDataTrackPublished] event on the [LocalParticipant] in + // order to be able to use the [send] method. + _streamSubscriptions.add(room.localParticipant.onDataTrackPublished.listen(_onLocalDataTrackPublished)); + notifyListeners(); + _completer.complete(room); + + _timer = Timer.periodic(const Duration(minutes: 1), (_) { + // Let's see if we can send some data over the DataTrack API + sendMessage('And another minute has passed since I connected...'); + // Also try the ByteBuffer way of sending data + final list = 'This data has been sent over the ByteBuffer channel of the DataTrack API'.codeUnits; + var bytes = Uint8List.fromList(list); + sendBufferMessage(bytes.buffer); + }); + } + + void _onLocalDataTrackPublished(LocalDataTrackPublishedEvent event) { + // Send buffered messages, if any... + while (_messages.isNotEmpty) { + var message = _messages.removeAt(0); + print('Sending buffered message: $message'); + event.localDataTrackPublication.localDataTrack.send(message); + } + } + + void _onConnectFailure(RoomConnectFailureEvent event) { + print('ConferenceRoom._onConnectFailure: ${event.exception}'); + _completer.completeError(event.exception); + } + + void _onDominantSpeakerChanged(DominantSpeakerChangedEvent event) { + print('ConferenceRoom._onDominantSpeakerChanged: ${event.remoteParticipant.identity}'); + var oldDominantParticipant = _participants.firstWhere((p) => p.isDominant, orElse: () => null); + if (oldDominantParticipant != null) { + var oldDominantParticipantIndex = _participants.indexOf(oldDominantParticipant); + _participants.replaceRange(oldDominantParticipantIndex, oldDominantParticipantIndex + 1, [oldDominantParticipant.copyWith(isDominant: false)]); + } + + var newDominantParticipant = _participants.firstWhere((p) => p.id == event.remoteParticipant.sid); + var newDominantParticipantIndex = _participants.indexOf(newDominantParticipant); + _participants.replaceRange(newDominantParticipantIndex, newDominantParticipantIndex + 1, [newDominantParticipant.copyWith(isDominant: true)]); + notifyListeners(); + } + + void _onParticipantConnected(RoomParticipantConnectedEvent event) { + print('ConferenceRoom._onParticipantConnected, ${event.remoteParticipant.sid}'); + _addRemoteParticipantListeners(event.remoteParticipant); + } + + void _onParticipantDisconnected(RoomParticipantDisconnectedEvent event) { + print('ConferenceRoom._onParticipantDisconnected: ${event.remoteParticipant.sid}'); + _participants.removeWhere((ParticipantWidget p) => p.id == event.remoteParticipant.sid); + notifyListeners(); + } + + ParticipantWidget _buildParticipant({ + @required Widget child, + @required String id, + @required bool audioEnabled, + @required bool videoEnabled, + RemoteParticipant remoteParticipant, + }) { + return ParticipantWidget( + id: remoteParticipant?.sid, + isRemote: remoteParticipant != null, + child: child, + audioEnabled: audioEnabled, + videoEnabled: videoEnabled, + ); + } + + void _addRemoteParticipantListeners(RemoteParticipant remoteParticipant) { + print('ConferenceRoom._addRemoteParticipantListeners() => Adding listeners to remoteParticipant ${remoteParticipant.sid}'); + _streamSubscriptions.add(remoteParticipant.onAudioTrackDisabled.listen(_onAudioTrackDisabled)); + _streamSubscriptions.add(remoteParticipant.onAudioTrackEnabled.listen(_onAudioTrackEnabled)); + _streamSubscriptions.add(remoteParticipant.onAudioTrackPublished.listen(_onAudioTrackPublished)); + _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscribed.listen(_onAudioTrackSubscribed)); + _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscriptionFailed.listen(_onAudioTrackSubscriptionFailed)); + _streamSubscriptions.add(remoteParticipant.onAudioTrackUnpublished.listen(_onAudioTrackUnpublished)); + _streamSubscriptions.add(remoteParticipant.onAudioTrackUnsubscribed.listen(_onAudioTrackUnsubscribed)); + + _streamSubscriptions.add(remoteParticipant.onDataTrackPublished.listen(_onDataTrackPublished)); + _streamSubscriptions.add(remoteParticipant.onDataTrackSubscribed.listen(_onDataTrackSubscribed)); + _streamSubscriptions.add(remoteParticipant.onDataTrackSubscriptionFailed.listen(_onDataTrackSubscriptionFailed)); + _streamSubscriptions.add(remoteParticipant.onDataTrackUnpublished.listen(_onDataTrackUnpublished)); + _streamSubscriptions.add(remoteParticipant.onDataTrackUnsubscribed.listen(_onDataTrackUnsubscribed)); + + _streamSubscriptions.add(remoteParticipant.onVideoTrackDisabled.listen(_onVideoTrackDisabled)); + _streamSubscriptions.add(remoteParticipant.onVideoTrackEnabled.listen(_onVideoTrackEnabled)); + _streamSubscriptions.add(remoteParticipant.onVideoTrackPublished.listen(_onVideoTrackPublished)); + _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscribed.listen(_onVideoTrackSubscribed)); + _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscriptionFailed.listen(_onVideoTrackSubscriptionFailed)); + _streamSubscriptions.add(remoteParticipant.onVideoTrackUnpublished.listen(_onVideoTrackUnpublished)); + _streamSubscriptions.add(remoteParticipant.onVideoTrackUnsubscribed.listen(_onVideoTrackUnsubscribed)); + } + + void _onAudioTrackDisabled(RemoteAudioTrackEvent event) { + print('ConferenceRoom._onAudioTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); + _setRemoteAudioEnabled(event); + } + + void _onAudioTrackEnabled(RemoteAudioTrackEvent event) { + print('ConferenceRoom._onAudioTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); + _setRemoteAudioEnabled(event); + } + + void _onAudioTrackPublished(RemoteAudioTrackEvent event) { + print('ConferenceRoom._onAudioTrackPublished(), ${event.remoteParticipant.sid}}'); + } + + void _onAudioTrackSubscribed(RemoteAudioTrackSubscriptionEvent event) { + print('ConferenceRoom._onAudioTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); + _addOrUpdateParticipant(event); + } + + void _onAudioTrackSubscriptionFailed(RemoteAudioTrackSubscriptionFailedEvent event) { + print('ConferenceRoom._onAudioTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); + _onExceptionStreamController.add( + PlatformException( + code: 'ConferenceRoom.audioTrackSubscriptionFailed', + message: 'AudioTrack Subscription Failed', + details: event.exception.toString(), + ), + ); + } + + void _onAudioTrackUnpublished(RemoteAudioTrackEvent event) { + print('ConferenceRoom._onAudioTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); + } + + void _onAudioTrackUnsubscribed(RemoteAudioTrackSubscriptionEvent event) { + print('ConferenceRoom._onAudioTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrack.sid}'); + } + + void _onDataTrackPublished(RemoteDataTrackEvent event) { + print('ConferenceRoom._onDataTrackPublished(), ${event.remoteParticipant.sid}}'); + } + + void _onDataTrackSubscribed(RemoteDataTrackSubscriptionEvent event) { + print('ConferenceRoom._onDataTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); + final dataTrack = event.remoteDataTrackPublication.remoteDataTrack; + _dataTracks.add(dataTrack); + _streamSubscriptions.add(dataTrack.onMessage.listen(_onMessage)); + _streamSubscriptions.add(dataTrack.onBufferMessage.listen(_onBufferMessage)); + } + + void _onDataTrackSubscriptionFailed(RemoteDataTrackSubscriptionFailedEvent event) { + print('ConferenceRoom._onDataTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); + _onExceptionStreamController.add( + PlatformException( + code: 'ConferenceRoom.dataTrackSubscriptionFailed', + message: 'DataTrack Subscription Failed', + details: event.exception.toString(), + ), + ); + } + + void _onDataTrackUnpublished(RemoteDataTrackEvent event) { + print('ConferenceRoom._onDataTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); + } + + void _onDataTrackUnsubscribed(RemoteDataTrackSubscriptionEvent event) { + print('ConferenceRoom._onDataTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrack.sid}'); + } + + void _onVideoTrackDisabled(RemoteVideoTrackEvent event) { + print('ConferenceRoom._onVideoTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); + _setRemoteVideoEnabled(event); + } + + void _onVideoTrackEnabled(RemoteVideoTrackEvent event) { + print('ConferenceRoom._onVideoTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); + _setRemoteVideoEnabled(event); + } + + void _onVideoTrackPublished(RemoteVideoTrackEvent event) { + print('ConferenceRoom._onVideoTrackPublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); + } + + void _onVideoTrackSubscribed(RemoteVideoTrackSubscriptionEvent event) { + print('ConferenceRoom._onVideoTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); + _addOrUpdateParticipant(event); + } + + void _onVideoTrackSubscriptionFailed(RemoteVideoTrackSubscriptionFailedEvent event) { + print('ConferenceRoom._onVideoTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); + _onExceptionStreamController.add( + PlatformException( + code: 'ConferenceRoom.videoTrackSubscriptionFailed', + message: 'VideoTrack Subscription Failed', + details: event.exception.toString(), + ), + ); + } + + void _onVideoTrackUnpublished(RemoteVideoTrackEvent event) { + print('ConferenceRoom._onVideoTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); + } + + void _onVideoTrackUnsubscribed(RemoteVideoTrackSubscriptionEvent event) { + print('ConferenceRoom._onVideoTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); + } + + void _onMessage(RemoteDataTrackStringMessageEvent event) { + print('onMessage => ${event.remoteDataTrack.sid}, ${event.message}'); + } + + void _onBufferMessage(RemoteDataTrackBufferMessageEvent event) { + print('onBufferMessage => ${event.remoteDataTrack.sid}, ${String.fromCharCodes(event.message.asUint8List())}'); + } + + void _setRemoteAudioEnabled(RemoteAudioTrackEvent event) { + if (event.remoteAudioTrackPublication == null) { + return; + } + var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); + if (index < 0) { + return; + } + var participant = _participants[index]; + _participants.replaceRange( + index, + index + 1, + [ + participant.copyWith(audioEnabled: event.remoteAudioTrackPublication.isTrackEnabled), + ], + ); + notifyListeners(); + } + + void _setRemoteVideoEnabled(RemoteVideoTrackEvent event) { + if (event.remoteVideoTrackPublication == null) { + return; + } + var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); + if (index < 0) { + return; + } + var participant = _participants[index]; + _participants.replaceRange( + index, + index + 1, + [ + participant.copyWith(videoEnabled: event.remoteVideoTrackPublication.isTrackEnabled), + ], + ); + notifyListeners(); + } + + void _addOrUpdateParticipant(RemoteParticipantEvent event) { + print('ConferenceRoom._addOrUpdateParticipant(), ${event.remoteParticipant.sid}'); + final participant = _participants.firstWhere( + (ParticipantWidget participant) => participant.id == event.remoteParticipant.sid, + orElse: () => null, + ); + if (participant != null) { + print('Participant found: ${participant.id}, updating A/V enabled values'); + _setRemoteVideoEnabled(event); + _setRemoteAudioEnabled(event); + } else { + final bufferedParticipant = _participantBuffer.firstWhere( + (ParticipantBuffer participant) => participant.id == event.remoteParticipant.sid, + orElse: () => null, + ); + if (bufferedParticipant != null) { + _participantBuffer.remove(bufferedParticipant); + } else if (event is RemoteAudioTrackEvent) { + print('Audio subscription came first, waiting for the video subscription...'); + _participantBuffer.add( + ParticipantBuffer( + id: event.remoteParticipant.sid, + audioEnabled: event.remoteAudioTrackPublication?.remoteAudioTrack?.isEnabled ?? true, + ), + ); + return; + } + if (event is RemoteVideoTrackSubscriptionEvent) { + print('New participant, adding: ${event.remoteParticipant.sid}'); + _participants.insert( + 0, + _buildParticipant( + child: event.remoteVideoTrack.widget(), + id: event.remoteParticipant.sid, + remoteParticipant: event.remoteParticipant, + audioEnabled: bufferedParticipant?.audioEnabled ?? true, + videoEnabled: event.remoteVideoTrackPublication?.remoteVideoTrack?.isEnabled ?? true, + ), + ); + } + notifyListeners(); + } + } } diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 638e07ab..ff21d73e 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -78,35 +78,35 @@ class _LandingPageState extends State with WidgetsBindingObserver { print(route.settings.name); } - // setState(() { - // print("didChangeAppLifecycleState"); - // print('state = $state'); - // AppGlobal.context = context; - // if (state == AppLifecycleState.resumed) { - // print(LandingPage.isOpenCallPage); - // if (LandingPage.isOpenCallPage) { - // if (!isPageNavigated) { - // isPageNavigated = true; - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => IncomingCall( - // incomingCallData: LandingPage.incomingCallData))) - // .then((value) { - // isPageNavigated = false; - // }); - // } - // } - // } - // - // if (state == AppLifecycleState.paused) { - // isPageNavigated = false; - // } - // - // if (state == AppLifecycleState.inactive) { - // isPageNavigated = false; - // } - // }); + setState(() { + print("didChangeAppLifecycleState"); + print('state = $state'); + AppGlobal.context = context; + if (state == AppLifecycleState.resumed) { + print(LandingPage.isOpenCallPage); + if (LandingPage.isOpenCallPage) { + if (!isPageNavigated) { + isPageNavigated = true; + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => IncomingCall( + incomingCallData: LandingPage.incomingCallData))) + .then((value) { + isPageNavigated = false; + }); + } + } + } + + if (state == AppLifecycleState.paused) { + isPageNavigated = false; + } + + if (state == AppLifecycleState.inactive) { + isPageNavigated = false; + } + }); } @override diff --git a/lib/pages/livecare/incoming_call.dart b/lib/pages/livecare/incoming_call.dart index 0f9208ea..de80b4ae 100644 --- a/lib/pages/livecare/incoming_call.dart +++ b/lib/pages/livecare/incoming_call.dart @@ -213,13 +213,13 @@ class _IncomingCallState extends State token: widget.incomingCallData.sessionId, identity: widget.incomingCallData.identity); - // await Navigator.of(context).push( - // MaterialPageRoute( - // fullscreenDialog: true, - // builder: (BuildContext context) => - // ConferencePage(roomModel: roomModel), - // ), - // ); + await Navigator.of(context).push( + MaterialPageRoute( + fullscreenDialog: true, + builder: (BuildContext context) => + ConferencePage(roomModel: roomModel), + ), + ); } catch (err) { print(err); await PlatformExceptionAlertDialog( diff --git a/pubspec.yaml b/pubspec.yaml index 0f46e89f..f7e1e67a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -144,7 +144,7 @@ dependencies: # recase: ^3.0.0 wakelock: ^0.1.4 after_layout: ^1.0.7 - #twilio_programmable_video: ^0.5.0+3 + twilio_programmable_video: ^0.5.0+3 flutter_tts: ^1.2.6 speech_to_text: