Merge branch 'dev_v3.13.6' of http://34.17.75.184/Haroon6138/diplomatic-quarter into dev_v3.13.6

# Conflicts:
#	pubspec.yaml
merge-update-with-lab-changes
Haroon Amjad 1 year ago
commit cf72ffe9ce

1
.gitignore vendored

@ -31,6 +31,7 @@ pubspec.lock
.pub-cache/
.pub/
/build/
/ios/Frameworks/
# Web related
lib/generated_plugin_registrant.dart

@ -56,6 +56,10 @@ android {
compileSdkVersion 34
// ndkVersion "24.0.8215888"
buildFeatures {
viewBinding true
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
@ -69,7 +73,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.ejada.hmg"
minSdkVersion 24
minSdkVersion 26
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
@ -117,15 +121,16 @@ android {
packagingOptions {
exclude 'META-INF/proguard/androidx-annotations.pro'
// pickFirst 'lib/x86/libc++_shared.so'
// pickFirst 'lib/x86_64/libc++_shared.so'
// pickFirst 'lib/armeabi-v7a/libc++_shared.so'
// pickFirst 'lib/arm64-v8a/libc++_shared.so'
// pickFirst '**/*.so'
pickFirst 'lib/x86/libc++_shared.so'
pickFirst 'lib/x86_64/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst '**/*.so'
}
compileOptions {
// coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
@ -136,13 +141,15 @@ flutter {
}
dependencies {
// coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.google.firebase:firebase-messaging:21.0.0"
// implementation ('com.google.firebase:firebase-inappmessaging-display:19.1.2',{
// exclude group: 'com.google.protobuf',module: 'protobuf-javalite'
// exclude group: 'com.google.protobuf',module: 'protobuf-lite'
// })
implementation 'pub.devrel:easypermissions:0.4.0'
implementation 'pub.devrel:easypermissions:3.0.0'
// implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0'
// implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0'
implementation 'com.google.guava:guava:27.0.1-android'
@ -163,9 +170,34 @@ dependencies {
// implementation "us.zoom.videosdk:ZoomVideoSDK:1.10.11"
// implementation group: 'us.zoom.videosdk', name: 'zoomvideosdk-core', version: '1.10.11'
implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1"
// implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1"
// implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1"
// implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1"
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-java8:2.4.0'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.google.android.gms:play-services-location:21.3.0'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'androidx.test.ext:junit:1.1.5'
implementation 'com.android.volley:volley:1.2.1'
def room_version = "2.4.0-alpha04"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
implementation 'net.zetetic:android-database-sqlcipher:4.5.2'
implementation 'com.intuit.ssp:ssp-android:1.1.0'
implementation 'com.intuit.sdp:sdp-android:1.1.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
// implementation "com.mapbox.maps:android:10.16.6"
implementation 'com.mapbox.maps:android:11.3.1'
implementation files('libs/PenNavUI.aar')
implementation files('libs/Penguin.aar')
implementation files('libs/PenguinRenderer.aar')
implementation "org.jetbrains.anko:anko-commons:0.10.4"
implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM
@ -177,6 +209,7 @@ dependencies {
implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.9.0'
androidTestImplementation "androidx.test:core:1.4.0"
}

Binary file not shown.

Binary file not shown.

@ -53,4 +53,20 @@
}
-dontwarn com.opentok.android.**
-dontwarn com.opentok.otc.**
-dontwarn com.opentok.otc.**
-dontwarn penguin.com.pennav.Model.Navigation.NearLandmark
-keep,includedescriptorclasses class net.sqlcipher.** { *; }
-keep,includedescriptorclasses interface net.sqlcipher.** { *; }
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-dontwarn retrofit2.**
-keep class com.google.gson.** { *; }
-dontwarn com.google.gson.**
# Penguin classes
-keep class com.peng.pennavmap.models.** { *; }
-keep class com.peng.pennavmap.db.** { *; }

@ -8,21 +8,36 @@
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" tools:node="remove"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove"/>
<!-- <uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/>-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:node="remove"/>-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BROADCAST_STICKY" tools:node="remove"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" />
<!-- <uses-permission android:name="android.permission.INTERNET" />-->
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@ -42,6 +57,7 @@
<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-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />-->
@ -59,13 +75,13 @@
</queries>
<application
android:name=".Application"
android:icon="@mipmap/ic_launcher"
android:icon="@mipmap/ic_launcher_local"
android:usesCleartextTraffic="true"
android:showOnLockScreen="true"
android:screenOrientation="sensorPortrait"
android:allowBackup="false"
android:extractNativeLibs="true"
tools:replace="android:extractNativeLibs"
tools:replace="android:extractNativeLibs,android:label"
android:label="Dr. Alhabib">
<meta-data android:name="push_kit_auto_init_enabled" android:value="true" />

@ -1,21 +1,19 @@
package com.ejada.hmg
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.ContentResolver
import android.media.AudioAttributes
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import android.view.WindowManager
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.PenguinInPlatformBridge
import com.ejada.hmg.utils.*
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterFragmentActivity() {
@RequiresApi(Build.VERSION_CODES.O)
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
// Create Flutter Platform Bridge
@ -23,6 +21,7 @@ class MainActivity: FlutterFragmentActivity() {
PlatformBridge(flutterEngine, this).create()
OpenTokPlatformBridge(flutterEngine, this).create()
PenguinInPlatformBridge(flutterEngine, this).create()
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// val mChannel = NotificationChannel("video_call_noti", "video call", NotificationManager.IMPORTANCE_HIGH)
@ -43,6 +42,25 @@ class MainActivity: FlutterFragmentActivity() {
// val time = timeToMillis("04:00:00", "HH:mm:ss")
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
val granted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
val intent = Intent("PERMISSION_RESULT_ACTION").apply {
putExtra("PERMISSION_GRANTED", granted)
}
sendBroadcast(intent)
// Log the request code and permission results
Log.d("PermissionsResult", "Request Code: $requestCode")
Log.d("PermissionsResult", "Permissions: ${permissions.joinToString()}")
Log.d("PermissionsResult", "Grant Results: ${grantResults.joinToString()}")
}
override fun onResume() {

@ -0,0 +1,52 @@
package com.cloud.diplomaticquarterapp
import com.ejada.hmg.MainActivity
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.penguin.PenguinView
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
class PenguinInPlatformBridge(
private var flutterEngine: FlutterEngine,
private var mainActivity: MainActivity
) {
private lateinit var channel: MethodChannel
companion object {
private const val CHANNEL = "launch_penguin_ui"
}
@RequiresApi(Build.VERSION_CODES.O)
fun create() {
// openTok = OpenTok(mainActivity, flutterEngine)
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
when (call.method) {
"launchPenguin" -> {
print("the platform channel is being called")
val args = call.arguments as Map<String, Any>?
Log.d("TAG", "configureFlutterEngine: $args")
println("args")
args?.let {
PenguinView(
mainActivity,
100,
args,
flutterEngine.dartExecutor.binaryMessenger,
activity = mainActivity,
channel
)
}
}
else -> {
result.notImplemented()
}
}
}
}
}

@ -0,0 +1,28 @@
package com.cloud.diplomaticquarterapp.PermissionManager
import android.Manifest
import android.os.Build
object PermissionHelper {
fun getRequiredPermissions(): Array<String> {
val permissions = mutableListOf(
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
// Manifest.permission.ACTIVITY_RECOGNITION
)
// For Android 12 (API level 31) and above, add specific permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12 (API 31) and above
permissions.add(Manifest.permission.BLUETOOTH_SCAN)
permissions.add(Manifest.permission.BLUETOOTH_CONNECT)
permissions.add(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS)
}
return permissions.toTypedArray()
}
}

@ -0,0 +1,50 @@
package com.cloud.diplomaticquarterapp.PermissionManager
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class PermissionManager(
private val context: Context,
val listener: PermissionListener,
private val requestCode: Int,
vararg permissions: String
) {
private val permissionsArray = permissions
interface PermissionListener {
fun onPermissionGranted()
fun onPermissionDenied()
}
fun arePermissionsGranted(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
permissionsArray.all {
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
} else {
true
}
}
fun requestPermissions(activity: Activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(activity, permissionsArray, requestCode)
}
}
fun handlePermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (this.requestCode == requestCode) {
val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
if (allGranted) {
listener.onPermissionGranted()
} else {
listener.onPermissionDenied()
}
}
}
}

@ -0,0 +1,15 @@
package com.cloud.diplomaticquarterapp.PermissionManager
// PermissionResultReceiver.kt
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
class PermissionResultReceiver(
private val callback: (Boolean) -> Unit
) : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val granted = intent?.getBooleanExtra("PERMISSION_GRANTED", false) ?: false
callback(granted)
}
}

@ -0,0 +1,13 @@
package com.cloud.diplomaticquarterapp.penguin
enum class PenguinMethod {
// initializePenguin("initializePenguin"),
// configurePenguin("configurePenguin"),
// showPenguinUI("showPenguinUI"),
// onPenNavUIDismiss("onPenNavUIDismiss"),
// onReportIssue("onReportIssue"),
// onPenNavSuccess("onPenNavSuccess"),
onPenNavInitializationError // onLocationOffCampus("onLocationOffCampus"),
// navigateToPOI("navigateToPOI"),
// openSharedLocation("openSharedLocation");
}

@ -0,0 +1,97 @@
package com.cloud.diplomaticquarterapp.penguin
import android.content.Context
import com.google.gson.Gson
import com.peng.pennavmap.PlugAndPlaySDK
import com.peng.pennavmap.connections.ApiController
import com.peng.pennavmap.interfaces.RefIdDelegate
import com.peng.pennavmap.models.TokenModel
import com.peng.pennavmap.models.postmodels.PostToken
import com.peng.pennavmap.utils.AppSharedData
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import android.util.Log
class PenguinNavigator() {
fun navigateTo(mContext: Context, refID: String, delegate: RefIdDelegate,clientID : String,clientKey : String ) {
val postToken = PostToken(clientID, clientKey)
getToken(mContext, postToken, object : RefIdDelegate {
override fun onRefByIDSuccess(PoiId: String?) {
Log.e("navigateTo", "PoiId is+++++++ $PoiId")
PlugAndPlaySDK.navigateTo(mContext, refID, object : RefIdDelegate {
override fun onRefByIDSuccess(PoiId: String?) {
Log.e("navigateTo", "PoiId 2is+++++++ $PoiId")
delegate.onRefByIDSuccess(refID)
}
override fun onGetByRefIDError(error: String?) {
delegate.onRefByIDSuccess(error)
}
})
}
override fun onGetByRefIDError(error: String?) {
delegate.onRefByIDSuccess(error)
}
})
}
fun getToken(mContext: Context, postToken: PostToken?, apiTokenCallBack: RefIdDelegate) {
try {
// Create the API call
val purposesCall: Call<ResponseBody> = ApiController.getInstance(mContext)
.apiMethods
.getToken(postToken)
// Enqueue the call for asynchronous execution
purposesCall.enqueue(object : Callback<ResponseBody?> {
override fun onResponse(
call: Call<ResponseBody?>,
response: Response<ResponseBody?>
) {
if (response.isSuccessful() && response.body() != null) {
try {
response.body()?.use { responseBody ->
val responseBodyString: String = responseBody.string() // Use `string()` to get the actual response content
if (responseBodyString.isNotEmpty()) {
val tokenModel = Gson().fromJson(responseBodyString, TokenModel::class.java)
if (tokenModel != null && tokenModel.token != null) {
AppSharedData.apiToken = tokenModel.token
apiTokenCallBack.onRefByIDSuccess(tokenModel.token)
} else {
apiTokenCallBack.onGetByRefIDError("Failed to parse token model")
}
} else {
apiTokenCallBack.onGetByRefIDError("Response body is empty")
}
}
} catch (e: Exception) {
apiTokenCallBack.onGetByRefIDError("An error occurred: ${e.message}")
}
} else {
apiTokenCallBack.onGetByRefIDError("Unsuccessful response: " + response.code())
}
}
override fun onFailure(call: Call<ResponseBody?>, t: Throwable) {
apiTokenCallBack.onGetByRefIDError(t.message)
}
})
} catch (error: Exception) {
apiTokenCallBack.onGetByRefIDError("Exception during API call: $error")
}
}
}

@ -0,0 +1,316 @@
package com.cloud.diplomaticquarterapp.penguin
import android.app.Activity
import android.content.Context
import android.content.Context.RECEIVER_EXPORTED
import android.content.IntentFilter
import android.graphics.Color
import android.os.Build
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.PermissionManager.PermissionHelper
import com.cloud.diplomaticquarterapp.PermissionManager.PermissionManager
import com.cloud.diplomaticquarterapp.PermissionManager.PermissionResultReceiver
import com.ejada.hmg.MainActivity
import com.peng.pennavmap.PlugAndPlayConfiguration
import com.peng.pennavmap.PlugAndPlaySDK
import com.peng.pennavmap.enums.InitializationErrorType
import com.peng.pennavmap.interfaces.PenNavUIDelegate
import com.peng.pennavmap.utils.Languages
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.platform.PlatformView
import com.cloud.diplomaticquarterapp.penguin.PenguinNavigator
import com.peng.pennavmap.interfaces.PIEventsDelegate
import com.peng.pennavmap.interfaces.PILocationDelegate
import com.peng.pennavmap.interfaces.RefIdDelegate
import com.peng.pennavmap.models.PIReportIssue
/**
* Custom PlatformView for displaying Penguin UI components within a Flutter app.
* Implements `PlatformView` for rendering the view, `MethodChannel.MethodCallHandler` for handling method calls,
* and `PenNavUIDelegate` for handling SDK events.
*/
@RequiresApi(Build.VERSION_CODES.O)
internal class PenguinView(
context: Context,
id: Int,
val creationParams: Map<String, Any>,
messenger: BinaryMessenger,
activity: MainActivity,
val channel: MethodChannel
) : PlatformView, MethodChannel.MethodCallHandler, PenNavUIDelegate {
// The layout for displaying the Penguin UI
private val mapLayout: RelativeLayout = RelativeLayout(context)
private val _context: Context = context
private val permissionResultReceiver: PermissionResultReceiver
private val permissionIntentFilter = IntentFilter("PERMISSION_RESULT_ACTION")
private companion object {
const val PERMISSIONS_REQUEST_CODE = 1
}
private lateinit var permissionManager: PermissionManager
// Reference to the main activity
private var _activity: Activity = activity
private lateinit var mContext: Context
lateinit var navigator: PenguinNavigator
init {
// Set layout parameters for the mapLayout
mapLayout.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
mContext = context
permissionResultReceiver = PermissionResultReceiver { granted ->
if (granted) {
onPermissionsGranted()
} else {
onPermissionsDenied()
}
}
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
mContext.registerReceiver(
permissionResultReceiver,
permissionIntentFilter,
RECEIVER_EXPORTED
)
} else {
mContext.registerReceiver(
permissionResultReceiver,
permissionIntentFilter,
)
}
// Set the background color of the layout
mapLayout.setBackgroundColor(Color.RED)
permissionManager = PermissionManager(
context = mContext,
listener = object : PermissionManager.PermissionListener {
override fun onPermissionGranted() {
// Handle permissions granted
onPermissionsGranted()
}
override fun onPermissionDenied() {
// Handle permissions denied
onPermissionsDenied()
}
},
requestCode = PERMISSIONS_REQUEST_CODE,
*PermissionHelper.getRequiredPermissions()
)
if (!permissionManager.arePermissionsGranted()) {
permissionManager.requestPermissions(_activity)
} else {
// Permissions already granted
permissionManager.listener.onPermissionGranted()
}
}
private fun onPermissionsGranted() {
// Handle the actions when permissions are granted
Log.d("PermissionsResult", "onPermissionsGranted")
// Register the platform view factory for creating custom views
// Initialize the Penguin SDK
initPenguin()
}
private fun onPermissionsDenied() {
// Handle the actions when permissions are denied
Log.d("PermissionsResult", "onPermissionsDenied")
}
/**
* Returns the view associated with this PlatformView.
*
* @return The main view for this PlatformView.
*/
override fun getView(): View {
return mapLayout
}
/**
* Cleans up resources associated with this PlatformView.
*/
override fun dispose() {
// Cleanup code if needed
}
/**
* Handles method calls from Dart code.
*
* @param call The method call from Dart.
* @param result The result callback to send responses back to Dart.
*/
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
// Handle method calls from Dart code here
}
/**
* Initializes the Penguin SDK with custom configuration and delegates.
*/
private fun initPenguin() {
navigator = PenguinNavigator()
// Configure the PlugAndPlaySDK
val language = when (creationParams["languageCode"] as String) {
"ar" -> Languages.ar
"en" -> Languages.en
else -> {
Languages.en
}
}
Log.d(
"TAG",
"initPenguin: ${Languages.getLanguageEnum(creationParams["languageCode"] as String)}"
)
PlugAndPlaySDK.configuration = PlugAndPlayConfiguration.Builder()
.setBaseUrl(
creationParams["dataURL"] as String,
creationParams["positionURL"] as String
)
.setServiceName(
creationParams["dataServiceName"] as String,
creationParams["positionServiceName"] as String
)
.setClientData(
creationParams["clientID"] as String,
creationParams["clientKey"] as String
)
.setUserName(creationParams["username"] as String)
// .setLanguageID(Languages.en)
.setLanguageID(language)
.setSimulationModeEnabled(creationParams["isSimulationModeEnabled"] as Boolean)
.setEnableBackButton(true)
// .setDeepLinkData("deeplink")
.setCustomizeColor("#2CA0AF")
.setDeepLinkSchema("")
.build()
// Set location delegate to handle location updates
PlugAndPlaySDK.setPiLocationDelegate {
// Example code to handle location updates
// Uncomment and modify as needed
// if (location.size() > 0)
// Toast.makeText(_context, "Location Info Latitude: ${location[0]}, Longitude: ${location[1]}", Toast.LENGTH_SHORT).show()
}
// Set events delegate for reporting issues
PlugAndPlaySDK.setPiEventsDelegate { }
// Start the Penguin SDK
PlugAndPlaySDK.start(mContext, this)
}
/**
* Navigates to the specified reference ID.
*
* @param refID The reference ID to navigate to.
*/
fun navigateTo(refID: String) {
try {
if (refID.isBlank()) {
Log.e("navigateTo", "Invalid refID: The reference ID is blank.")
}
// referenceId = refID
navigator.navigateTo(mContext, refID,object : RefIdDelegate {
override fun onRefByIDSuccess(PoiId: String?) {
Log.e("navigateTo", "PoiId is penguin view+++++++ $PoiId")
// channelFlutter.invokeMethod(
// PenguinMethod.navigateToPOI.name,
// "navigateTo Success"
// )
}
override fun onGetByRefIDError(error: String?) {
Log.e("navigateTo", "error is penguin view+++++++ $error")
// channelFlutter.invokeMethod(
// PenguinMethod.navigateToPOI.name,
// "navigateTo Failed: Invalid refID"
// )
}
} , creationParams["clientID"] as String, creationParams["clientKey"] as String )
} catch (e: Exception) {
Log.e("navigateTo", "Exception occurred during navigation: ${e.message}", e)
// channelFlutter.invokeMethod(
// PenguinMethod.navigateToPOI.name,
// "Failed: Exception - ${e.message}"
// )
}
}
/**
* Called when Penguin UI setup is successful.
*
* @param warningCode Optional warning code received from the SDK.
*/
override fun onPenNavSuccess(warningCode: String?) {
val clinicId = creationParams["clinicID"] as String
if(clinicId.isEmpty()) return
navigateTo(clinicId)
}
/**
* Called when there is an initialization error with Penguin UI.
*
* @param description Description of the error.
* @param errorType Type of initialization error.
*/
override fun onPenNavInitializationError(
description: String?,
errorType: InitializationErrorType?
) {
val arguments: Map<String, Any?> = mapOf(
"description" to description,
"type" to errorType?.name
)
channel.invokeMethod(PenguinMethod.onPenNavInitializationError.name, arguments)
Toast.makeText(mContext, "Navigation Error: $description", Toast.LENGTH_SHORT).show()
}
/**
* Called when Penguin UI is dismissed.
*/
override fun onPenNavUIDismiss() {
// Handle UI dismissal if needed
try {
mContext.unregisterReceiver(permissionResultReceiver)
dispose();
} catch (e: IllegalArgumentException) {
Log.e("PenguinView", "Receiver not registered: $e")
}
}
}

@ -22,7 +22,7 @@ import com.github.kittinunf.fuel.httpPost
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import io.flutter.plugin.common.MethodChannel
import org.jetbrains.anko.doAsyncResult
//import org.jetbrains.anko.doAsyncResult
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
@ -149,7 +149,7 @@ fun sendNotification(context: Context, title: String, @Nullable subtitle: String
val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setSmallIcon(R.mipmap.ic_launcher_local)
.setContentIntent(notificationPendingIntent)
.setAutoCancel(true)
.setContentTitle(title)
@ -208,7 +208,6 @@ fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTP
.header("Content-Type", "application/json")
.header("Allow", "*/*")
.response { request, response, result ->
result.doAsyncResult { }
result.fold({ data ->
val dataString = String(data)
if (isJSONValid(dataString)) {

@ -19,4 +19,5 @@
<string name="GEOFENCE_REQUEST_TOO_FREQUENT">
Geofence requests happened too frequently.
</string>
<string name="mapbox_access_token" translatable="false">sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg</string>
</resources>

@ -13,6 +13,20 @@ buildscript {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
maven {
url 'https://api.mapbox.com/downloads/v2/releases/maven'
credentials {
username = 'mapbox'
password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"
if (password == null || password == "") {
throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.")
}
}
authentication {
basic(BasicAuthentication)
}
}
// maven {
// url "https://dl.bintray.com/kotlin/kotlin-eap/"
@ -26,6 +40,7 @@ buildscript {
// classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12'
classpath "com.mapbox.gradle.plugins:access-token:0.4.0"
}
}
@ -34,12 +49,29 @@ allprojects {
google()
// jcenter()
mavenCentral()
flatDir {
dirs 'libs'
}
maven {
url 'https://developer.huawei.com/repo/'
}
maven {
url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local"
}
maven {
url 'https://api.mapbox.com/downloads/v2/releases/maven'
credentials {
username = 'mapbox'
password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"
if (password == null || password == "") {
throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.")
}
}
authentication {
basic(BasicAuthentication)
}
}
}
}

@ -3,3 +3,5 @@ org.gradle.jvmargs=-Xmx4096m
android.useAndroidX=true
android.enableJetifier=true
android.suppressUnsupportedCompileSdk=33
MAPBOX_USER_NAME = "mapbox"
MAPBOX_DOWNLOADS_TOKEN="sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"

@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
<string>13.0</string>
</dict>
</plist>

@ -33,6 +33,7 @@ target 'Runner' do
pod 'OpenTok', '~> 2.22.0'
pod 'VTO2Lib'
pod 'MapboxMaps', '10.18.2'
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
@ -54,6 +55,7 @@ post_install do |installer|
]
build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386'
build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
build_configuration.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
xcconfig_path = build_configuration.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR")
@ -62,6 +64,17 @@ post_install do |installer|
if build_configuration.build_settings['WRAPPER_EXTENSION'] == 'bundle'
build_configuration.build_settings['DEVELOPMENT_TEAM'] = '3A359E86ZF'
end
if target.name == 'MapboxMobileEvents'
`xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents -o Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents`
end
if target.name == 'MapboxCommon'
`xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon -o Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon`
end
if target.name == 'MapboxCoreMaps'
`xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxCoreMaps/MapboxCoreMaps.xcframework/ios-arm64/MapboxCoreMaps.framework/MapboxCoreMaps -o Pods/MapboxCoreMaps/MapboxCoreMaps.xcframework/ios-arm64/MapboxCoreMaps.framework/MapboxCoreMaps`
end
end
end
end

@ -8,18 +8,30 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
29631B9E2C96C7F600DF5916 /* PenguinNavigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */; };
301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */; };
301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */; };
306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; };
306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
4EE411B2E3CB5D4F81AE5078 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */; };
47C935002C91766800981BA7 /* Penguin.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FC2C91766400981BA7 /* Penguin.xcframework */; };
47C935012C91766800981BA7 /* Penguin.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FC2C91766400981BA7 /* Penguin.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
47C935022C91766900981BA7 /* PenguinINRenderer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */; };
47C935032C91766900981BA7 /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
47C935042C91766A00981BA7 /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */; };
47C935052C91766A00981BA7 /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
762D738E274E42650063CE73 /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 762D738C274E42650063CE73 /* ring_30Sec.caf */; };
762D738F274E42650063CE73 /* ring_30Sec.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 762D738D274E42650063CE73 /* ring_30Sec.mp3 */; };
76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76815B26275F381C00E66E94 /* HealthKit.framework */; };
76962ECE28AE5C10004EAE09 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */; };
76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */; };
76D71B6A2C6B819000DAFB84 /* PenguinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B692C6B819000DAFB84 /* PenguinModel.swift */; };
76D71B6C2C6B81B300DAFB84 /* PenguinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */; };
76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */; };
76D71B702C6B81EA00DAFB84 /* PenguinViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */; };
76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76F2556027F1FFED0062C1CD /* PassKit.framework */; };
76F9B0E22C6DED310064C51B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13E5B711BC29EB6ECCE1964C /* Pods_Runner.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@ -43,12 +55,15 @@
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
768D81742C6DF6E4005C655F /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
47C935032C91766900981BA7 /* PenguinINRenderer.xcframework in Embed Frameworks */,
47C935012C91766800981BA7 /* Penguin.xcframework in Embed Frameworks */,
47C935052C91766A00981BA7 /* PenNavUI.xcframework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -56,14 +71,18 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
13E5B711BC29EB6ECCE1964C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = "<group>"; };
301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = "<group>"; };
301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = "<group>"; };
306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = "<group>"; };
306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenguinINRenderer.xcframework; path = Frameworks/PenguinINRenderer.xcframework; sourceTree = "<group>"; };
47C934FB2C91766400981BA7 /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = "<group>"; };
47C934FC2C91766400981BA7 /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = "<group>"; };
6EE8819867EC2775AB578377 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -74,6 +93,11 @@
7643E4062BE0D0B400BD2F25 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
76815B26275F381C00E66E94 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; };
76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = "<group>"; };
76D71B692C6B819000DAFB84 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = "<group>"; };
76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinView.swift; sourceTree = "<group>"; };
76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinPlugin.swift; sourceTree = "<group>"; };
76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinViewFactory.swift; sourceTree = "<group>"; };
76F2556027F1FFED0062C1CD /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
838788A2BEDC4910F4B029A6 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
@ -110,10 +134,13 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
76F9B0E22C6DED310064C51B /* Pods_Runner.framework in Frameworks */,
76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */,
76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */,
E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */,
4EE411B2E3CB5D4F81AE5078 /* Pods_Runner.framework in Frameworks */,
47C935042C91766A00981BA7 /* PenNavUI.xcframework in Frameworks */,
47C935002C91766800981BA7 /* Penguin.xcframework in Frameworks */,
47C935022C91766900981BA7 /* PenguinINRenderer.xcframework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -133,10 +160,13 @@
555EAAA626EFB641859EF0BE /* Frameworks */ = {
isa = PBXGroup;
children = (
47C934FC2C91766400981BA7 /* Penguin.xcframework */,
47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */,
47C934FB2C91766400981BA7 /* PenNavUI.xcframework */,
76F2556027F1FFED0062C1CD /* PassKit.framework */,
76815B26275F381C00E66E94 /* HealthKit.framework */,
E9620804255C2ED100D3A35D /* NetworkExtension.framework */,
3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */,
13E5B711BC29EB6ECCE1964C /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -151,6 +181,18 @@
path = Pods;
sourceTree = "<group>";
};
76D71B682C6B817500DAFB84 /* Penguin */ = {
isa = PBXGroup;
children = (
76D71B692C6B819000DAFB84 /* PenguinModel.swift */,
76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */,
76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */,
76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */,
29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */,
);
path = Penguin;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@ -186,6 +228,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
76D71B682C6B817500DAFB84 /* Penguin */,
762D738C274E42650063CE73 /* ring_30Sec.caf */,
762D738D274E42650063CE73 /* ring_30Sec.mp3 */,
306FE6C9271D8B54002D6EFC /* OpenTok */,
@ -220,6 +263,7 @@
E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */,
306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */,
E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */,
76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */,
);
path = Helper;
sourceTree = "<group>";
@ -254,7 +298,7 @@
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
768D81742C6DF6E4005C655F /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
487FDD6493EB9AE7D8E39485 /* [CP] Embed Pods Frameworks */,
4671D3CD126F6635F4B75A6E /* [CP] Copy Pods Resources */,
@ -274,7 +318,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1430;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@ -419,12 +463,18 @@
buildActionMask = 2147483647;
files = (
306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */,
76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */,
E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */,
E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */,
76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */,
E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */,
E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */,
E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */,
E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */,
76D71B6C2C6B81B300DAFB84 /* PenguinView.swift in Sources */,
29631B9E2C96C7F600DF5916 /* PenguinNavigator.swift in Sources */,
76D71B6A2C6B819000DAFB84 /* PenguinModel.swift in Sources */,
76D71B702C6B81EA00DAFB84 /* PenguinViewFactory.swift in Sources */,
301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */,
E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */,
306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */,
@ -528,6 +578,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
@ -553,10 +604,13 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
@ -675,6 +729,7 @@
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
@ -700,10 +755,14 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@ -713,6 +772,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
@ -738,11 +798,14 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_COMPILATION_MODE = singlefile;
"SWIFT_COMPILATION_MODE[arch=*]" = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

@ -4,7 +4,7 @@ import GoogleMaps
var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil
@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {
let locationManager = CLLocationManager()
var flutterViewController:MainFlutterVC!
@ -30,11 +30,13 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil
flutterViewController = mainViewController
HMGPlatformBridge.initialize(flutterViewController: flutterViewController)
OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok"))
HMGPenguinInPlatformBridge.initialize(flutterViewController: flutterViewController)
}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"))
HMGPenguinInPlatformBridge.initialize(flutterViewController: flutterViewController)
}
}

