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-requests/571/merge
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":{
"appType":"1",
"cp_id":"2640966000002322881",
"product_id":"736430079244816567",
"client_id":"563735388191982656",
@ -10,5 +25,50 @@
"api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI",
"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 {
signingConfig signingConfigs.config
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
staging {
// Specifies a sorted list of fallback build types that the
@ -77,6 +78,15 @@ android {
matchingFallbacks = ['debug', 'qa', 'release']
}
}
packagingOptions {
exclude 'META-INF/proguard/androidx-annotations.pro'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
flutter {
@ -111,6 +121,7 @@ dependencies {
implementation "com.opentok.android:opentok-android-sdk:2.19.1"
implementation 'com.facebook.stetho:stetho:1.5.1'
implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1'

@ -1,4 +1,27 @@
-keep class tvi.webrtc.** { *; }
-keep class com.twilio.video.** { *; }
-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.ACTIVITY_RECOGNITION" />
<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.CAMERA" />
<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.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-feature
android:name="android.hardware.location.network"
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" />
<uses-feature android:name="android.hardware.location.network" 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-->
<uses-permission android:name="android.permission.ACCESS_WIFI_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.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_WIFI_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.SYSTEM_ALERT_WINDOW"/>
<!-- Detect Reboot Permission -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<queries>
<intent>
<action android:name="android.speech.RecognitionService" />
@ -48,10 +42,12 @@
<application
android:name=".Application"
android:icon="@mipmap/ic_launcher"
android:label="Dr. Alhabib"
android:screenOrientation="sensorPortrait"
android:usesCleartextTraffic="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
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
@ -87,44 +83,59 @@
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
</receiver>
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<!-- Geofencing -->
<service
android:name=".geofence.intent_receivers.GeofenceTransitionsJobIntentService"
android:exported="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">
<service android:name=".geofence.intent_receivers.GeofenceTransitionsJobIntentService" android:exported="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>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
</receiver>
<receiver android:name=".geofence.intent_receivers.LocationProviderChangeReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<action android:name="android.location.PROVIDERS_CHANGED"/>
</intent-filter>
</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 -->
<!--
Huawei Push Notifications
Set push kit auto enable to true (for obtaining the token on initialize)
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8" />
android:name="push_kit_auto_init_enabled"
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.
@ -134,7 +145,6 @@
android:value="2" />
</application>
z
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
@ -142,4 +152,5 @@
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
</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
# platform :ios, '10.0'
# platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
$FirebaseAnalyticsWithoutAdIdSupport = true
project 'Runner', {
'Debug' => :debug,
@ -11,86 +10,32 @@ project 'Runner', {
'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 [];
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
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
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
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
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
# Native Pods
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
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
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
flutter_additional_ios_build_settings(target)
end
end

File diff suppressed because it is too large Load Diff

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

@ -29,12 +29,12 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil
if let mainViewController = window.rootViewController as? MainFlutterVC{ // platform initialization suppose to be in foreground
flutterViewController = mainViewController
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
flutterViewController = mainViewController
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 NetworkExtension
import SystemConfiguration.CaptiveNetwork
import OpenTok
fileprivate var openTok:OpenTok?
class OpenTokPlatformBridge : NSObject{
private var methodChannel:FlutterMethodChannel? = nil
private var mainViewController:MainFlutterVC!
private static var shared_:OpenTokPlatformBridge?
class func initialize(flutterViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){
shared_ = OpenTokPlatformBridge()
shared_?.mainViewController = flutterViewController
shared_?.openChannel()
openTok = OpenTok(mainViewController: flutterViewController, registrar: registrar)
}
func shared() -> OpenTokPlatformBridge{
assert((OpenTokPlatformBridge.shared_ != nil), "OpenTokPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.")
return OpenTokPlatformBridge.shared_!
}
private func openChannel(){
methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger)
methodChannel?.setMethodCallHandler { (call, result) in
print("Called function \(call.method)")
switch(call.method) {
case "initSession":
openTok?.initSession(call: call, result: result)
case "swapCamera":
openTok?.swapCamera(call: call, result: result)
case "toggleAudio":
openTok?.toggleAudio(call: call, result: result)
case "toggleVideo":
openTok?.toggleVideo(call: call, result: result)
default:
result(FlutterMethodNotImplemented)
}
print("")
}
}
// private var methodChannel:FlutterMethodChannel? = nil
// private var mainViewController:MainFlutterVC!
// private static var shared_:OpenTokPlatformBridge?
//
// class func initialize(flutterViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){
// shared_ = OpenTokPlatformBridge()
// shared_?.mainViewController = flutterViewController
//
// shared_?.openChannel()
// openTok = OpenTok(mainViewController: flutterViewController, registrar: registrar)
// }
//
// func shared() -> OpenTokPlatformBridge{
// assert((OpenTokPlatformBridge.shared_ != nil), "OpenTokPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.")
// return OpenTokPlatformBridge.shared_!
// }
//
// private func openChannel(){
// methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger)
// methodChannel?.setMethodCallHandler { (call, result) in
// print("Called function \(call.method)")
//
// switch(call.method) {
// case "initSession":
// openTok?.initSession(call: call, result: result)
//
// case "swapCamera":
// openTok?.swapCamera(call: call, result: result)
//
// case "toggleAudio":
// openTok?.toggleAudio(call: call, result: result)
//
// case "toggleVideo":
// openTok?.toggleVideo(call: call, result: result)
//
// default:
// result(FlutterMethodNotImplemented)
// }
//
// print("")
// }
// }
}

@ -6,7 +6,7 @@
//
import Foundation
import OpenTok
//import OpenTok
import UIKit
enum SdkState: String {
@ -17,163 +17,164 @@ enum SdkState: String {
}
class OpenTok : NSObject{
private var mainViewController:MainFlutterVC!
private var registrar:FlutterPluginRegistrar?
var methodChannel: FlutterMethodChannel?
init(mainViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){
self.mainViewController = mainViewController
self.methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger)
self.registrar = registrar
let remoteVDOFactory = OpenTokRemoteVideoFactory(messenger: registrar!.messenger())
registrar?.register(remoteVDOFactory, withId: "remote-video-container")
let localVDOFactory = OpenTokLocalVideoFactory(messenger: registrar!.messenger())
registrar?.register(localVDOFactory, withId: "local-video-container")
}
var otSession: OTSession?
var subscriber: OTSubscriber?
lazy var publisher: OTPublisher = {
let settings = OTPublisherSettings()
settings.name = UIDevice.current.name
return OTPublisher(delegate: self, settings: settings)!
}()
func initSession(call:FlutterMethodCall, result: @escaping FlutterResult){
if let arguments = call.arguments as? [String: String],
let apiKey = arguments["apiKey"],
let sessionId = arguments["sessionId"],
let token = arguments["token"]{
var error: OTError?
defer {
// todo
}
notifyFlutter(state: SdkState.wait)
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
}
result("")
}
func toggleAudio(call:FlutterMethodCall, result: @escaping FlutterResult) {
if let arguments = call.arguments as? [String: Bool],
let publishAudio = arguments["publishAudio"] {
publisher.publishAudio = !publisher.publishAudio
}
result("")
}
func toggleVideo(call:FlutterMethodCall, result: @escaping FlutterResult) {
if let arguments = call.arguments as? [String: Bool],
let publishVideo = arguments["publishVideo"] {
publisher.publishVideo = !publisher.publishVideo
}
result("")
}
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)
var error: OTError?
defer {
// todo
}
self.otSession?.publish(self.publisher, error: &error)
if let pubView = self.publisher.view {
pubView.frame = CGRect(x: 0, y: 0, width: 200, height: 300)
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 session(_ session: OTSession, didFailWithError error: OTError) {
print("The client failed to connect to the session: \(error).")
}
func session(_ session: OTSession, streamCreated stream: OTStream) {
print("A stream was created in the session.")
var error: OTError?
defer {
// todo
}
subscriber = OTSubscriber(stream: stream, delegate: self)
session.subscribe(subscriber!, error: &error)
}
func session(_ session: OTSession, streamDestroyed stream: OTStream) {
print("A stream was destroyed in the session.")
}
}
extension OpenTok: OTPublisherDelegate {
func publisher(_ publisher: OTPublisherKit, streamCreated stream: OTStream) {
}
func publisher(_ publisher: OTPublisherKit, streamDestroyed stream: OTStream) {
}
func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) {
print("Publisher failed: \(error.localizedDescription)")
}
}
extension OpenTok: OTSubscriberDelegate {
func subscriberDidConnect(toStream subscriberKit: OTSubscriberKit) {
print("Subscriber connected")
if let subView = self.subscriber?.view {
subView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
if OpenTokRemoteVideoFactory.view == nil {
OpenTokRemoteVideoFactory.viewToAddSub = subView
} else {
OpenTokRemoteVideoFactory.view?.addSubscriberView(subView)
}
}
}
func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) {
print("Subscriber failed: \(error.localizedDescription)")
}
// private var mainViewController:MainFlutterVC!
// private var registrar:FlutterPluginRegistrar?
// var methodChannel: FlutterMethodChannel?
//
// init(mainViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){
// self.mainViewController = mainViewController
// self.methodChannel = FlutterMethodChannel(name: "OpenTok-Platform-Bridge", binaryMessenger: mainViewController.binaryMessenger)
// self.registrar = registrar
//
// let remoteVDOFactory = OpenTokRemoteVideoFactory(messenger: registrar!.messenger())
// registrar?.register(remoteVDOFactory, withId: "remote-video-container")
//
// let localVDOFactory = OpenTokLocalVideoFactory(messenger: registrar!.messenger())
// registrar?.register(localVDOFactory, withId: "local-video-container")
// }
//
// var otSession: OTSession?
//
// var subscriber: OTSubscriber?
// lazy var publisher: OTPublisher = {
// let settings = OTPublisherSettings()
// settings.name = UIDevice.current.name
// return OTPublisher(delegate: self, settings: settings)!
// }()
//
// func initSession(call:FlutterMethodCall, result: @escaping FlutterResult){
// if let arguments = call.arguments as? [String: String],
// let apiKey = arguments["apiKey"],
// let sessionId = arguments["sessionId"],
// let token = arguments["token"]{
//
// var error: OTError?
// defer {
// // todo
// }
//
// notifyFlutter(state: SdkState.wait)
// 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
// }
// result("")
// }
//
// func toggleAudio(call:FlutterMethodCall, result: @escaping FlutterResult) {
// if let arguments = call.arguments as? [String: Bool],
// let publishAudio = arguments["publishAudio"] {
// publisher.publishAudio = !publisher.publishAudio
// }
// result("")
// }
//
// func toggleVideo(call:FlutterMethodCall, result: @escaping FlutterResult) {
// if let arguments = call.arguments as? [String: Bool],
// let publishVideo = arguments["publishVideo"] {
// publisher.publishVideo = !publisher.publishVideo
// }
// result("")
// }
//
//
// 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)
//
// var error: OTError?
// defer {
// // todo
// }
//
// self.otSession?.publish(self.publisher, error: &error)
//
// if let pubView = self.publisher.view {
// pubView.frame = CGRect(x: 0, y: 0, width: 200, height: 300)
//
// 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 session(_ session: OTSession, didFailWithError error: OTError) {
// print("The client failed to connect to the session: \(error).")
// }
//
// func session(_ session: OTSession, streamCreated stream: OTStream) {
// print("A stream was created in the session.")
// var error: OTError?
// defer {
// // todo
// }
// subscriber = OTSubscriber(stream: stream, delegate: self)
//
// session.subscribe(subscriber!, error: &error)
// }
//
// func session(_ session: OTSession, streamDestroyed stream: OTStream) {
// print("A stream was destroyed in the session.")
// }
//}
//
//extension OpenTok: OTPublisherDelegate {
// func publisher(_ publisher: OTPublisherKit, streamCreated stream: OTStream) {
// }
//
// func publisher(_ publisher: OTPublisherKit, streamDestroyed stream: OTStream) {
// }
//
// func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) {
// print("Publisher failed: \(error.localizedDescription)")
// }
//}
//
//extension OpenTok: OTSubscriberDelegate {
// func subscriberDidConnect(toStream subscriberKit: OTSubscriberKit) {
// print("Subscriber connected")
//
// if let subView = self.subscriber?.view {
// subView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
//
// if OpenTokRemoteVideoFactory.view == nil {
// OpenTokRemoteVideoFactory.viewToAddSub = subView
// } else {
// OpenTokRemoteVideoFactory.view?.addSubscriberView(subView)
// }
// }
// }
//
// 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/PlatformBridge.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:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
@ -25,14 +26,10 @@ import 'locator.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 {
WidgetsFlutterBinding.ensureInitialized();
// FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await Firebase.initializeApp();
setupLocator();
runApp(MyApp());
@ -74,6 +71,7 @@ class _MyApp extends State<MyApp> {
@override
Widget build(BuildContext context) {
PlatformBridge.init(context);
PushNotificationHandler(context).init(); // Asyncronously
LocalNotification.init(onNotificationClick: (payload) {
LocalNotification.getInstance().showNow(title: "Payload", subtitle: payload, payload: payload);

@ -1,216 +1,61 @@
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/call_page.dart';
import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart';
import 'package:diplomaticquarterapp/uitl/SignalRUtil.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 = false;
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){
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();
}
}
// 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 = false;
// // 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();
// }
//
// 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: Container() //showNoise ? _buildNoiseBox() : buildLayout(),
// );
// }
// }

@ -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:core';
import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart';
import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
@ -34,23 +35,48 @@ class _CamViewWidgetState extends State<CamViewWidget> {
child: Stack(
children: [
FractionallySizedBox(
heightFactor: 1,
widthFactor: 1,
heightFactor: 1, widthFactor: 1,
child: Container(
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(
key: Key('publisher'),
onButtonBarHeight: widget.onButtonBarHeightStreamController.stream,
onButtonBarVisible: widget.onButtonBarVisibleStreamController.stream,
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/location_util.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/widgets/bottom_navigation/bottom_nav_bar.dart';
import 'package:diplomaticquarterapp/widgets/buttons/floatingActionButton.dart';
@ -44,6 +45,7 @@ import 'package:provider/provider.dart';
import '../../locator.dart';
import '../../routes.dart';
class LandingPage extends StatefulWidget {
static LandingPage shared;
_LandingPageState state;
@ -197,37 +199,11 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
var route = ModalRoute.of(context);
if (route != null) {}
//setState(() {
AppGlobal.context = context;
if (state == AppLifecycleState.resumed) {
if (LandingPage.isOpenCallPage) {
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;
});
});
}
}
PushNotificationHandler.getInstance().onResume();
sharedPref.remove(APPOINTMENT_HISTORY_MEDICAL);
}
if (state == AppLifecycleState.paused) {
isPageNavigated = false;
}
if (state == AppLifecycleState.inactive) {
isPageNavigated = false;
}
//});
}
@override
@ -239,6 +215,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
PushNotificationHandler.getInstance().onResume();
WidgetsBinding.instance.addObserver(this);
AppGlobal.context = context;
@ -247,14 +224,11 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
pageController = PageController(keepPage: 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);
WidgetsBinding.instance.addPostFrameCallback((_) {
if (projectViewModel.isLogin && !projectViewModel.isLoginChild) {
familyFileProvider.getSharedRecordByStatus();
}
// if (!signalRUtil.getConnectionState()) signalRUtil.startSignalRConnection();
});
// HMG (Guest/Internet) Wifi Access [Zohaib Kambrani]
//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)});
// }).checkAndConnectIfNoInternet();
if (Platform.isIOS) {
_firebaseMessaging.requestPermission();
}
requestPermissions().then((results) {
locationUtils.getCurrentLocation();
_firebaseMessaging.getToken().then((String token) {
@ -277,8 +247,6 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
if (!projectViewModel.isLoginChild) {
checkUserStatus(token);
}
// if (projectViewModel.isLogin) this.getNotificationCount(DEVICE_TOKEN);
}
});
if (results[Permission.location].isGranted) {}
@ -288,181 +256,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
// if (results[Permission.accessMediaLocation].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 {
@ -486,29 +280,6 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
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 {
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/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/widgets/platform_exception_alert_dialog.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.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
getObject(String key) async {
Future getObject(String key) async {
final SharedPreferences prefs = await _prefs;
var string = prefs.getString(key);
if (string == null) {

@ -1,12 +1,21 @@
import 'package:diplomaticquarterapp/locator.dart';
import 'package:flutter/material.dart';
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>();
static NavigationService instance = NavigationService();
Future<dynamic> navigateTo(String routeName) {
return navigatorKey.currentState.pushNamed(routeName);
static Future<dynamic> navigateTo(String 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
firebase_messaging: ^11.1.0
firebase_analytics: ^8.3.4
# Progress bar
progress_hud_v2: ^2.0.0
percent_indicator: ^3.4.0
@ -85,7 +87,10 @@ dependencies:
charts_flutter: ^0.12.0
google_maps_flutter: ^2.1.1
# Huawei
huawei_map: ^6.0.1+304
huawei_push: ^5.3.0+304
# Qr code Scanner TODO fix it
# barcode_scanner: ^1.0.1

Loading…
Cancel
Save