Merge branch 'zik_new_design_flutter_v2.5' into 'development_v2.5'

Zik new design flutter v2.5

See merge request Cloud_Solution/diplomatic-quarter!570
merge-update-with-lab-changes
haroon amjad 4 years ago
commit 0ae4a13c02

@ -1,6 +1,21 @@
{ {
"agcgw":{
"backurl":"connect-drcn.hispace.hicloud.com",
"url":"connect-drcn.dbankcloud.cn",
"websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com",
"websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn"
},
"agcgw_all":{
"CN":"connect-drcn.dbankcloud.cn",
"CN_back":"connect-drcn.hispace.hicloud.com",
"DE":"connect-dre.dbankcloud.cn",
"DE_back":"connect-dre.hispace.hicloud.com",
"RU":"connect-drru.dbankcloud.cn",
"RU_back":"connect-drru.hispace.hicloud.com",
"SG":"connect-dra.dbankcloud.cn",
"SG_back":"connect-dra.hispace.hicloud.com"
},
"client":{ "client":{
"appType":"1",
"cp_id":"2640966000002322881", "cp_id":"2640966000002322881",
"product_id":"736430079244816567", "product_id":"736430079244816567",
"client_id":"563735388191982656", "client_id":"563735388191982656",
@ -10,5 +25,50 @@
"api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI", "api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI",
"package_name":"com.ejada.hmg" "package_name":"com.ejada.hmg"
}, },
"configuration_version":"1.0" "oauth_client":{
} "client_id":"102857389",
"client_type":1
},
"app_info":{
"app_id":"102857389",
"package_name":"com.ejada.hmg"
},
"service":{
"analytics":{
"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
"collector_url_ru":"datacollector-drru.dt.hicloud.com,datacollector-drru.dt.dbankcloud.cn",
"collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn",
"collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
"resource_id":"p1",
"channel_id":""
},
"search":{
"url":"https://search-drcn.cloud.huawei.com"
},
"cloudstorage":{
"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn"
},
"ml":{
"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"
}
},
"region":"CN",
"configuration_version":"3.0",
"appInfos":[
{
"package_name":"com.ejada.hmg",
"client":{
"app_id":"102857389"
},
"app_info":{
"package_name":"com.ejada.hmg",
"app_id":"102857389"
},
"oauth_client":{
"client_type":1,
"client_id":"102857389"
}
}
]
}

@ -67,6 +67,7 @@ android {
} }
release { release {
signingConfig signingConfigs.config signingConfig signingConfigs.config
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
staging { staging {
// Specifies a sorted list of fallback build types that the // Specifies a sorted list of fallback build types that the
@ -77,6 +78,15 @@ android {
matchingFallbacks = ['debug', 'qa', 'release'] matchingFallbacks = ['debug', 'qa', 'release']
} }
} }
packagingOptions {
exclude 'META-INF/proguard/androidx-annotations.pro'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
} }
flutter { flutter {
@ -111,6 +121,7 @@ dependencies {
implementation "com.opentok.android:opentok-android-sdk:2.19.1" implementation "com.opentok.android:opentok-android-sdk:2.19.1"
implementation 'com.facebook.stetho:stetho:1.5.1' implementation 'com.facebook.stetho:stetho:1.5.1'
implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1' implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1'

@ -1,4 +1,27 @@
-keep class tvi.webrtc.** { *; } -keep class tvi.webrtc.** { *; }
-keep class com.twilio.video.** { *; } -keep class com.twilio.video.** { *; }
-keep class com.twilio.common.** { *; } -keep class com.twilio.common.** { *; }
-keepattributes InnerClasses -keepattributes InnerClasses
-keep class com.ejada.** { *; }
-keep class org.webrtc.** { *; }
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
## Flutter wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
-dontwarn io.flutter.embedding.**
-keep class com.huawei.hms.flutter.** { *; }
-repackageclasses

@ -13,7 +13,7 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" /> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
@ -22,24 +22,18 @@
<uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" /> <uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-feature <uses-feature android:name="android.hardware.location.gps" android:required="false" />
android:name="android.hardware.location.network" <uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
android:required="false" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" />
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA" />
<!-- Wifi Permissions--> <!-- Wifi Permissions-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<!-- Detect Reboot Permission --> <!-- Detect Reboot Permission -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<queries> <queries>
<intent> <intent>
<action android:name="android.speech.RecognitionService" /> <action android:name="android.speech.RecognitionService" />
@ -48,10 +42,12 @@
<application <application
android:name=".Application" android:name=".Application"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="Dr. Alhabib" android:usesCleartextTraffic="true"
android:screenOrientation="sensorPortrait"
android:showOnLockScreen="true" android:showOnLockScreen="true"
android:usesCleartextTraffic="true"> android:screenOrientation="sensorPortrait"
android:label="Dr. Alhabib">
<meta-data android:name="push_kit_auto_init_enabled" android:value="true" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
@ -87,44 +83,59 @@
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"> <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" /> <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" /> <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<!-- Geofencing --> <!-- Geofencing -->
<service <service android:name=".geofence.intent_receivers.GeofenceTransitionsJobIntentService" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" />
android:name=".geofence.intent_receivers.GeofenceTransitionsJobIntentService" <receiver android:name=".geofence.intent_receivers.GeofenceBroadcastReceiver" android:enabled="true" android:exported="true" />
android:exported="true" <receiver android:name=".geofence.intent_receivers.GeofencingRebootBroadcastReceiver" android:enabled="true">
android:permission="android.permission.BIND_JOB_SERVICE" />
<receiver
android:name=".geofence.intent_receivers.GeofenceBroadcastReceiver"
android:enabled="true"
android:exported="true" />
<receiver
android:name=".geofence.intent_receivers.GeofencingRebootBroadcastReceiver"
android:enabled="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" /> <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".geofence.intent_receivers.LocationProviderChangeReceiver"> <receiver android:name=".geofence.intent_receivers.LocationProviderChangeReceiver">
<intent-filter> <intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" /> <action android:name="android.location.PROVIDERS_CHANGED"/>
</intent-filter> </intent-filter>
</receiver> </receiver>
<service android:name=".geofence.intent_receivers.ReregisterGeofenceJobService" android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name=".geofence.intent_receivers.ReregisterGeofenceJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- Geofencing --> <!-- Geofencing -->
<!--
Huawei Push Notifications
Set push kit auto enable to true (for obtaining the token on initialize)
-->
<meta-data <meta-data
android:name="com.google.android.geo.API_KEY" android:name="push_kit_auto_init_enabled"
android:value="AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8" /> android:value="true" />
<!-- These receivers are for sending scheduled local notifications -->
<receiver android:name="com.huawei.hms.flutter.push.receiver.local.HmsLocalNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="com.huawei.hms.flutter.push.receiver.local.HmsLocalNotificationScheduledPublisher"
android:enabled="true"
android:exported="true" />
<receiver
android:name="com.huawei.hms.flutter.push.receiver.BackgroundMessageBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.huawei.hms.flutter.push.receiver.BACKGROUND_REMOTE_MESSAGE" />
</intent-filter>
</receiver>
<!-- Huawei Push Notifications -->
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8"/>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
@ -134,7 +145,6 @@
android:value="2" /> android:value="2" />
</application> </application>
z
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.USE_FINGERPRINT" />
@ -142,4 +152,5 @@
<uses-permission android:name="android.permission.WRITE_CALENDAR" /> <uses-permission android:name="android.permission.WRITE_CALENDAR" />
</manifest> </manifest>

@ -0,0 +1,56 @@
/*
* ---------------
* Note: Todo
* ---------------
* Need to be place in huawei_push (package com.huawei.hms.flutter.push.hms) and define in huawei_push manifest.xml
* */
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import com.huawei.hms.flutter.push.hms.FlutterHmsMessageService;
import com.huawei.hms.flutter.push.utils.ApplicationUtils;
import org.json.JSONObject;
//package com.huawei.hms.flutter.push.hms
//
//
//import android.content.Context;
//import android.content.Intent;
//import android.content.SharedPreferences;
//
//import com.huawei.hms.flutter.push.hms.FlutterHmsMessageService;
//import com.huawei.hms.flutter.push.utils.ApplicationUtils;
//import com.huawei.hms.push.RemoteMessage;
//
//import org.json.JSONObject;
//
//public class CustomFlutterHmsMessageService extends FlutterHmsMessageService {
// @Override
// public void onMessageReceived(RemoteMessage remoteMessage) {
// super.onMessageReceived(remoteMessage);
// try {
// String jsonStr = remoteMessage.getData();
// JSONObject json_data = new JSONObject(jsonStr);
// JSONObject json_data_data = new JSONObject(json_data.getString("data"));
// if(json_data_data.getString("is_call").equalsIgnoreCase("true")){
// boolean isApplicationInForeground = ApplicationUtils.isApplicationInForeground(this);
// if(!isApplicationInForeground){
// SharedPreferences preferences = getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE);
// preferences.edit().putString("flutter.call_data", json_data.getString("data")).apply();
//
// Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
// intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
// startActivity(intent);
// Log.v("onMessageReceived", "startActivity(intent) called");
// }
// }
//
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
//}

@ -1,9 +1,8 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
# platform :ios, '10.0' # platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'
$FirebaseAnalyticsWithoutAdIdSupport = true
project 'Runner', { project 'Runner', {
'Debug' => :debug, 'Debug' => :debug,
@ -11,86 +10,32 @@ project 'Runner', {
'Release' => :release, 'Release' => :release,
} }
# pod 'FBSDKCoreKit' def flutter_root
# pod 'FBSDKLoginKit' generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
def parse_KV_file(file, separator='=') raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end end
generated_key_values = {}
skip_line_start_symbols = ["#", "/"] File.foreach(generated_xcode_build_settings_path) do |line|
File.foreach(file_abs_path) do |line| matches = line.match(/FLUTTER_ROOT\=(.*)/)
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } return matches[1].strip if matches
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 end
generated_key_values raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do target 'Runner' do
use_frameworks! use_frameworks!
use_modular_headers! use_modular_headers!
# Native Pods flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
pod 'NVActivityIndicatorView'
pod 'OpenTok'
# 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 end
post_install do |installer| post_install do |installer|
installer.pods_project.targets.each do |target| installer.pods_project.targets.each do |target|
target.build_configurations.each do |config| flutter_additional_ios_build_settings(target)
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end end
end end

File diff suppressed because it is too large Load Diff

@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>

@ -29,12 +29,12 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil
if let mainViewController = window.rootViewController as? MainFlutterVC{ // platform initialization suppose to be in foreground if let mainViewController = window.rootViewController as? MainFlutterVC{ // platform initialization suppose to be in foreground
flutterViewController = mainViewController flutterViewController = mainViewController
HMGPlatformBridge.initialize(flutterViewController: flutterViewController) HMGPlatformBridge.initialize(flutterViewController: flutterViewController)
OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok")) // OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok"))
}else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background }else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background
flutterViewController = mainViewController flutterViewController = mainViewController
HMGPlatformBridge.initialize(flutterViewController: flutterViewController) HMGPlatformBridge.initialize(flutterViewController: flutterViewController)
OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok")) // OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok"))
} }
} }