@ -0,0 +1,61 @@
//
// HMGPenguinInPlatformBridge.swift
// Runner
//
// Created by Haroon Amjad on 13/08/2024.
//
import Foundation
var flutterMethodChannelPenguinIn:FlutterMethodChannel? = nil
fileprivate var mainViewController:MainFlutterVC!
class HMGPenguinInPlatformBridge{
private let channelName = "launch_penguin_ui"
private static var shared_:HMGPenguinInPlatformBridge?
class func initialize(flutterViewController:MainFlutterVC){
shared_ = HMGPenguinInPlatformBridge()
mainViewController = flutterViewController
shared_?.openChannel()
}
func shared() -> HMGPenguinInPlatformBridge{
assert((HMGPenguinInPlatformBridge.shared_ != nil), "HMGPenguinInPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.")
return HMGPenguinInPlatformBridge.shared_!
}
private func openChannel(){
flutterMethodChannelPenguinIn = FlutterMethodChannel(name: channelName, binaryMessenger: mainViewController.binaryMessenger)
flutterMethodChannelPenguinIn?.setMethodCallHandler { (methodCall, result) in
print("Called function \(methodCall.method)")
if let arguments = methodCall.arguments as Any? {
if methodCall.method == "launchPenguin"{
self.launchPenguinView(arguments: arguments, result: result)
}
} else {
result(FlutterError(code: "INVALID_ARGUMENT", message: "Storyboard name is required", details: nil))
}
}
}
private func launchPenguinView(arguments: Any, result: @escaping FlutterResult) {
let penguinView = PenguinView(
frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height),
viewIdentifier: 0,
arguments: arguments,
binaryMessenger: mainViewController.binaryMessenger
)
let penguinUIView = penguinView.view()
penguinUIView.frame = mainViewController.view.bounds
penguinUIView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mainViewController.view.addSubview(penguinUIView)
result(nil) // Call result to indicate the method was successfully handled
}
}

@ -39,7 +39,7 @@
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>11.0</string>
<string>13.0</string>
<key>NFCReaderUsageDescription</key>
<string>This app requires NFC Usage access to allow for Online CheckIn for appointments.</string>
<key>NSAppTransportSecurity</key>
@ -60,7 +60,7 @@
<key>NSCalendarsUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCalendarsWriteOnlyAccessUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCalendarsFullAccessUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCameraUsageDescription</key>

@ -0,0 +1,76 @@
//
// PenguinModel.swift
// Runner
//
// Created by Amir on 06/08/2024.
//
import Foundation
// Define the model class
struct PenguinModel {
let baseURL: String
let dataURL: String
let dataServiceName: String
let positionURL: String
let clientKey: String
let storyboardName: String
let mapBoxKey: String
let clientID: String
let positionServiceName: String
let username: String
let isSimulationModeEnabled: Bool
let isShowUserName: Bool
let isUpdateUserLocationSmoothly: Bool
let isEnableReportIssue: Bool
let languageCode: String
let clinicID: String
let patientID: String
let projectID: String
// Initialize the model from a dictionary
init?(from dictionary: [String: Any]) {
guard
let baseURL = dictionary["baseURL"] as? String,
let dataURL = dictionary["dataURL"] as? String,
let dataServiceName = dictionary["dataServiceName"] as? String,
let positionURL = dictionary["positionURL"] as? String,
let clientKey = dictionary["clientKey"] as? String,
let storyboardName = dictionary["storyboardName"] as? String,
let mapBoxKey = dictionary["mapBoxKey"] as? String,
let clientID = dictionary["clientID"] as? String,
let positionServiceName = dictionary["positionServiceName"] as? String,
let username = dictionary["username"] as? String,
let isSimulationModeEnabled = dictionary["isSimulationModeEnabled"] as? Bool,
let isShowUserName = dictionary["isShowUserName"] as? Bool,
let isUpdateUserLocationSmoothly = dictionary["isUpdateUserLocationSmoothly"] as? Bool,
let isEnableReportIssue = dictionary["isEnableReportIssue"] as? Bool,
let languageCode = dictionary["languageCode"] as? String,
let clinicID = dictionary["clinicID"] as? String,
let patientID = dictionary["patientID"] as? String,
let projectID = dictionary["projectID"] as? String
else {
print("Initialization failed due to missing or invalid keys.")
return nil
}
self.baseURL = baseURL
self.dataURL = dataURL
self.dataServiceName = dataServiceName
self.positionURL = positionURL
self.clientKey = clientKey
self.storyboardName = storyboardName
self.mapBoxKey = mapBoxKey
self.clientID = clientID
self.positionServiceName = positionServiceName
self.username = username
self.isSimulationModeEnabled = isSimulationModeEnabled
self.isShowUserName = isShowUserName
self.isUpdateUserLocationSmoothly = isUpdateUserLocationSmoothly
self.isEnableReportIssue = isEnableReportIssue
self.languageCode = languageCode
self.clinicID = clinicID
self.patientID = patientID
self.projectID = projectID
}
}