@ -8,52 +8,51 @@
import UIKit import UIKit
import NetworkExtension import NetworkExtension
import SystemConfiguration.CaptiveNetwork import SystemConfiguration.CaptiveNetwork
import OpenTok
fileprivate var openTok:OpenTok? fileprivate var openTok:OpenTok?
class OpenTokPlatformBridge : NSObject{ class OpenTokPlatformBridge : NSObject{
private var methodChannel:FlutterMethodChannel? = nil // private var methodChannel:FlutterMethodChannel? = nil
private var mainViewController:MainFlutterVC! // private var mainViewController:MainFlutterVC!
private static var shared_:OpenTokPlatformBridge? // private static var shared_:OpenTokPlatformBridge?
//
class func initialize(flutterViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){ // class func initialize(flutterViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){
shared_ = OpenTokPlatformBridge() // shared_ = OpenTokPlatformBridge()
shared_?.mainViewController = flutterViewController // shared_?.mainViewController = flutterViewController
//
shared_?.openChannel() // shared_?.openChannel()
openTok = OpenTok(mainViewController: flutterViewController, registrar: registrar) // openTok = OpenTok(mainViewController: flutterViewController, registrar: registrar)
} // }
//
func shared() -> OpenTokPlatformBridge{ // func shared() -> OpenTokPlatformBridge{
assert((OpenTokPlatformBridge.shared_ != nil), "OpenTokPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.") // assert((OpenTokPlatformBridge.shared_ != nil), "OpenTokPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.")
return OpenTokPlatformBridge.shared_! // return OpenTokPlatformBridge.shared_!
} // }
//
private func openChannel(){ // private func openChannel(){
methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger) // methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger)
methodChannel?.setMethodCallHandler { (call, result) in // methodChannel?.setMethodCallHandler { (call, result) in
print("Called function \(call.method)") // print("Called function \(call.method)")
//
switch(call.method) { // switch(call.method) {
case "initSession": // case "initSession":
openTok?.initSession(call: call, result: result) // openTok?.initSession(call: call, result: result)
//
case "swapCamera": // case "swapCamera":
openTok?.swapCamera(call: call, result: result) // openTok?.swapCamera(call: call, result: result)
//
case "toggleAudio": // case "toggleAudio":
openTok?.toggleAudio(call: call, result: result) // openTok?.toggleAudio(call: call, result: result)
//
case "toggleVideo": // case "toggleVideo":
openTok?.toggleVideo(call: call, result: result) // openTok?.toggleVideo(call: call, result: result)
//
default: // default:
result(FlutterMethodNotImplemented) // result(FlutterMethodNotImplemented)
} // }
//
print("") // print("")
} // }
} // }
} }