@ -0,0 +1,57 @@
import PenNavUI
import UIKit
class PenguinNavigator {
private var config: PenguinModel
init(config: PenguinModel) {
self.config = config
}
private func logError(_ message: String) {
// Centralized logging function
print("PenguinSDKNavigator Error: \(message)")
}
func navigateToPOI( referenceId:String,completion: @escaping (Bool, String?) -> Void) {
PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in
if let error = error {
let errorMessage = "Token error while getting the for Navigate to method"
completion(false, "Failed to get token: \(errorMessage)")
print("Failed to get token: \(errorMessage)")
return
}
guard let token = token else {
completion(false, "Token is nil")
print("Token is nil")
return
}
print("Token Generated")
print(token);
}
}
private func handleNavigation(referenceId: String, token: String, completion: @escaping (Bool, String?) -> Void) {
DispatchQueue.main.async {
PenNavUIManager.shared.setToken(token: token)
PenNavUIManager.shared.navigate(to: referenceId) { [weak self] _, navError in
guard let self = self else { return }
if let navError = navError {
self.logError("Navigation error: Reference ID invalid")
completion(false, "Navigation error: \(navError.localizedDescription)")
return
}
// Navigation successful
completion(true, nil)
}
}
}
}

@ -0,0 +1,31 @@
//
// BlueGpsPlugin.swift
// Runner
//
// Created by Penguin .
//
//import Foundation
//import Flutter
//
///**
// * A Flutter plugin for integrating Penguin SDK functionality.
// * This class registers a view factory with the Flutter engine to create native views.
// */
//class PenguinPlugin: NSObject, FlutterPlugin {
//
// /**
// * Registers the plugin with the Flutter engine.
// *
// * @param registrar The [FlutterPluginRegistrar] used to register the plugin.
// * This method is called when the plugin is initialized, and it sets up the communication
// * between Flutter and native code.
// */
// public static func register(with registrar: FlutterPluginRegistrar) {
// // Create an instance of PenguinViewFactory with the binary messenger from the registrar
// let factory = PenguinViewFactory(messenger: registrar.messenger())
//
// // Register the view factory with a unique ID for use in Flutter code
// registrar.register(factory, withId: "penguin_native")
// }
//}

@ -0,0 +1,224 @@
//
// BlueGpsView.swift
// Runner
//
// Created by Penguin.
//
import Foundation
import UIKit
import Flutter
import PenNavUI
import Foundation
import Flutter
import UIKit
/**
* A custom Flutter platform view for displaying Penguin UI components.
* This class integrates with the Penguin navigation SDK and handles UI events.
*/
class PenguinView: NSObject, FlutterPlatformView
, PIEventsDelegate, PenNavInitializationDelegate
{
// The main view displayed within the platform view
private var _view: UIView
private var model: PenguinModel?
/**
* Initializes the PenguinView with the provided parameters.
*
* @param frame The frame of the view, specifying its size and position.
* @param viewId A unique identifier for this view instance.
* @param args Optional arguments provided for creating the view.
* @param messenger The [FlutterBinaryMessenger] used for communication with Dart.
*/
init(
frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
binaryMessenger messenger: FlutterBinaryMessenger?
) {
_view = UIView()
super.init()
// Get the screen's width and height to set the view's frame
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
// Uncomment to set the background color of the view
// _view.backgroundColor = UIColor.red
// Set the frame of the view to cover the entire screen
_view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
print("========Inside Penguin View ========")
print(args)
guard let arguments = args as? [String: Any] else {
print("Error: Arguments are not in the expected format.")
return
}
print("===== i got tha Args=======")
// Initialize the model from the arguments
if let penguinModel = PenguinModel(from: arguments) {
self.model = penguinModel
initPenguin(args: penguinModel)
} else {
print("Error: Failed to initialize PenguinModel from arguments ")
}
// Initialize the Penguin SDK with required configurations
// initPenguin( arguments: args)
}
/**
* Initializes the Penguin SDK with custom configuration settings.
*/
func initPenguin(args: PenguinModel) {
// Set the initialization delegate to handle SDK initialization events
PenNavUIManager.shared.initializationDelegate = self
// Configure the Penguin SDK with necessary parameters
PenNavUIManager.shared
.setClientKey(args.clientKey)
.setClientID(args.clientID)
.setUsername(args.username)
.setSimulationModeEnabled(isEnable: args.isSimulationModeEnabled)
.setBaseURL(dataURL: args.dataURL, positionURL: args.positionURL)
.setServiceName(dataServiceName: args.dataServiceName, positionServiceName: args.positionServiceName)
.setIsShowUserName(args.isShowUserName)
.setIsUpdateUserLocationSmoothly(args.isUpdateUserLocationSmoothly)
.setEnableReportIssue(enable: args.isEnableReportIssue)
.setLanguage(args.languageCode)
.setBackButtonVisibility(true)
.build()
}
/**
* Returns the main view associated with this platform view.
*
* @return The UIView instance that represents this platform view.
*/
func view() -> UIView {
return _view
}
// MARK: - PIEventsDelegate Methods
/**
* Called when the Penguin UI is dismissed.
*/
func onPenNavUIDismiss() {
// Handle UI dismissal if needed
print("====== onPenNavUIDismiss =========")
self.view().removeFromSuperview()
}
/**
* Called when a report issue is generated.
*
* @param issue The type of issue reported.
*/
func onReportIssue(_ issue: PenNavUI.IssueType) {
// Handle report issue events if needed
print("====== onReportIssueError =========")
}
/**
* Called when the Penguin UI setup is successful.
*/
func onPenNavSuccess() {
print("====== onPenNavSuccess =========")
// Obtain the FlutterViewController instance
let controller: FlutterViewController = UIApplication.shared.windows.first?.rootViewController as! FlutterViewController
print("====== after contoller onPenNavSuccess =========")
// Set the events delegate to handle SDK events
PenNavUIManager.shared.eventsDelegate = self
print("====== after eventsDelegate onPenNavSuccess =========")
// Present the Penguin UI on top of the Flutter view controller
PenNavUIManager.shared.present(root: controller, view: _view)
print("====== after present onPenNavSuccess =========")
print(model?.clinicID)
print("====== after present onPenNavSuccess =========")
guard let config = self.model else {
print("Error: Config Model is nil")
return
}
guard let clinicID = self.model?.clinicID,
let clientID = self.model?.clientID, !clientID.isEmpty else {
print("Error: Config Client ID is nil or empty")
return
}
let navigator = PenguinNavigator(config: config)
PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in
if let error = error {
let errorMessage = "Token error while getting the for Navigate to method"
print("Failed to get token: \(errorMessage)")
return
}
guard let token = token else {
print("Token is nil")
return
}
print("Token Generated")
print(token);
self?.handleNavigation(clinicID: clinicID, token: token) { success, errorMessage in
if success {
print("Navigation successful")
} else {
print("Navigation failed: \(errorMessage ?? "Unknown error")")
}
}
print("====== after Token onPenNavSuccess =========")
}
}
private func handleNavigation(clinicID: String, token: String, completion: @escaping (Bool, String?) -> Void) {
DispatchQueue.main.async {
PenNavUIManager.shared.setToken(token: token)
PenNavUIManager.shared.navigate(to: clinicID)
completion(true,nil)
}
}
/**
* Called when there is an initialization error with the Penguin UI.
*
* @param errorType The type of initialization error.
* @param errorDescription A description of the error.
*/
func onPenNavInitializationError(errorType: PenNavUI.PenNavUIError, errorDescription: String) {
// Handle initialization errors if needed
print("onPenNavInitializationErrorType: \(errorType.rawValue)")
print("onPenNavInitializationError: \(errorDescription)")
}
}

@ -0,0 +1,59 @@
//
// BlueGpsViewFactory.swift
// Runner
//
// Created by Penguin .
//
import Foundation
import Flutter
/**
* A factory class for creating instances of [PenguinView].
* This class implements `FlutterPlatformViewFactory` to create and manage native views.
*/
class PenguinViewFactory: NSObject, FlutterPlatformViewFactory {
// The binary messenger used for communication with the Flutter engine
private var messenger: FlutterBinaryMessenger
/**
* Initializes the PenguinViewFactory with the given messenger.
*
* @param messenger The [FlutterBinaryMessenger] used to communicate with Dart code.
*/
init(messenger: FlutterBinaryMessenger) {
self.messenger = messenger
super.init()
}
/**
* Creates a new instance of [PenguinView].
*
* @param frame The frame of the view, specifying its size and position.
* @param viewId A unique identifier for this view instance.
* @param args Optional arguments provided for creating the view.
* @return An instance of [PenguinView] configured with the provided parameters.
*/
func create(
withFrame frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) -> FlutterPlatformView {
return PenguinView(
frame: frame,
viewIdentifier: viewId,
arguments: args,
binaryMessenger: messenger)
}
/**
* Returns the codec used for encoding and decoding method channel arguments.
* This method is required when `arguments` in `create` is not `nil`.
*
* @return A [FlutterMessageCodec] instance used for serialization.
*/
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}

@ -22,8 +22,8 @@ var PACKAGES_ORDER_HISTORY = '/api/orders/items';
var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara';
// var BASE_URL = 'http://10.50.100.198:2018/';
// var BASE_URL = 'http://10.50.100.198:4422/';
// var BASE_URL = 'https://uat.hmgwebservices.com/';
var BASE_URL = 'https://hmgwebservices.com/';
var BASE_URL = 'https://uat.hmgwebservices.com/';
// var BASE_URL = 'https://hmgwebservices.com/';
// var BASE_URL = 'http://10.20.200.111:1010/';
// var BASE_URL = 'https://orash.cloudsolutions.com.sa/';
// var BASE_URL = 'https://vidauat.cloudsolutions.com.sa/';

@ -1976,5 +1976,8 @@ const Map localizedValues = {
"selectHospitalBloodDonation": {"en": "Please select the hospital you want to book an appointment with: ", "ar": "يرجى اختيار المستشفى الذي تريد حجز موعد معه:"},
"wecare": {"en": "We Care", "ar": "نحن نهتم"},
"myinstructions": {"en": "My Instructions", "ar": "تعليماتي"},
"clinicLocation": {"en": "Clinic Location", "ar": "موقع العيادة"},
"searchClinic": {"en": "Search Clinic", "ar": "بحث العيادة"},
"selectBranch":{"en":"Select Branch", "ar":"اختر الفرع"},
"searchByBranch":{"en":"Search By Branch Name", "ar":"البحث عن طريق اسم الفرع"}
};

@ -199,9 +199,9 @@ class BaseAppClient {
// }
// if (AppGlobal.isNetworkDebugEnabled) {
// print("URL : $url");
// final jsonBody = json.encode(body);
// print(jsonBody);
print("URL : $url");
final jsonBody = json.encode(body);
print(jsonBody);
// }
if (await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck)) {

@ -19,6 +19,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart';
bool isAppArabic = false;
class ProjectViewModel extends BaseViewModel {
GAnalytics get analytics => locator<GAnalytics>();
@ -38,6 +39,7 @@ class ProjectViewModel extends BaseViewModel {
dynamic searchvalue;
bool isLogin = false;
bool _isAllAppointmentsLoaded = false;
bool get isAllAppointmentsLoaded => _isAllAppointmentsLoaded;
bool isPatientAdmitted = false;
bool patientHasAdmissionRequest = false;
@ -45,15 +47,17 @@ class ProjectViewModel extends BaseViewModel {
GetAdmissionInfoResponseModel getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel();
GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel();
bool isIndoorNavigationEnabled = false;
void setIsAllAppointmentsLoaded(bool value) {
_isAllAppointmentsLoaded = value;
notifyListeners();
}
RegisterInfoResponse _registerInfo = RegisterInfoResponse();
RegisterInfoResponse get registerInfo => _registerInfo;
dynamic get searchValue => searchvalue;
Locale get appLocal => _appLocale;
@ -70,7 +74,9 @@ class ProjectViewModel extends BaseViewModel {
List<ProjectDetailListModel> _projectDetailListModel = [];
List<PrivilegeModel> get privileges => isLoginChild ? privilegeChildUser : privilegeChildUser;
List<VidaPlusProjectListModel> get vidaPlusProjectList => _vidaPlusProjectListModel;
List<HMCProjectListModel> get hMCProjectListModel => _hMCProjectListModel;
List<ProjectDetailListModel> get projectDetailListModel => _projectDetailListModel;
@ -137,6 +143,11 @@ class ProjectViewModel extends BaseViewModel {
notifyListeners();
}
setIsIndoorNavigationEnabled(bool isEnabled) {
this.isIndoorNavigationEnabled = isEnabled;
notifyListeners();
}
setPatientHasAdmissionRequest(bool hasAdmissionRequest) {
this.patientHasAdmissionRequest = hasAdmissionRequest;
notifyListeners();
@ -200,8 +211,6 @@ class ProjectViewModel extends BaseViewModel {
notifyListeners();
}
bool havePrivilege(int id) {
bool isHavePrivilege = false;
try {
@ -222,7 +231,7 @@ class ProjectViewModel extends BaseViewModel {
@override
void dispose() {
if (subscription != null) subscription.cancel();
if (subscription != null) subscription.cancel();
super.dispose();
}

@ -37,6 +37,7 @@ class _AllHabibMedicalSevicePage2State extends State<AllHabibMedicalSevicePage2>
AuthProvider authProvider = new AuthProvider();
WeatherService _weatherService = WeatherService();
double weatherNum = 30;
late ProjectViewModel projectViewModel;
@override
void initState() {
@ -235,7 +236,7 @@ class _AllHabibMedicalSevicePage2State extends State<AllHabibMedicalSevicePage2>
itemCount: hmgServices.length,
padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) {
return ServicesView(hmgServices[index], index, false);
return ServicesView(hmgServices[index], index, false, projectViewModel);
},
),
),

@ -272,7 +272,7 @@ class _InPatientPendingAdvancePaymentState extends State<InPatientPendingAdvance
if (isCopy) {
Share.share(paymentLink);
} else {
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(paymentLink)), options: _InAppBrowserOptions);
this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(paymentLink))), options: _InAppBrowserOptions);
}
} else {
AppToast.showErrorToast(message: res["endUserMessage"]);

@ -39,6 +39,7 @@ class BookedButtons {
"icon": "hosp_location.svg",
"caller": "navigateToProject",
},
{"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"}
{"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"},
// {"title": TranslationBase.of(AppGlobal.context).clinic, "subtitle": TranslationBase.of(AppGlobal.context).locationa, "icon": "hosp_location.svg", "caller": "goToNavigation"}
];
}

@ -19,6 +19,7 @@ class ConfirmedButtons {
// "icon": "assets/images/new-design/generate_visit_ticket.png",
// "caller": "visitTicket"
// },
{"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"}
{"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"},
// {"title": TranslationBase.of(AppGlobal.context).clinic, "subtitle": TranslationBase.of(AppGlobal.context).locationa, "icon": "hosp_location.svg", "caller": "goToNavigation"}
];
}

@ -27,9 +27,11 @@ import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_it
import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_details_page.dart';
import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart';
@ -40,6 +42,7 @@ import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
import 'package:huawei_map/huawei_map.dart' as hmsMap;
import 'package:intl/intl.dart';
import 'package:map_launcher/map_launcher.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
@ -178,6 +181,31 @@ class _AppointmentActionsState extends State<AppointmentActions> {
navigateToInsertComplaint();
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint');
break;
case "goToNavigation":
initPenguinSDK();
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'navigate to clinic');
break;
}
}
initPenguinSDK() async {
NavigationClinicDetails data = NavigationClinicDetails();
// data.clinicId = widget.appo.clinicID.toString();
data.clinicId = "49";
data.patientId = widget.appo.patientID.toString();
data.projectId = widget.appo.projectID.toString();
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.activityRecognition,
].request().whenComplete(() {
PenguinMethodChannel.launch("penguin", widget.projectViewModel!.isArabic ? "ar" : "en", widget.projectViewModel!.authenticatedUserObject.user.patientID.toString(), details: data);
});
}
}