@ -6,7 +6,7 @@
// //
import Foundation import Foundation
import OpenTok //import OpenTok
import UIKit import UIKit
enum SdkState: String { enum SdkState: String {
@ -17,163 +17,164 @@ enum SdkState: String {
} }
class OpenTok : NSObject{ class OpenTok : NSObject{
private var mainViewController:MainFlutterVC!
private var registrar:FlutterPluginRegistrar?
var methodChannel: FlutterMethodChannel?
init(mainViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){ // private var mainViewController:MainFlutterVC!
self.mainViewController = mainViewController // private var registrar:FlutterPluginRegistrar?
self.methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger) // var methodChannel: FlutterMethodChannel?
self.registrar = registrar //
// init(mainViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){
let remoteVDOFactory = OpenTokRemoteVideoFactory(messenger: registrar!.messenger()) // self.mainViewController = mainViewController
registrar?.register(remoteVDOFactory, withId: "remote-video-container") // self.methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger)
// self.registrar = registrar
let localVDOFactory = OpenTokLocalVideoFactory(messenger: registrar!.messenger()) //
registrar?.register(localVDOFactory, withId: "local-video-container") // let remoteVDOFactory = OpenTokRemoteVideoFactory(messenger: registrar!.messenger())
} // registrar?.register(remoteVDOFactory, withId: "remote-video-container")
//
var otSession: OTSession? // let localVDOFactory = OpenTokLocalVideoFactory(messenger: registrar!.messenger())
// registrar?.register(localVDOFactory, withId: "local-video-container")
var subscriber: OTSubscriber? // }
lazy var publisher: OTPublisher = { //
let settings = OTPublisherSettings() // var otSession: OTSession?
settings.name = UIDevice.current.name //
return OTPublisher(delegate: self, settings: settings)! // var subscriber: OTSubscriber?
}() // lazy var publisher: OTPublisher = {
// let settings = OTPublisherSettings()
func initSession(call:FlutterMethodCall, result: @escaping FlutterResult){ // settings.name = UIDevice.current.name
if let arguments = call.arguments as? [String: String], // return OTPublisher(delegate: self, settings: settings)!
let apiKey = arguments["apiKey"], // }()
let sessionId = arguments["sessionId"], //
let token = arguments["token"]{ // func initSession(call:FlutterMethodCall, result: @escaping FlutterResult){
// if let arguments = call.arguments as? [String: String],
var error: OTError? // let apiKey = arguments["apiKey"],
defer { // let sessionId = arguments["sessionId"],
// todo // let token = arguments["token"]{
} //
// var error: OTError?
notifyFlutter(state: SdkState.wait) // defer {
otSession = OTSession(apiKey: apiKey, sessionId: sessionId, delegate: self)! // // todo
otSession?.connect(withToken: token, error: &error) // }
//
result("") // notifyFlutter(state: SdkState.wait)
}else{ // otSession = OTSession(apiKey: apiKey, sessionId: sessionId, delegate: self)!
// otSession?.connect(withToken: token, error: &error)
} //
// result("")
} // }else{
//
// }
func swapCamera(call:FlutterMethodCall, result: @escaping FlutterResult) { //
if publisher.cameraPosition == .front { // }
publisher.cameraPosition = .back //
} else { //
publisher.cameraPosition = .front // func swapCamera(call:FlutterMethodCall, result: @escaping FlutterResult) {
} // if publisher.cameraPosition == .front {
result("") // publisher.cameraPosition = .back
} // } else {
// publisher.cameraPosition = .front
func toggleAudio(call:FlutterMethodCall, result: @escaping FlutterResult) { // }
if let arguments = call.arguments as? [String: Bool], // result("")
let publishAudio = arguments["publishAudio"] { // }
publisher.publishAudio = !publisher.publishAudio //
} // func toggleAudio(call:FlutterMethodCall, result: @escaping FlutterResult) {
result("") // if let arguments = call.arguments as? [String: Bool],
} // let publishAudio = arguments["publishAudio"] {
// publisher.publishAudio = !publisher.publishAudio
func toggleVideo(call:FlutterMethodCall, result: @escaping FlutterResult) { // }
if let arguments = call.arguments as? [String: Bool], // result("")
let publishVideo = arguments["publishVideo"] { // }
publisher.publishVideo = !publisher.publishVideo //
} // func toggleVideo(call:FlutterMethodCall, result: @escaping FlutterResult) {
result("") // if let arguments = call.arguments as? [String: Bool],
} // let publishVideo = arguments["publishVideo"] {
// publisher.publishVideo = !publisher.publishVideo
// }
func notifyFlutter(state: SdkState) { // result("")
methodChannel?.invokeMethod("updateState", arguments: state.rawValue) // }
} //
//
} // func notifyFlutter(state: SdkState) {
// methodChannel?.invokeMethod("updateState", arguments: state.rawValue)
extension OpenTok: OTSessionDelegate { // }
func sessionDidConnect(_ sessionDelegate: OTSession) { //
print("The client connected to the session.") //}
notifyFlutter(state: SdkState.loggedIn) //
//extension OpenTok: OTSessionDelegate {
var error: OTError? // func sessionDidConnect(_ sessionDelegate: OTSession) {
defer { // print("The client connected to the session.")
// todo // notifyFlutter(state: SdkState.loggedIn)
} //
// var error: OTError?
self.otSession?.publish(self.publisher, error: &error) // defer {
// // todo
if let pubView = self.publisher.view { // }
pubView.frame = CGRect(x: 0, y: 0, width: 200, height: 300) //
// self.otSession?.publish(self.publisher, error: &error)
if OpenTokLocalVideoFactory.view == nil { //
OpenTokLocalVideoFactory.viewToAddPub = pubView // if let pubView = self.publisher.view {
} else { // pubView.frame = CGRect(x: 0, y: 0, width: 200, height: 300)
OpenTokLocalVideoFactory.view?.addPublisherView(pubView) //
} // if OpenTokLocalVideoFactory.view == nil {
} // OpenTokLocalVideoFactory.viewToAddPub = pubView
} // } else {
// OpenTokLocalVideoFactory.view?.addPublisherView(pubView)
func sessionDidDisconnect(_ session: OTSession) { // }
print("The client disconnected from the session.") // }
notifyFlutter(state: SdkState.loggedOut) // }
} //
// func sessionDidDisconnect(_ session: OTSession) {
func session(_ session: OTSession, didFailWithError error: OTError) { // print("The client disconnected from the session.")
print("The client failed to connect to the session: \(error).") // notifyFlutter(state: SdkState.loggedOut)
} // }
//
func session(_ session: OTSession, streamCreated stream: OTStream) { // func session(_ session: OTSession, didFailWithError error: OTError) {
print("A stream was created in the session.") // print("The client failed to connect to the session: \(error).")
var error: OTError? // }
defer { //
// todo // func session(_ session: OTSession, streamCreated stream: OTStream) {
} // print("A stream was created in the session.")
subscriber = OTSubscriber(stream: stream, delegate: self) // var error: OTError?
// defer {
session.subscribe(subscriber!, error: &error) // // todo
} // }
// subscriber = OTSubscriber(stream: stream, delegate: self)
func session(_ session: OTSession, streamDestroyed stream: OTStream) { //
print("A stream was destroyed in the session.") // session.subscribe(subscriber!, error: &error)
} // }
} //
// func session(_ session: OTSession, streamDestroyed stream: OTStream) {
extension OpenTok: OTPublisherDelegate { // print("A stream was destroyed in the session.")
func publisher(_ publisher: OTPublisherKit, streamCreated stream: OTStream) { // }
} //}
//
func publisher(_ publisher: OTPublisherKit, streamDestroyed stream: OTStream) { //extension OpenTok: OTPublisherDelegate {
} // func publisher(_ publisher: OTPublisherKit, streamCreated stream: OTStream) {
// }
func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) { //
print("Publisher failed: \(error.localizedDescription)") // func publisher(_ publisher: OTPublisherKit, streamDestroyed stream: OTStream) {
} // }
} //
// func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) {
extension OpenTok: OTSubscriberDelegate { // print("Publisher failed: \(error.localizedDescription)")
func subscriberDidConnect(toStream subscriberKit: OTSubscriberKit) { // }
print("Subscriber connected") //}
//
if let subView = self.subscriber?.view { //extension OpenTok: OTSubscriberDelegate {
subView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) // func subscriberDidConnect(toStream subscriberKit: OTSubscriberKit) {
// print("Subscriber connected")
if OpenTokRemoteVideoFactory.view == nil { //
OpenTokRemoteVideoFactory.viewToAddSub = subView // if let subView = self.subscriber?.view {
} else { // subView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
OpenTokRemoteVideoFactory.view?.addSubscriberView(subView) //
} // if OpenTokRemoteVideoFactory.view == nil {
} // OpenTokRemoteVideoFactory.viewToAddSub = subView
} // } else {
// OpenTokRemoteVideoFactory.view?.addSubscriberView(subView)
func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) { // }
print("Subscriber failed: \(error.localizedDescription)") // }
} // }
//
// func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) {
// print("Subscriber failed: \(error.localizedDescription)")
// }
} }