@ -29,10 +29,12 @@ import 'package:diplomaticquarterapp/services/livecare_services/livecare_provide
import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart';
import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
@ -50,6 +52,7 @@ import 'package:flutter_countdown_timer/current_remaining_time.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
class ToDo extends StatefulWidget {
@ -354,23 +357,56 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 25 / 16),
),
),
InkWell(
onTap: () {
navigateToAppointmentDetails(context, appoList[index]);
},
child: Padding(
padding: const EdgeInsets.only(top: 0.0),
child: Text(
TranslationBase.of(context).moreDetails,
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w600,
color: CustomColors.accentColor,
letterSpacing: -0.48,
height: 25 / 16,
decoration: TextDecoration.underline),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
navigateToAppointmentDetails(context, appoList[index]);
},
child: Padding(
padding: const EdgeInsets.only(top: 0.0),
child: Text(
TranslationBase.of(context).moreDetails,
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w600,
color: CustomColors.accentColor,
letterSpacing: -0.48,
height: 25 / 16,
decoration: TextDecoration.underline),
),
),
),
),
if (projectViewModel.isIndoorNavigationEnabled)
InkWell(
onTap: () {
NavigationClinicDetails data = NavigationClinicDetails();
// data.clinicId = appoList[index].clinicID.toString();
data.clinicId = "46";
data.patientId = appoList[index].patientID.toString();
data.projectId = appoList[index].projectID.toString();
initPenguinSDK(data);
},
child: Column(
children: [
SvgPicture.asset(
"assets/images/new/Indoor_nav_appo.svg",
),
Text(
TranslationBase.of(context).clinicLocation,
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w600,
color: CustomColors.accentColor,
letterSpacing: -0.48,
height: 25 / 16,
decoration: TextDecoration.underline),
),
],
),
),
],
),
],
),
@ -530,6 +566,21 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
);
}
initPenguinSDK(NavigationClinicDetails data) async {
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.activityRecognition,
].request().whenComplete(() {
PenguinMethodChannel.launch("penguin", projectViewModel.isArabic ? "ar" : "en", projectViewModel.authenticatedUserObject.user.patientID.toString(), details: data);
});
}
}
String getNextActionImage(nextAction) {
switch (nextAction) {
case 0:

@ -52,7 +52,11 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
hmgServices.add(HmgServices(0, TranslationBase.of(context).book, TranslationBase.of(context).appointmentLabel, "assets/images/new/book appointment.svg", isLogin));
hmgServices.add(HmgServices(1, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin));
hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin));
projectViewModel.isIndoorNavigationEnabled
? hmgServices.add(HmgServices(2, "Hospital", "Navigation", "assets/images/new/indoor_nav_home.svg", isLogin))
: hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin));
hmgServices.add(HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin));
hmgServices.add(HmgServices(4, TranslationBase.of(context).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin));
hmgServices.add(HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin));
@ -296,15 +300,16 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
child: ServicesView(
new HmgServices(23, TranslationBase.of(context).InPatient, TranslationBase.of(context).inPatientServices, "assets/images/new/InPatient.svg", false),
23,
true)),
true,
projectViewModel)),
),
),
Expanded(
flex: 4,
child: AspectRatio(
aspectRatio: 1.0,
child: ServicesView(
new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2, true)),
child: ServicesView(new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2,
true, projectViewModel)),
),
],
),
@ -322,7 +327,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
itemCount: hmgServices.length,
padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) {
return ServicesView(hmgServices[index], index, true);
return ServicesView(hmgServices[index], index, true, projectViewModel);
},
),
),
@ -341,7 +346,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
itemCount: hmgServices.length,
padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) {
return ServicesView(hmgServices[index], index, true);
return ServicesView(hmgServices[index], index, true, projectViewModel, isLocked: hmgServices[index].action == 2 ? !projectViewModel.havePrivilege(107) : false);
},
),
),
@ -489,8 +494,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
flex: 1,
child: InkWell(
onTap: () {
if (projectViewModel.havePrivilege(100))
widget.onPharmacyClick!();
if (projectViewModel.havePrivilege(100)) widget.onPharmacyClick!();
},
child: Stack(children: [
Container(

@ -43,7 +43,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart';
// import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart';
@ -664,7 +664,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString();
model.setState(model.count, 0, true, notificationCount);
sharedPref.setString(NOTIFICATION_COUNT, notificationCount);
FlutterAppIconBadge.updateBadge(int.parse(notificationCount));
// FlutterAppIconBadge.updateBadge(int.parse(notificationCount));
}
});
// if (await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN) == null || !await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN)) {

@ -4,7 +4,9 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/hmg_services.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart';
@ -31,14 +33,20 @@ import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart
import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/location_util.dart';
import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/location_selection_dialog.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../locator.dart';
@ -52,8 +60,10 @@ class ServicesView extends StatelessWidget {
PharmacyModuleViewModel pharmacyModuleViewModel = locator<PharmacyModuleViewModel>();
late LocationUtils locationUtils;
bool isHomePage;
late ProjectViewModel projectViewModel;
bool isLocked;
ServicesView(this.hmgServices, this.index, this.isHomePage);
ServicesView(this.hmgServices, this.index, this.isHomePage, this.projectViewModel, {this.isLocked = false});
@override
Widget build(BuildContext context) {
@ -159,12 +169,57 @@ class ServicesView extends StatelessWidget {
],
),
),
isLocked
? Container(
width: double.infinity,
height: double.infinity,
decoration: containerRadiusWithGradientServices(20, lightColor: Colors.grey.withOpacity(0.6), darkColor: Colors.grey.withOpacity(0.6)),
child: Icon(
Icons.lock_outline,
size: 40,
),
)
: Container()
],
),
),
);
}
openNavigationProjectSelection(BuildContext context) {
int _selectedHospitalIndex = 0;
List<HospitalsModel> projectsListLocal = [];
Utils.navigationProjectsList.forEach((v) {
projectsListLocal.add(new HospitalsModel.fromJson(v));
});
showDialog(
context: context,
builder: (cxt) => LocationSelectionDialog(
data: projectsListLocal,
selectedIndex: _selectedHospitalIndex,
onValueSelected: (index) {
_selectedHospitalIndex = index;
initPenguinSDK(projectsListLocal[index].iD);
},
),
);
}
initPenguinSDK(int projectID) async {
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.activityRecognition,
].request().whenComplete(() {
PenguinMethodChannel.launch("penguin", projectViewModel.isArabic ? "ar" : "en", "1231755");
});
} //
}
handleHomePageServices(HmgServices hmgServices, BuildContext context) {
if (hmgServices.action == 0) {
Navigator.push(context, FadePage(page: Search()));
@ -172,8 +227,13 @@ class ServicesView extends StatelessWidget {
} else if (hmgServices.action == 1) {
openLiveCare(context);
} else if (hmgServices.action == 2) {
Navigator.push(context, FadePage(page: ErOptions(isAppbar: true)));
locator<GAnalytics>().hmgServices.logServiceName('emergency service');
// initPenguinSDK();
if (projectViewModel.isIndoorNavigationEnabled) {
if (!isLocked) openNavigationProjectSelection(context);
} else {
Navigator.push(context, FadePage(page: ErOptions(isAppbar: true)));
locator<GAnalytics>().hmgServices.logServiceName('emergency service');
}
} else if (hmgServices.action == 3) {
Navigator.push(context, FadePage(page: HomeHealthCarePage()));
locator<GAnalytics>().hmgServices.logServiceName('home health care');
@ -266,10 +326,8 @@ class ServicesView extends StatelessWidget {
} else if (hmgServices.action == 21) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => MyWebView(
title: "HMG News",
selectedUrl:"https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live",
),
builder: (BuildContext context) => MyWebView(title: "HMG News", selectedUrl: "https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live",
),
),
);
locator<GAnalytics>().hmgServices.logServiceName('latest news');

@ -14,7 +14,7 @@ class VideoCallWebPage extends StatelessWidget{
final String receiverId;
final String callerId;
VideoCallWebPage({required this.receiverId, required this.callerId}){
request = URLRequest(url: Uri.parse("https://vcallapi.hmg.com/Mobileindex.html?username=$receiverId&doctorid=$callerId"));
request = URLRequest(url: WebUri.uri(Uri.parse("https://vcallapi.hmg.com/Mobileindex.html?username=$receiverId&doctorid=$callerId")));
}
InAppWebViewGroupOptions options = InAppWebViewGroupOptions(

@ -34,7 +34,7 @@ class _syncHealthDataButtonState extends State<syncHealthDataButton> {
int MedCategoryID = 0;
HealthFactory health = HealthFactory();
// HealthFactory health = HealthFactory();
List<HealthDataType> types = [HealthDataType.STEPS, HealthDataType.HEART_RATE, Platform.isAndroid ? HealthDataType.DISTANCE_DELTA : HealthDataType.DISTANCE_WALKING_RUNNING];
@override
@ -48,29 +48,29 @@ class _syncHealthDataButtonState extends State<syncHealthDataButton> {
}
checkPermissions() async {
if (Platform.isAndroid) {
if (await PermissionService.isHealthDataPermissionEnabled()) {
await health.requestAuthorization(types).then((value) {
if (value) {
readAll();
}
});
} else {
Utils.showPermissionConsentDialog(context, TranslationBase.of(context).physicalActivityPermission, () async {
await health.requestAuthorization(types).then((value) {
if (value) {
readAll();
}
});
});
}
} else {
await health.requestAuthorization(types).then((value) {
if (value) {
readAll();
}
});
}
// if (Platform.isAndroid) {
// if (await PermissionService.isHealthDataPermissionEnabled()) {
// await health.requestAuthorization(types).then((value) {
// if (value) {
// readAll();
// }
// });
// } else {
// Utils.showPermissionConsentDialog(context, TranslationBase.of(context).physicalActivityPermission, () async {
// await health.requestAuthorization(types).then((value) {
// if (value) {
// readAll();
// }
// });
// });
// }
// } else {
// await health.requestAuthorization(types).then((value) {
// if (value) {
// readAll();
// }
// });
// }
}
void readAll() async {
@ -83,13 +83,13 @@ class _syncHealthDataButtonState extends State<syncHealthDataButton> {
DateTime startDate = DateTime.now().subtract(new Duration(days: 30));
try {
List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types);
_healthDataList.addAll(healthData);
// List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types);
// _healthDataList.addAll(healthData);
} catch (e) {
print("Caught exception in getHealthDataFromTypes: $e");
}
_healthDataList = HealthFactory.removeDuplicates(_healthDataList);
// _healthDataList = HealthFactory.removeDuplicates(_healthDataList);
_healthDataList.forEach((x) {
if (x.type == HealthDataType.STEPS) {

@ -54,7 +54,7 @@ class PayfortService extends BaseService {
"Pat_Token": result.tokenName,
"IsRefund": false,
"RemmeberMe": false,
"Reconciliation_Reference": result.reconciliationReference,
// "Reconciliation_Reference": result.reconciliationReference,
"LanguageID": 1,
"PatientID": patientID
};

@ -3,7 +3,7 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart';
import 'package:flutter/material.dart';
import 'package:localstorage/localstorage.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:vibration/vibration.dart';
// import 'package:vibration/vibration.dart';
import 'package:geolocator/geolocator.dart' as geo;
class PermissionService extends BaseService {
@ -25,10 +25,10 @@ class PermissionService extends BaseService {
vibrate(callback, context) async {
if (callback == null) return null;
if (isVibrationEnabled() == true) {
if (await Vibration.hasVibrator() !=null) {
Vibration.vibrate(duration: 100);
callback();
}
// if (await Vibration.hasVibrator() !=null) {
// Vibration.vibrate(duration: 100);
// callback();
// }
} else {
callback();
}

@ -7,9 +7,7 @@ import 'package:permission_handler/permission_handler.dart';
import 'PlatformBridge.dart';
class AppPermission{
class AppPermission {
static Future<bool> askVideoCallPermission(BuildContext context) async {
if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) {
return false;
@ -21,6 +19,30 @@ class AppPermission{
return true;
}
//
// Manifest.permission.INTERNET,
// Manifest.permission.ACCESS_FINE_LOCATION,
// Manifest.permission.ACCESS_COARSE_LOCATION,
// Manifest.permission.ACCESS_NETWORK_STATE,
// Manifest.permission.BLUETOOTH,
// Manifest.permission.BLUETOOTH_ADMIN,
// Manifest.permission.BLUETOOTH_SCAN,
// Manifest.permission.BLUETOOTH_CONNECT,
// Manifest.permission.HIGH_SAMPLING_RATE_SENSORS,
// Manifest.permission.ACTIVITY_RECOGNITION
static Future<bool> askPenguinPermissions() async {
if (!(await Permission.location.request().isGranted) ||
!(await Permission.bluetooth.request().isGranted) ||
!(await Permission.bluetoothScan.request().isGranted) ||
!(await Permission.bluetoothConnect.request().isGranted) ||
!(await Permission.activityRecognition.request().isGranted)) {
return false;
}
return true;
}
static Future _drawOverAppsMessageDialog(BuildContext context) async {
ConfirmDialog dialog = new ConfirmDialog(
context: context,
@ -34,4 +56,4 @@ class AppPermission{
cancelFunction: () => {});
dialog.showAlertDialog(context);
}
}
}

@ -0,0 +1,98 @@
import 'package:flutter/services.dart';
class PenguinMethodChannel {
static const MethodChannel _channel = MethodChannel('launch_penguin_ui');
static Future<void> launch(String storyboardName, String languageCode, String username, {NavigationClinicDetails? details}) async {
try {
await _channel.invokeMethod('launchPenguin', {
"storyboardName": storyboardName,
"baseURL": "https://prod.hmg.nav.penguinin.com",
// "dataURL": "https://hmg.nav.penguinin.com",
// "positionURL": "https://hmg.nav.penguinin.com",
// "dataURL": "https://hmg-v33.local.penguinin.com",
// "positionURL": "https://hmg-v33.local.penguinin.com",
"dataURL": "https://prod.hmg.nav.penguinin.com",
"positionURL": "https://prod.hmg.nav.penguinin.com",
"dataServiceName": "api",
"positionServiceName": "pe",
"clientID": "HMG",
"username": "test",
"isSimulationModeEnabled": false,
"isShowUserName": false,
"isUpdateUserLocationSmoothly": true,
"isEnableReportIssue": true,
"languageCode": languageCode,
"clientKey": "UGVuZ3VpbklOX1Blbk5hdl9QSUY=",
"mapBoxKey": "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg",
// "clinicID": details?.clinicId ?? "",
"clinicID": details?.clinicId ?? "", // 46 ,49, 133
"patientID": details?.patientId ?? "",
"projectID": details?.projectId ?? "",
});
} on PlatformException catch (e) {
print("Failed to launch PenguinIn: '${e.message}'.");
}
}
void setMethodCallHandler(){
_channel.setMethodCallHandler((MethodCall call) async {
try {
print(call.method);
switch (call.method) {
case PenguinMethodNames.onPenNavInitializationError:
_handleInitializationError(call.arguments); // Handle onPenNavInitializationError errors.
break;
case PenguinMethodNames.onPenNavUIDismiss:
//todo handle pen dismissable
// _handlePenNavUIDismiss(); // Handle UI dismissal event.
break;
case PenguinMethodNames.onReportIssue:
// Handle the report issue event.
_handleInitializationError(call.arguments);
break;
default:
_handleUnknownMethod(call.method); // Handle unknown method calls.
}
} catch (e) {
print("Error handling method call '${call.method}': $e");
// Optionally, log this error to an external service
}
});
}
static void _handleUnknownMethod(String method) {
print("Unknown method: $method");
// Optionally, handle this unknown method case, such as reporting or ignoring it
}
static void _handleInitializationError(Map<dynamic, dynamic> error) {
final type = error['type'] as String?;
final description = error['description'] as String?;
print("Initialization Error: ${type ?? 'Unknown Type'}, ${description ?? 'No Description'}");
}
}
// Define constants for method names
class PenguinMethodNames {
static const String showPenguinUI = 'showPenguinUI';
static const String openSharedLocation = 'openSharedLocation';
// ---- Handler Method
static const String onPenNavSuccess = 'onPenNavSuccess'; // Tested Android,iOS
static const String onPenNavInitializationError = 'onPenNavInitializationError'; // Tested Android,iOS
static const String onPenNavUIDismiss = 'onPenNavUIDismiss'; //Tested Android,iOS
static const String onReportIssue = 'onReportIssue'; // Tested Android,iOS
static const String onLocationOffCampus = 'onLocationOffCampus'; // Tested iOS,Android
static const String navigateToPOI = 'navigateToPOI'; // Tested Android,iOS
}
class NavigationClinicDetails {
String? clinicId;
String? patientId;
String? projectId;
}

@ -15,6 +15,7 @@ import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart';
import 'package:diplomaticquarterapp/uitl/LocalNotification.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_messaging/firebase_messaging.dart' as fir;
@ -388,9 +389,16 @@ class PushNotificationHandler {
if (remoteMessage.data.isEmpty) {
return;
}
debugPrint('the value of the remote message is ${remoteMessage.data}');
if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) {
_incomingCall(remoteMessage.data);
// showCallkitIncoming(remoteMessage.data);
}if(remoteMessage.data['is_navigation'] == 'true' || remoteMessage.data['is_navigation'] == true ){
NavigationClinicDetails data = NavigationClinicDetails();
data.clinicId = remoteMessage.data['clinic_Id'];
data.patientId = remoteMessage.data['patient_Id'];
data.projectId = remoteMessage.data['project_Id'];
initPenguinSDK(data);
} else {
GetNotificationsResponseModel notification = new GetNotificationsResponseModel();
@ -408,6 +416,21 @@ class PushNotificationHandler {
}
}
initPenguinSDK(NavigationClinicDetails data) async {
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.activityRecognition,
].request().whenComplete(() {
PenguinMethodChannel.launch("penguin", "en", "1231755", details: data);
});
}
}
onToken(String token) async {
// print("Push Notification Token: " + token);
await AppSharedPreferences().setString(PUSH_TOKEN, token);

@ -2963,7 +2963,10 @@ class TranslationBase {
String get selectHospitalBloodDonation => localizedValues["selectHospitalBloodDonation"][locale.languageCode];
String get wecare => localizedValues["wecare"][locale.languageCode];
String get myinstructions => localizedValues["myinstructions"][locale.languageCode];
String get clinicLocation => localizedValues["clinicLocation"][locale.languageCode];
String get searchClinic => localizedValues["searchClinic"][locale.languageCode];
String get selectBranch => localizedValues["selectBranch"][locale.languageCode];
String get searchByBranch => localizedValues["searchByBranch"][locale.languageCode];
}

@ -65,6 +65,30 @@ AppSharedPreferences sharedPref = new AppSharedPreferences();
class Utils {
// static ProgressDialog pr;
static var navigationProjectsList = [
{
"Desciption": "Sahafa Hospital",
"DesciptionN": null,
"ID": 130,
"LegalName": "Sahafa Hospital",
"LegalNameN": "مستشفى الصحافة",
"Name": "Sahafa Hospital",
"NameN": null,
"PhoneNumber": "+966115222222",
"SetupID": "013311",
"DistanceInKilometers": 0,
"HasVida3": false,
"IsActive": true,
"IsHmg": true,
"IsVidaPlus": false,
"Latitude": "24.8113774",
"Longitude": "46.6239813",
"MainProjectID": 130,
"ProjectOutSA": false,
"UsingInDoctorApp": false
}
];
///show custom Error Toast
/// [message] to show for user
static showErrorToast([String? message]) {
@ -909,7 +933,7 @@ class Utils {
return projectDetailListModel;
}
//static String generateSignature() {}
//static String generateSignature() {}
}
Widget applyShadow({Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), required Widget child}) {

@ -0,0 +1,290 @@
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/medical/radiology_view_model.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:flutter/material.dart';
import '../../uitl/translations_delegate_base.dart';
class LocationSelectionDialog extends StatelessWidget {
final List<HospitalsModel> data;
final Function(int)? onValueSelected;
final int? selectedIndex;
const LocationSelectionDialog(
{super.key,
required this.data,
this.onValueSelected,
this.selectedIndex});
@override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: LocationDialogBody(
data: data,
onValueSelected: onValueSelected,
selectedIndex: selectedIndex,
));
}
}
class LocationDialogBody extends StatefulWidget {
final List<HospitalsModel> data;
final Function(int)? onValueSelected;
final int? selectedIndex;
const LocationDialogBody(
{super.key,
required this.data,
this.onValueSelected,
this.selectedIndex});
@override
State<LocationDialogBody> createState() => _LocationDialogBodyState();
}
class _LocationDialogBodyState extends State<LocationDialogBody> {
bool isListVisible = false;
int currentlySelected = -1;
@override
Widget build(BuildContext context) {
return isListVisible
? LocationListExpandedBody(
data: widget.data,
onItemClick: (data) {
if (data.isEmpty) return;
var selected = widget.data.indexWhere(
(item) => item.name == data,
);
if (selected == -1) return;
setState(() {
currentlySelected = selected;
isListVisible = false;
});
},
)
: LocationListWrapBody(
onConfirmClicked: () {
widget.onValueSelected?.call(currentlySelected);
},
onTextBoxClicked: () {
setState(() {
isListVisible = true;
});
},
selectedText: currentlySelected == -1
? ""
: widget.data[currentlySelected].name ?? "");
}
}
class LocationListExpandedBody extends StatefulWidget {
final List<HospitalsModel> data;
final Function(String) onItemClick;
const LocationListExpandedBody(
{super.key, required this.data, required this.onItemClick});
@override
State<LocationListExpandedBody> createState() =>
_LocationListExpandedBodyState();
}
class _LocationListExpandedBodyState extends State<LocationListExpandedBody> {
List<HospitalsModel> tempListData = [];
TextEditingController controller = new TextEditingController();
@override
void initState() {
super.initState();
setState(() {
tempListData.addAll(widget.data);
});
}
@override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SelectBranchHeader(),
SizedBox(height: 8,),
TextField(
controller: controller,
onChanged: (v) {
tempListData.clear();
if (v.length > 0) {
for (int i = 0; i < widget.data.length; i++) {
if (widget.data[i].name
?.toLowerCase()
.contains(v.toLowerCase()) ==
true) {
tempListData.add(widget.data[i]);
}
}
} else {
tempListData.addAll(widget.data);
}
setState(() {});
},
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 12),
hintText: TranslationBase.of(context).searchByBranch,
suffixIcon: Icon(Icons.search),
contentPadding: EdgeInsets.symmetric(vertical: 9,horizontal: 14),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: Colors.grey, // Normal border color
width: 1.0,
),
),
),
),
SizedBox(
height: 16,
),
ListView.builder(
itemCount: tempListData.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(bottom: 8),
child: SizedBox(
height: 24,
child: InkWell(
onTap: () {
widget
.onItemClick(tempListData[index].name ?? "");
},
child: Text(
"${tempListData[index].name ?? ""} ( ${tempListData[index].distanceInKilometers} km )",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.black,
letterSpacing: -0.96),
),
),
),
);
})
],
),
),
);
}
}
class LocationListWrapBody extends StatelessWidget {
final VoidCallback? onConfirmClicked;
final VoidCallback? onTextBoxClicked;
final String selectedText;
const LocationListWrapBody(
{super.key,
this.onConfirmClicked,
this.onTextBoxClicked,
required this.selectedText});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SelectBranchHeader(),
SizedBox(
height: 24,
),
ListTile(
onTap: () {
onTextBoxClicked?.call();
},
title: Text(
TranslationBase.of(context).selectBranch,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.black,
letterSpacing: -0.96),
),
subtitle: selectedText.isEmpty
? null
: Text(
selectedText,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.black,
letterSpacing: -0.96),
),
trailing: Icon(
Icons.arrow_drop_down_outlined,
color: Colors.black,
),
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.grey, width: 1),
borderRadius: BorderRadius.circular(8),
),
),
SizedBox(
height: 24,
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: DefaultButton(
TranslationBase.of(context).confirm,
() {
Navigator.pop(context);
onConfirmClicked?.call();
},
color: CustomColors.accentColor,
),
),
],
),
],
),
);
}
}
class SelectBranchHeader extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
TranslationBase.of(context).selectBranch,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w600,
color: Colors.black,
letterSpacing: -0.96),
),
InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(Icons.close),
))
],
);
}
}

@ -38,9 +38,9 @@ class MyInAppBrowser extends InAppBrowser {
static String APPLE_PAY_PAYFORT_URL = 'https://hmgwebservices.com/PayFortWebLive/PayFortApi/MakeApplePayRequest'; // Payfort Payment Gateway URL LIVE
// static String APPLE_PAY_PAYFORT_URL = 'https://hmgwebservices.com/PayFortWebLive/PayFortApi/MakeApplePayRequest'; // Payfort Payment Gateway URL UAT
// static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort Payment Gateway URL UAT
static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort Payment Gateway URL UAT
static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort Payment Gateway URL LIVE
// static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort Payment Gateway URL LIVE
// static String SERVICE_URL = 'https://uat.hmgwebservices.com/payfortforvidaplus/pages/SendPayFortRequest.aspx'; //Payfort Payment Gateway URL UAT VIDA PLUS
@ -138,7 +138,7 @@ class MyInAppBrowser extends InAppBrowser {
openPackagesPaymentBrowser({required int customer_id, required int order_id}) {
paymentType = _PAYMENT_TYPE.PACKAGES;
var full_url = '$PACKAGES_REQUEST_PAYMENT_URL?customer_id=$customer_id&order_id=$order_id';
this.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(full_url)), options: _InAppBrowserOptions);
this.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(full_url))), options: _InAppBrowserOptions);
}
openPaymentBrowser(num amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID,
@ -190,7 +190,7 @@ class MyInAppBrowser extends InAppBrowser {
String url = "https://hmgwebservices.com/HMGApplePayLive/applepay/pay?apq=" + res['result']; // Prod
// String url = "https://uat.hmgwebservices.com/HMGApplePayLive/applepay/pay?apq=" + res['result']; // UAT
// safariBrowser.open(url: Uri.parse(url));
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(url)), options: _InAppBrowserOptions);
this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(url))), options: _InAppBrowserOptions);
}).catchError((err) {
print(err);
if (context != null) GifLoaderDialogUtils.hideDialog(context);
@ -233,7 +233,7 @@ class MyInAppBrowser extends InAppBrowser {
appoNo, clinicID, doctorID, "", installments)
.then((value) {
paymentType = _PAYMENT_TYPE.PATIENT;
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions);
this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions);
});
}).catchError((err) {
print(err);
@ -245,7 +245,7 @@ class MyInAppBrowser extends InAppBrowser {
clinicID, doctorID)
.then((value) {
paymentType = _PAYMENT_TYPE.PATIENT;
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions);
this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions);
});
}
}
@ -258,16 +258,16 @@ class MyInAppBrowser extends InAppBrowser {
// getPatientData();
generatePharmacyURL(order, amount, orderDesc, transactionID, emailId, paymentMethod, patientName, patientID, authenticatedUser).then((value) {
if (order.customValuesXml!.contains("ApplePay")) {
safariBrowser.open(url: Uri.parse(value));
safariBrowser.open(url: WebUri.uri(Uri.parse(value)));
} else {
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions);
this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions);
}
});
}
openBrowser(String url) {
this.browser = browser;
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(url)), options: _InAppBrowserOptions);
this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(url))), options: _InAppBrowserOptions);
}
Future<String> generateURL(num amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID,
@ -489,7 +489,7 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser {
}
@override
void onCompletedInitialLoad() {
void onCompletedInitialLoad(bool? didLoadSuccessfully) {
print("ChromeSafari browser initial load completed");
onLoadStartCallback!("ApplePay");
}

@ -1,7 +1,7 @@
name: diplomaticquarterapp
description: A new Flutter application.
version: 4.5.063+4050063
version: 4.5.065+4050065
environment:
sdk: ">=3.0.0 <3.13.0"
@ -34,7 +34,8 @@ dependencies:
get_it: ^7.2.0
#Google Fit & Apple HealthKit
health: ^3.0.3
# health: ^3.0.3
health: ^11.1.0
#chart
fl_chart: ^0.64.0
@ -99,7 +100,7 @@ dependencies:
flutter_rating_bar: ^4.0.1
# Calendar
# syncfusion_flutter_calendar: ^23.1.42
# syncfusion_flutter_calendar: ^23.1.42
syncfusion_flutter_calendar: ^24.1.47
# SVG Images
@ -109,7 +110,7 @@ dependencies:
manage_calendar_events: ^2.0.3
#InAppBrowser
flutter_inappwebview: ^5.8.0
flutter_inappwebview: ^6.1.5
#Circular progress bar for reverse timer
circular_countdown_timer: ^0.2.0
@ -124,7 +125,7 @@ dependencies:
flutter_datetime_picker_plus: ^2.1.0
carousel_pro_nullsafety: ^2.0.0
flutter_local_notifications: any
device_calendar: ^4.3.2
device_calendar: ^4.3.3
geolocator: ^9.0.2
geocoding: ^2.0.1
jiffy: ^6.2.1
@ -135,13 +136,15 @@ dependencies:
google_maps_place_picker_mb: ^3.0.0
map_launcher: ^3.0.1
flutter_countdown_timer: ^4.1.0
carousel_slider: ^5.0.0
#Dependencies for video call implementation
native_device_orientation: ^1.0.0
wakelock: ^0.6.2
# wakelock: ^0.6.2
wakelock_plus: ^1.1.4
after_layout: ^1.1.0
cached_network_image: ^3.3.0
flutter_tts: ^3.6.1
vibration: ^1.7.3
# vibration: ^1.7.3
flutter_nfc_kit: ^3.3.1
#geofencing: any
speech_to_text: ^6.1.1
@ -151,16 +154,16 @@ dependencies:
in_app_review: ^2.0.3
badges: ^3.1.2
flutter_app_icon_badge: ^2.0.0
# flutter_app_icon_badge: ^2.0.0
# dropdown_search: 5.0.6
youtube_player_flutter: ^8.1.2
youtube_player_flutter: ^9.1.0
# shimmer: ^3.0.0
carousel_slider: ^5.0.0
# carousel_slider: ^4.0.0
# flutter_staggered_grid_view: ^0.7.0
huawei_hmsavailability: ^6.11.0+301
huawei_location: ^6.11.0+301
share_plus: ^6.3.4
share_plus: ^10.0.2
# Marker Animation
auto_size_text: ^3.0.0
equatable: ^2.0.3
@ -170,17 +173,17 @@ dependencies:
google_api_availability: ^5.0.0
open_filex: ^4.3.2
path_provider: ^2.0.8
amazon_payfort: ^1.1.0
amazon_payfort: ^1.1.3
logger: ^2.0.2+1
network_info_plus: any
flutter_zoom_videosdk: ^1.10.11
flutter_zoom_videosdk: ^1.11.2
dart_jsonwebtoken: ^2.14.0
win32: ^5.5.4
cloudflare_turnstile: ^2.0.1
dependency_overrides:
win32: ^5.5.4
dev_dependencies:
flutter_test:

Loading…
Cancel
Save