@ -9,6 +9,7 @@ import 'package:diplomaticquarterapp/theme/theme_value.dart';
import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; import 'package:diplomaticquarterapp/uitl/LocalNotification.dart';
import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import 'package:diplomaticquarterapp/uitl/push-notification-handler.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
@ -25,14 +26,10 @@ import 'locator.dart';
import 'pages/pharmacies/compare-list.dart'; import 'pages/pharmacies/compare-list.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
// FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await Firebase.initializeApp(); await Firebase.initializeApp();
setupLocator(); setupLocator();
runApp(MyApp()); runApp(MyApp());
@ -74,6 +71,7 @@ class _MyApp extends State<MyApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
PlatformBridge.init(context); PlatformBridge.init(context);
PushNotificationHandler(context).init(); // Asyncronously
LocalNotification.init(onNotificationClick: (payload) { LocalNotification.init(onNotificationClick: (payload) {
LocalNotification.getInstance().showNow(title: "Payload", subtitle: payload, payload: payload); LocalNotification.getInstance().showNow(title: "Payload", subtitle: payload, payload: payload);

@ -1,216 +1,61 @@
import 'dart:async'; // import 'dart:async';
//
import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart'; // import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; // import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart';
import 'package:diplomaticquarterapp/pages/webRTC/call_page.dart'; // import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart';
import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart'; // import 'package:flutter/material.dart';
import 'package:diplomaticquarterapp/uitl/SignalRUtil.dart'; // import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; // // import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter/services.dart'; //
import 'package:flutter_webrtc/flutter_webrtc.dart'; // import '../conference_button_bar.dart';
//
import '../conference_button_bar.dart'; // class CallHomePage extends StatefulWidget {
// final String receiverId;
class CallHomePage extends StatefulWidget { // final String callerId;
final String receiverId; //
final String callerId; // const CallHomePage({Key key, this.receiverId, this.callerId}) : super(key: key);
//
const CallHomePage({Key key, this.receiverId, this.callerId}) : super(key: key); // @override
// _CallHomePageState createState() => _CallHomePageState();
@override // }
_CallHomePageState createState() => _CallHomePageState(); //
} // class _CallHomePageState extends State<CallHomePage> {
// bool showNoise = false;
class _CallHomePageState extends State<CallHomePage> { // // RTCVideoRenderer _localRenderer = RTCVideoRenderer();
bool showNoise = false; // // RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
RTCVideoRenderer _localRenderer = RTCVideoRenderer(); //
RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); // final StreamController<bool> _audioButton = StreamController<bool>.broadcast();
// final StreamController<bool> _videoButton = StreamController<bool>.broadcast();
final StreamController<bool> _audioButton = StreamController<bool>.broadcast(); // final StreamController<bool> _onButtonBarVisibleStreamController = StreamController<bool>.broadcast();
final StreamController<bool> _videoButton = StreamController<bool>.broadcast(); // final StreamController<double> _onButtonBarHeightStreamController = StreamController<double>.broadcast();
final StreamController<bool> _onButtonBarVisibleStreamController = StreamController<bool>.broadcast(); //
final StreamController<double> _onButtonBarHeightStreamController = StreamController<double>.broadcast(); // //Stream to enable video
// // MediaStream localMediaStream;
//Stream to enable video // // MediaStream remoteMediaStream;
MediaStream localMediaStream; // Signaling signaling = Signaling()..init();
MediaStream remoteMediaStream; //
Signaling signaling = Signaling()..init(); // @override
// void initState() {
@override // // TODO: implement initState
void initState() { // super.initState();
// TODO: implement initState // startCall();
super.initState(); // }
startCall(); //
} // startCall() async{
// // await _localRenderer.initialize();
startCall() async{ // // await _remoteRenderer.initialize();
await _localRenderer.initialize(); // }
await _remoteRenderer.initialize(); //
final connected = await receivedCall(); // Future<void> _disposeStreamsAndSubscriptions() async {
} // if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close();
// if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close();
// }
Future<bool> receivedCall() async { //
//Stream local media // @override
localMediaStream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': true}); // Widget build(BuildContext context) {
_localRenderer.srcObject = localMediaStream; // return Scaffold(
// backgroundColor: Colors.white,
final connected = await signaling.acceptCall(widget.callerId, widget.receiverId, localMediaStream: localMediaStream, onRemoteMediaStream: (remoteMediaStream){ // body: Container() //showNoise ? _buildNoiseBox() : buildLayout(),
this.remoteMediaStream = remoteMediaStream; // );
_remoteRenderer.srcObject = remoteMediaStream; // }
}); // }
if(connected){
signaling.signalR.listen(
onAcceptCall: (arg0){
print(arg0.toString());
},
onCandidate: (candidateJson){
signaling.addCandidate(candidateJson);
},
onDeclineCall: (arg0,arg1){
// _onHangup();
},
onHangupCall: (arg0){
// _onHangup();
},
onOffer: (offerSdp, callerUser) async{
print('${offerSdp.toString()} | ${callerUser.toString()}');
await signaling.answerOffer(offerSdp);
}
);
}
return connected;
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_localRenderer?.dispose();
_remoteRenderer?.dispose();
_audioButton?.close();
_videoButton?.close();
localMediaStream?.dispose();
remoteMediaStream?.dispose();
_disposeStreamsAndSubscriptions();
}
Future<void> _disposeStreamsAndSubscriptions() async {
if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close();
if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close();
}
@override
Widget build(BuildContext context) {
// return WillPopScope(
// onWillPop: () async => false,
// child: Scaffold(
// backgroundColor: Colors.black,
// // body: ,
// ),
// );
return Scaffold(
backgroundColor: Colors.white,
body: showNoise ? _buildNoiseBox() : buildLayout(),
);
}
LayoutBuilder buildLayout() {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Stack(
children: [
CamViewWidget(
localRenderer: _localRenderer,
remoteRenderer: _remoteRenderer,
constraints: constraints,
onButtonBarVisibleStreamController: _onButtonBarVisibleStreamController,
onButtonBarHeightStreamController: _onButtonBarHeightStreamController,
),
ConferenceButtonBar(
audioEnabled: _audioButton.stream,
videoEnabled: _videoButton.stream,
onAudioEnabled: _onAudioEnable,
onVideoEnabled: _onVideoEnabled,
onSwitchCamera: _onSwitchCamera,
onHangup: _onHangup,
onPersonAdd: () {},
onPersonRemove: () {},
onHeight: _onHeightBar,
onShow: _onShowBar,
onHide: _onHideBar,
),
],
);
},
);
}
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),
),
),
),
),
);
}
Function _onAudioEnable() {
final audioTrack = localMediaStream.getAudioTracks()[0];
final mute = audioTrack.muted;
Helper.setMicrophoneMute(!mute, audioTrack);
_audioButton.add(mute);
}
Function _onVideoEnabled() {
final videoTrack = localMediaStream.getVideoTracks()[0];
bool videoEnabled = videoTrack.enabled;
localMediaStream.getVideoTracks()[0].enabled = !videoEnabled;
_videoButton.add(!videoEnabled);
}
Function _onSwitchCamera() {
Helper.switchCamera(localMediaStream.getVideoTracks()[0]);
}
void _onShowBar() {
setState(() {
});
_onButtonBarVisibleStreamController.add(true);
}
void _onHeightBar(double height) {
_onButtonBarHeightStreamController.add(height);
}
void _onHideBar() {
setState(() {
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
});
_onButtonBarVisibleStreamController.add(false);
}
Future<void> _onHangup() async {
signaling.hangupCall(widget.callerId, widget.receiverId);
print('onHangup');
Navigator.of(context).pop();
}
}

@ -0,0 +1,186 @@
import 'dart:async';
import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart';
import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import '../conference_button_bar.dart';
class CallHomePage extends StatefulWidget {
final String receiverId;
final String callerId;
const CallHomePage({Key key, this.receiverId, this.callerId}) : super(key: key);
@override
_CallHomePageState createState() => _CallHomePageState();
}
class _CallHomePageState extends State<CallHomePage> {
bool showNoise = true;
RTCVideoRenderer _localRenderer = RTCVideoRenderer();
RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
final StreamController<bool> _audioButton = StreamController<bool>.broadcast();
final StreamController<bool> _videoButton = StreamController<bool>.broadcast();
final StreamController<bool> _onButtonBarVisibleStreamController = StreamController<bool>.broadcast();
final StreamController<double> _onButtonBarHeightStreamController = StreamController<double>.broadcast();
//Stream to enable video
MediaStream localMediaStream;
MediaStream remoteMediaStream;
Signaling signaling = Signaling()..init();
@override
void initState() {
// TODO: implement initState
super.initState();
startCall();
}
startCall() async{
await _localRenderer.initialize();
await _remoteRenderer.initialize();
final connected = await receivedCall();
}
Future<bool> receivedCall() async {
//Stream local media
localMediaStream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': true});
_localRenderer.srcObject = localMediaStream;
final connected = await signaling.acceptCall(widget.callerId, widget.receiverId, localMediaStream: localMediaStream, onRemoteMediaStream: (remoteMediaStream){
setState(() {
this.remoteMediaStream = remoteMediaStream;
_remoteRenderer.srcObject = remoteMediaStream;
});
});
if(connected){
signaling.signalR.listen(
onAcceptCall: (arg0){
print(arg0.toString());
},
onCandidate: (candidateJson){
signaling.addCandidate(candidateJson);
},
onDeclineCall: (arg0,arg1){
// _onHangup();
},
onHangupCall: (arg0){
// _onHangup();
},
onOffer: (offerSdp, callerUser) async{
print('${offerSdp.toString()} | ${callerUser.toString()}');
await signaling.answerOffer(offerSdp);
}
);
}
return connected;
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_localRenderer?.dispose();
_remoteRenderer?.dispose();
_audioButton?.close();
_videoButton?.close();
localMediaStream?.dispose();
remoteMediaStream?.dispose();
_disposeStreamsAndSubscriptions();
}
Future<void> _disposeStreamsAndSubscriptions() async {
if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close();
if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: buildLayout(),
);
}
LayoutBuilder buildLayout() {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Stack(
children: [
CamViewWidget(
localRenderer: _localRenderer,
remoteRenderer: _remoteRenderer,
constraints: constraints,
onButtonBarVisibleStreamController: _onButtonBarVisibleStreamController,
onButtonBarHeightStreamController: _onButtonBarHeightStreamController,
),
ConferenceButtonBar(
audioEnabled: _audioButton.stream,
videoEnabled: _videoButton.stream,
onAudioEnabled: _onAudioEnable,
onVideoEnabled: _onVideoEnabled,
onSwitchCamera: _onSwitchCamera,
onHangup: _onHangup,
onPersonAdd: () {},
onPersonRemove: () {},
onHeight: _onHeightBar,
onShow: _onShowBar,
onHide: _onHideBar,
),
],
);
},
);
}
Function _onAudioEnable() {
final audioTrack = localMediaStream.getAudioTracks()[0];
final mute = audioTrack.muted;
Helper.setMicrophoneMute(!mute, audioTrack);
_audioButton.add(mute);
}
Function _onVideoEnabled() {
final videoTrack = localMediaStream.getVideoTracks()[0];
bool videoEnabled = videoTrack.enabled;
localMediaStream.getVideoTracks()[0].enabled = !videoEnabled;
_videoButton.add(!videoEnabled);
}
Function _onSwitchCamera() {
Helper.switchCamera(localMediaStream.getVideoTracks()[0]);
}
void _onShowBar() {
setState(() {
});
_onButtonBarVisibleStreamController.add(true);
}
void _onHeightBar(double height) {
_onButtonBarHeightStreamController.add(height);
}
void _onHideBar() {
setState(() {
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
});
_onButtonBarVisibleStreamController.add(false);
}
Future<void> _onHangup() async {
signaling.hangupCall(widget.callerId, widget.receiverId);
print('onHangup');
Navigator.of(context).pop();
}
}

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:core'; import 'dart:core';
import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart';
@ -34,23 +35,48 @@ class _CamViewWidgetState extends State<CamViewWidget> {
child: Stack( child: Stack(
children: [ children: [
FractionallySizedBox( FractionallySizedBox(
heightFactor: 1, heightFactor: 1, widthFactor: 1,
widthFactor: 1,
child: Container( child: Container(
color: Colors.black87, color: Colors.black87,
child: RTCVideoView(widget.remoteRenderer, mirror: true), child: RTCVideoView(widget.remoteRenderer, mirror: true,filterQuality: FilterQuality.medium,),
), ),
), ),
if(widget.remoteRenderer.srcObject == null)
Positioned.fill(child: _buildNoiseBox()),
Positioned.fill(
child: RTCVideoView(widget.remoteRenderer)
),
DraggableCam( DraggableCam(
key: Key('publisher'), key: Key('publisher'),
onButtonBarHeight: widget.onButtonBarHeightStreamController.stream, onButtonBarHeight: widget.onButtonBarHeightStreamController.stream,
onButtonBarVisible: widget.onButtonBarVisibleStreamController.stream, onButtonBarVisible: widget.onButtonBarVisibleStreamController.stream,
availableScreenSize: widget.constraints.biggest, availableScreenSize: widget.constraints.biggest,
child: RTCVideoView(widget.localRenderer), child: RTCVideoView(widget.localRenderer)
), ),
// Expanded(child: RTCVideoView(widget.remoteRenderer)),
if(widget.remoteRenderer.srcObject == null)
Container(
margin: EdgeInsets.all(MediaQuery.of(context).size.width/8),
child: Text(
'Waiting for another participant to connect to the call...',
key: Key('text-wait'),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
)
),
], ],
), ),
); );
} }
Widget _buildNoiseBox() {
return NoiseBox(
density: NoiseBoxDensity.xHigh,
backgroundColor: Colors.grey.shade900,
);
}
} }

@ -27,6 +27,7 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import 'package:diplomaticquarterapp/uitl/push-notification-handler.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart'; import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart';
import 'package:diplomaticquarterapp/widgets/buttons/floatingActionButton.dart'; import 'package:diplomaticquarterapp/widgets/buttons/floatingActionButton.dart';
@ -44,6 +45,7 @@ import 'package:provider/provider.dart';
import '../../locator.dart'; import '../../locator.dart';
import '../../routes.dart'; import '../../routes.dart';
class LandingPage extends StatefulWidget { class LandingPage extends StatefulWidget {
static LandingPage shared; static LandingPage shared;
_LandingPageState state; _LandingPageState state;
@ -197,37 +199,11 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
void didChangeAppLifecycleState(AppLifecycleState state) { void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state); super.didChangeAppLifecycleState(state);
var route = ModalRoute.of(context);
if (route != null) {}
//setState(() {
AppGlobal.context = context; AppGlobal.context = context;
if (state == AppLifecycleState.resumed) { if (state == AppLifecycleState.resumed) {
if (LandingPage.isOpenCallPage) { PushNotificationHandler.getInstance().onResume();
if (Platform.isAndroid) {
return;
}
if (!isPageNavigated) {
isPageNavigated = true;
Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
Future.delayed(Duration(seconds: 5), () {
isPageNavigated = false;
});
});
}
}
sharedPref.remove(APPOINTMENT_HISTORY_MEDICAL); sharedPref.remove(APPOINTMENT_HISTORY_MEDICAL);
} }
if (state == AppLifecycleState.paused) {
isPageNavigated = false;
}
if (state == AppLifecycleState.inactive) {
isPageNavigated = false;
}
//});
} }
@override @override
@ -239,6 +215,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
PushNotificationHandler.getInstance().onResume();
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
AppGlobal.context = context; AppGlobal.context = context;
@ -247,14 +224,11 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
pageController = PageController(keepPage: true); pageController = PageController(keepPage: true);
_firebaseMessaging.setAutoInitEnabled(true); _firebaseMessaging.setAutoInitEnabled(true);
// signalRUtil = new SignalRUtil(hubName: "https://VCallApi.hmg.com/WebRTCHub?source=mobile&username=2001273", context: context);
locationUtils = new LocationUtils(isShowConfirmDialog: false, context: context); locationUtils = new LocationUtils(isShowConfirmDialog: false, context: context);
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (projectViewModel.isLogin && !projectViewModel.isLoginChild) { if (projectViewModel.isLogin && !projectViewModel.isLoginChild) {
familyFileProvider.getSharedRecordByStatus(); familyFileProvider.getSharedRecordByStatus();
} }
// if (!signalRUtil.getConnectionState()) signalRUtil.startSignalRConnection();
}); });
// HMG (Guest/Internet) Wifi Access [Zohaib Kambrani] // HMG (Guest/Internet) Wifi Access [Zohaib Kambrani]
//for now commented to reduce this call will enable it when needed //for now commented to reduce this call will enable it when needed
@ -263,10 +237,6 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
// PlatformBridge().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)}); // PlatformBridge().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)});
// }).checkAndConnectIfNoInternet(); // }).checkAndConnectIfNoInternet();
if (Platform.isIOS) {
_firebaseMessaging.requestPermission();
}
requestPermissions().then((results) { requestPermissions().then((results) {
locationUtils.getCurrentLocation(); locationUtils.getCurrentLocation();
_firebaseMessaging.getToken().then((String token) { _firebaseMessaging.getToken().then((String token) {
@ -277,8 +247,6 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
if (!projectViewModel.isLoginChild) { if (!projectViewModel.isLoginChild) {
checkUserStatus(token); checkUserStatus(token);
} }
// if (projectViewModel.isLogin) this.getNotificationCount(DEVICE_TOKEN);
} }
}); });
if (results[Permission.location].isGranted) {} if (results[Permission.location].isGranted) {}
@ -288,181 +256,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
// if (results[Permission.accessMediaLocation].isGranted) ; // if (results[Permission.accessMediaLocation].isGranted) ;
// if (results[Permission.calendar].isGranted) ; // if (results[Permission.calendar].isGranted) ;
}); });
// });
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
print("onMessage: $message");
print(message);
print(message.data['name']);
print(message.data['appointmentdate']);
if (Platform.isIOS) {
if (message.data['is_call'] == "true") {
var route = ModalRoute.of(context);
if (route != null) {
print(route.settings.name);
}
Map<String, dynamic> myMap = new Map<String, dynamic>.from(message.data);
print(myMap);
LandingPage.isOpenCallPage = true;
LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
if (!isPageNavigated) {
isPageNavigated = true;
Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
isPageNavigated = false;
});
}
} else {
print("Is Call Not Found iOS");
}
} else {
print("Is Call Not Found iOS");
}
if (Platform.isAndroid) {
print("messagedata:${message}");
print("messagedata:${message.data}");
if (message.data.containsKey("is_call")) {
var route = ModalRoute.of(context);
if (route != null) {
print(route.settings.name);
}
Map<String, dynamic> myMap = new Map<String, dynamic>.from(message.data);
print(myMap);
if (LandingPage.isOpenCallPage) {
return;
}
LandingPage.isOpenCallPage = true;
LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
if (!isPageNavigated) {
isPageNavigated = true;
Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
Future.delayed(Duration(seconds: 5), () {
isPageNavigated = false;
});
});
}
} else {
print("Is Call Not Found Android");
LocalNotification.getInstance().showNow(title: message.data['notification']['title'], subtitle: message.data['notification']['body']);
}
} else {
print("Is Call Not Found Android");
}
});
FirebaseMessaging.onBackgroundMessage((message) {
return Platform.isIOS ? null : myBackgroundMessageHandler(message.data);
});
// todo verify all functionality
// _firebaseMessaging.configure(
// // onMessage: (Map<String, dynamic> message) async {
// // // showDialog("onMessage: $message");
// // print("onMessage: $message");
// // print(message);
// // print(message['name']);
// // print(message['appointmentdate']);
// //
// // if (Platform.isIOS) {
// // if (message['is_call'] == "true") {
// // var route = ModalRoute.of(context);
// //
// // if (route != null) {
// // print(route.settings.name);
// // }
// //
// // Map<String, dynamic> myMap = new Map<String, dynamic>.from(message);
// // print(myMap);
// // LandingPage.isOpenCallPage = true;
// // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
// // if (!isPageNavigated) {
// // isPageNavigated = true;
// // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
// // isPageNavigated = false;
// // });
// // }
// // } else {
// // print("Is Call Not Found iOS");
// // }
// // } else {
// // print("Is Call Not Found iOS");
// // }
// //
// // if (Platform.isAndroid) {
// // if (message['data'].containsKey("is_call")) {
// // var route = ModalRoute.of(context);
// //
// // if (route != null) {
// // print(route.settings.name);
// // }
// //
// // Map<String, dynamic> myMap = new Map<String, dynamic>.from(message['data']);
// // print(myMap);
// // if (LandingPage.isOpenCallPage) {
// // return;
// // }
// // LandingPage.isOpenCallPage = true;
// // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
// // if (!isPageNavigated) {
// // isPageNavigated = true;
// // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
// // Future.delayed(Duration(seconds: 5), () {
// // isPageNavigated = false;
// // });
// // });
// // }
// // } else {
// // print("Is Call Not Found Android");
// // LocalNotification.getInstance().showNow(title: message['notification']['title'], subtitle: message['notification']['body']);
// // }
// // } else {
// // print("Is Call Not Found Android");
// // }
// // },
// onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
// onLaunch: (Map<String, dynamic> message) async {
// print("onLaunch: $message");
// // showDialog("onLaunch: $message");
// },
// onResume: (Map<String, dynamic> message) async {
// print("onResume: $message");
// print(message);
// print(message['name']);
// print(message['appointmentdate']);
//
// // showDialog("onResume: $message");
//
// if (Platform.isIOS) {
// if (message['is_call'] == "true") {
// var route = ModalRoute.of(context);
//
// if (route != null) {
// print(route.settings.name);
// }
//
// Map<String, dynamic> myMap = new Map<String, dynamic>.from(message);
// print(myMap);
// LandingPage.isOpenCallPage = true;
// LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
// if (!isPageNavigated) {
// isPageNavigated = true;
// Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
// isPageNavigated = false;
// });
// }
// } else {
// print("Is Call Not Found iOS");
// }
// } else {
// print("Is Call Not Found iOS");
// }
// },
// );
} }
Future<Map<Permission, PermissionStatus>> requestPermissions() async { Future<Map<Permission, PermissionStatus>> requestPermissions() async {
@ -486,29 +280,6 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
return permissionResults; return permissionResults;
} }
static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
Map<String, dynamic> myMap = new Map<String, dynamic>.from(message['data']);
if (message.containsKey('data')) {
LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
LandingPage.isOpenCallPage = true;
// Future.delayed(Duration(seconds: 3), () {
// Navigator.push(locator<NavigationService>().navigatorKey.currentContext, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData)));
NavigationService.instance.navigateTo(INCOMING_CALL_PAGE);
// });
// if (!isPageNavigated) {
// isPageNavigated = true;
// Navigator.push(locator<NavigationService>().navigatorKey.currentContext, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData)));
// .then((value) {
// isPageNavigated = false;
// });
// }
}
if (message.containsKey('notification')) {
final dynamic notification = message['notification'];
}
}
void setUserValues(value) async { void setUserValues(value) async {
if (value != null) sharedPref.setObject(IMEI_USER_DATA, value); if (value != null) sharedPref.setObject(IMEI_USER_DATA, value);
} }

@ -4,6 +4,7 @@ import 'package:camera/camera.dart';
import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart'; import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart';
import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart'; import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart';
import 'package:diplomaticquarterapp/pages/conference/web_rtc/call_home_page.dart'; import 'package:diplomaticquarterapp/pages/conference/web_rtc/call_home_page.dart';
import 'package:diplomaticquarterapp/pages/conference/web_rtc/call_home_page_.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/platform_exception_alert_dialog.dart'; import 'package:diplomaticquarterapp/pages/conference/widgets/platform_exception_alert_dialog.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';

@ -0,0 +1,37 @@
import 'dart:io';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:flutter/cupertino.dart';
import 'package:permission_handler/permission_handler.dart';
import 'PlatformBridge.dart';
class AppPermission{
static Future<bool> askVideoCallPermission(BuildContext context) async {
if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) {
return false;
}
if (Platform.isAndroid && !(await PlatformBridge.shared().isDrawOverAppsPermissionAllowed())) {
await _drawOverAppsMessageDialog(context);
return false;
}
return true;
}
static Future _drawOverAppsMessageDialog(BuildContext context) async {
ConfirmDialog dialog = new ConfirmDialog(
context: context,
confirmMessage: "Please select 'Dr. Alh'abib' from the list and allow draw over app permission to use live care.",
okText: TranslationBase.of(context).confirm,
cancelText: TranslationBase.of(context).cancel_nocaps,
okFunction: () async {
await PlatformBridge.shared().askDrawOverAppsPermission();
Navigator.pop(context);
},
cancelFunction: () => {});
dialog.showAlertDialog(context);
}
}

@ -79,7 +79,7 @@ class AppSharedPreferences {
} }
/// Get Object [key] the key was saved /// Get Object [key] the key was saved
getObject(String key) async { Future getObject(String key) async {
final SharedPreferences prefs = await _prefs; final SharedPreferences prefs = await _prefs;
var string = prefs.getString(key); var string = prefs.getString(key);
if (string == null) { if (string == null) {

@ -1,12 +1,21 @@
import 'package:diplomaticquarterapp/locator.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class NavigationService { class NavigationService {
final GlobalKey<NavigatorState> navigatorKey = final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>(); new GlobalKey<NavigatorState>();
static NavigationService instance = NavigationService();
Future<dynamic> navigateTo(String routeName) { static Future<dynamic> navigateTo(String routeName) {
return navigatorKey.currentState.pushNamed(routeName); final key = locator<NavigationService>().navigatorKey;
return key.currentState.pushNamed(routeName);
}
static Future<dynamic> navigateToPage(Widget page) {
final key = locator<NavigationService>().navigatorKey;
final pageRoute = MaterialPageRoute(builder: (context) => page);
return Navigator.push(key.currentContext, pageRoute);
} }
} }
BuildContext get currentContext => locator<NavigationService>().navigatorKey.currentContext;

@ -0,0 +1,282 @@
import 'dart:convert';
import 'dart:io';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:huawei_push/huawei_push.dart' as h_push;
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_messaging/firebase_messaging.dart' as fir;
import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'app_shared_preferences.dart';
import 'navigation_service.dart';
// |--> Push Notification Background
Future<dynamic> backgroundMessageHandler(dynamic message) async{
fir.RemoteMessage message_;
if(message is h_push.RemoteMessage){ // if huawei remote message convert it to Firebase Remote Message
message_ = toFirebaseRemoteMessage(message);
}
if (message_.data != null && message_.data['is_call'] == 'true') {
_incomingCall(message_.data);
return;
}
print("Background message is received, sending local notification.");
h_push.Push.localNotification({
h_push.HMSLocalNotificationAttr.TITLE: 'Background Message',
h_push.HMSLocalNotificationAttr.MESSAGE: "By: BackgroundMessageHandler"
});
}
// Push Notification Background <--|
RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message){
final payload_data = jsonDecode(message.data);
final fire_message = RemoteMessage(
from: message.from,
collapseKey: message.collapseKey,
data: payload_data['data'],
messageId: message.messageId,
sentTime: DateTime.fromMillisecondsSinceEpoch(message.sentTime*1000),
ttl: message.ttl,
category: null,
messageType: message.type,
notification: RemoteNotification(
title: message.notification.title,
titleLocArgs: (message.notification.titleLocalizationArgs ?? []).map((e) => e.toString()).toList(),
titleLocKey: message.notification.titleLocalizationKey,
body: message.notification.body,
bodyLocArgs: (message.notification.bodyLocalizationArgs ?? []).map((e) => e.toString()).toList(),
bodyLocKey: message.notification.bodyLocalizationKey,
android: AndroidNotification(
channelId: message.notification.channelId,
clickAction: message.notification.clickAction,
color: message.notification.color,
count: null,
imageUrl: message.notification.imageUrl.path,
link: message.notification.link.path,
smallIcon: message.notification.icon,
sound: message.notification.sound,
ticker: message.notification.ticker,
tag: message.notification.tag,
),
)
);
return fire_message;
}
_incomingCall(Map data) async{
LandingPage.incomingCallData = IncomingCallData.fromJson(data);
if(LandingPage.isOpenCallPage == false){
LandingPage.isOpenCallPage = true;
final permited = await AppPermission.askVideoCallPermission(currentContext);
if(permited)
await NavigationService.navigateToPage(IncomingCall(incomingCallData: LandingPage.incomingCallData));
LandingPage.isOpenCallPage = false;
}
await Future.delayed(Duration(milliseconds: 500));
await AppSharedPreferences().remove('call_data');
}
class PushNotificationHandler{
final BuildContext context;
static PushNotificationHandler _instance;
PushNotificationHandler(this.context){
PushNotificationHandler._instance = this;
}
static PushNotificationHandler getInstance() => _instance;
init() async{
if (Platform.isIOS) {
final permission = await FirebaseMessaging.instance.requestPermission();
if(permission.authorizationStatus == AuthorizationStatus.denied)
return;
}
if(Platform.isAndroid && (await FlutterHmsGmsAvailability.isHmsAvailable)) { // 'Android HMS' (Handle Huawei Push_Kit Streams)
h_push.Push.enableLogger();
final result = await h_push.Push.setAutoInitEnabled(true);
h_push.Push.onNotificationOpenedApp.listen((message){
newMessage(toFirebaseRemoteMessage(message));
}, onError: (e) => print(e.toString()));
h_push.Push.onMessageReceivedStream.listen((message){
newMessage(toFirebaseRemoteMessage(message));
}, onError: (e) => print(e.toString()));
h_push.Push.getTokenStream.listen((token){
onToken(token);
}, onError: (e) => print(e.toString()));
await h_push.Push.getToken('');
h_push.Push.registerBackgroundMessageHandler(backgroundMessageHandler);
}else{ // 'Android GMS or iOS' (Handle Firebase Messaging Streams)
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
newMessage(message);
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
newMessage(message);
});
FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
onToken(fcm_token);
});
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
final fcmToken = await FirebaseMessaging.instance.getToken();
if(fcmToken != null)
onToken(fcmToken);
}
}
newMessage(RemoteMessage remoteMessage){
print('RemoteMessage.data:: ${remoteMessage.data}');
if(remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true)
_incomingCall(remoteMessage.data);
}
onToken(String token) async{
print("Push Notification Token: " + token);
AppSharedPreferences().setString(PUSH_TOKEN, token);
DEVICE_TOKEN = token;
}
onResume() async {
var call_data = await AppSharedPreferences().getObject('call_data');
if(call_data != null){
_incomingCall(call_data);
}
}
}
/* todo verify all functionality */
// _firebaseMessaging.configure(
// // onMessage: (Map<String, dynamic> message) async {
// // // showDialog("onMessage: $message");
// // print("onMessage: $message");
// // print(message);
// // print(message['name']);
// // print(message['appointmentdate']);
// //
// // if (Platform.isIOS) {
// // if (message['is_call'] == "true") {
// // var route = ModalRoute.of(context);
// //
// // if (route != null) {
// // print(route.settings.name);
// // }
// //s
// // Map<String, dynamic> myMap = new Map<String, dynamic>.from(mesage);
// // print(myMap);
// // LandingPage.isOpenCallPage = true;
// // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
// // if (!isPageNavigated) {
// // isPageNavigated = true;
// // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
// // isPageNavigated = false;
// // });
// // }
// // } else {
// // print("Is Call Not Found iOS");
// // }
// // } else {
// // print("Is Call Not Found iOS");
// // }
// //
// // if (Platform.isAndroid) {
// // if (message['data'].containsKey("is_call")) {
// // var route = ModalRoute.of(context);
// //
// // if (route != null) {
// // print(route.settings.name);
// // }
// //
// // Map<String, dynamic> myMap = new Map<String, dynamic>.from(message['data']);
// // print(myMap);
// // if (LandingPage.isOpenCallPage) {
// // return;
// // }
// // LandingPage.isOpenCallPage = true;
// // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
// // if (!isPageNavigated) {
// // isPageNavigated = true;
// // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
// // Future.delayed(Duration(seconds: 5), () {
// // isPageNavigated = false;
// // });
// // });
// // }
// // } else {
// // print("Is Call Not Found Android");
// // LocalNotification.getInstance().showNow(title: message['notification']['title'], subtitle: message['notification']['body']);
// // }
// // } else {
// // print("Is Call Not Found Android");
// // }
// // },
// onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
// onLaunch: (Map<String, dynamic> message) async {
// print("onLaunch: $message");
// // showDialog("onLaunch: $message");
// },
// onResume: (Map<String, dynamic> message) async {
// print("onResume: $message");
// print(message);
// print(message['name']);
// print(message['appointmentdate']);
//
// // showDialog("onResume: $message");
//
// if (Platform.isIOS) {
// if (message['is_call'] == "true") {
// var route = ModalRoute.of(context);
//
// if (route != null) {
// print(route.settings.name);
// }
//
// Map<String, dynamic> myMap = new Map<String, dynamic>.from(message);
// print(myMap);
// LandingPage.isOpenCallPage = true;
// LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
// if (!isPageNavigated) {
// isPageNavigated = true;
// Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
// isPageNavigated = false;
// });
// }
// } else {
// print("Is Call Not Found iOS");
// }
// } else {
// print("Is Call Not Found iOS");
// }
// },
// );

@ -57,6 +57,8 @@ dependencies:
fluttertoast: ^8.0.8 fluttertoast: ^8.0.8
firebase_messaging: ^11.1.0 firebase_messaging: ^11.1.0
firebase_analytics: ^8.3.4 firebase_analytics: ^8.3.4
# Progress bar # Progress bar
progress_hud_v2: ^2.0.0 progress_hud_v2: ^2.0.0
percent_indicator: ^3.4.0 percent_indicator: ^3.4.0
@ -85,7 +87,10 @@ dependencies:
charts_flutter: ^0.12.0 charts_flutter: ^0.12.0
google_maps_flutter: ^2.1.1 google_maps_flutter: ^2.1.1
# Huawei
huawei_map: ^6.0.1+304 huawei_map: ^6.0.1+304
huawei_push: ^5.3.0+304
# Qr code Scanner TODO fix it # Qr code Scanner TODO fix it
# barcode_scanner: ^1.0.1 # barcode_scanner: ^1.0.1

Loading…
Cancel
Save