diff --git a/.gitignore b/.gitignore
index cff0e374..55ad4693 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ pubspec.lock
.pub-cache/
.pub/
/build/
+/ios/Frameworks/
# Web related
lib/generated_plugin_registrant.dart
diff --git a/android/app/build.gradle b/android/app/build.gradle
index f1799225..b5f2d00f 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -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"
}
diff --git a/android/app/libs/PenNavUI.aar b/android/app/libs/PenNavUI.aar
new file mode 100644
index 00000000..6291c4ec
Binary files /dev/null and b/android/app/libs/PenNavUI.aar differ
diff --git a/android/app/libs/Penguin.aar b/android/app/libs/Penguin.aar
new file mode 100644
index 00000000..7cdc0b71
Binary files /dev/null and b/android/app/libs/Penguin.aar differ
diff --git a/android/app/libs/PenguinRenderer.aar b/android/app/libs/PenguinRenderer.aar
new file mode 100644
index 00000000..c60248c9
Binary files /dev/null and b/android/app/libs/PenguinRenderer.aar differ
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
index 69cd8026..ab7b2ca4 100644
--- a/android/app/proguard-rules.pro
+++ b/android/app/proguard-rules.pro
@@ -53,4 +53,20 @@
}
-dontwarn com.opentok.android.**
--dontwarn com.opentok.otc.**
\ No newline at end of file
+-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.** { *; }
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index b1540644..58ac88b7 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -8,21 +8,36 @@
FlutterApplication and put your custom class here. -->
-
-
-
-
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -42,6 +57,7 @@
+
@@ -59,13 +75,13 @@
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt
index 8aa1ef85..df41e342 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt
@@ -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,
+ 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() {
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt
new file mode 100644
index 00000000..93affaef
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt
@@ -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?
+ Log.d("TAG", "configureFlutterEngine: $args")
+ println("args")
+ args?.let {
+ PenguinView(
+ mainActivity,
+ 100,
+ args,
+ flutterEngine.dartExecutor.binaryMessenger,
+ activity = mainActivity,
+ channel
+ )
+ }
+ }
+
+ else -> {
+ result.notImplemented()
+ }
+ }
+ }
+ }
+
+}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt
new file mode 100644
index 00000000..b308af05
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt
@@ -0,0 +1,28 @@
+package com.cloud.diplomaticquarterapp.PermissionManager
+
+import android.Manifest
+import android.os.Build
+
+object PermissionHelper {
+
+ fun getRequiredPermissions(): Array {
+ 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()
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt
new file mode 100644
index 00000000..81f2a6f0
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt
@@ -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, grantResults: IntArray) {
+ if (this.requestCode == requestCode) {
+ val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
+ if (allGranted) {
+ listener.onPermissionGranted()
+ } else {
+ listener.onPermissionDenied()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt
new file mode 100644
index 00000000..33765192
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt
@@ -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)
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt
new file mode 100644
index 00000000..c76f9784
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt
@@ -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");
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt
new file mode 100644
index 00000000..98245cc9
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt
@@ -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 = ApiController.getInstance(mContext)
+ .apiMethods
+ .getToken(postToken)
+
+ // Enqueue the call for asynchronous execution
+ purposesCall.enqueue(object : Callback {
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ 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, t: Throwable) {
+ apiTokenCallBack.onGetByRefIDError(t.message)
+ }
+ })
+ } catch (error: Exception) {
+ apiTokenCallBack.onGetByRefIDError("Exception during API call: $error")
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt
new file mode 100644
index 00000000..743ce93b
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt
@@ -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,
+ 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 = 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")
+ }
+ }
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt
index 7fbf859a..57da2eb8 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt
@@ -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 httpPost(url: String, body: Map, 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)) {
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png
similarity index 100%
rename from android/app/src/main/res/mipmap-hdpi/ic_launcher.png
rename to android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png
similarity index 100%
rename from android/app/src/main/res/mipmap-mdpi/ic_launcher.png
rename to android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
rename to android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
rename to android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
rename to android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index 4e107030..1093435a 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -19,4 +19,5 @@
Geofence requests happened too frequently.
+ sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg
diff --git a/android/build.gradle b/android/build.gradle
index b5185cca..c5f1baa2 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -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)
+ }
+ }
}
}
diff --git a/android/gradle.properties b/android/gradle.properties
index 06a44c05..cf554544 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -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"
\ No newline at end of file
diff --git a/assets/images/new/NFCCheckIn_QR_gps_HMG.png b/assets/images/new/NFCCheckIn_QR_gps_HMG.png
new file mode 100644
index 00000000..20fc0ef6
Binary files /dev/null and b/assets/images/new/NFCCheckIn_QR_gps_HMG.png differ
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
index cb6be309..c5ff5d37 100644
--- a/ios/Flutter/AppFrameworkInfo.plist
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 11.0
+ 13.0
diff --git a/ios/Podfile b/ios/Podfile
index 5495f0ca..5564c00b 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -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
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index e7357518..5dad833f 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -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 = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = ""; };
301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = ""; };
301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = ""; };
306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = ""; };
306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = ""; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
- 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 = ""; };
+ 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = ""; };
+ 47C934FC2C91766400981BA7 /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = ""; };
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 = ""; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
@@ -74,6 +93,11 @@
7643E4062BE0D0B400BD2F25 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = ""; };
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 = ""; };
+ 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = ""; };
+ 76D71B692C6B819000DAFB84 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = ""; };
+ 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinView.swift; sourceTree = ""; };
+ 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinPlugin.swift; sourceTree = ""; };
+ 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinViewFactory.swift; sourceTree = ""; };
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 = ""; };
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 = ""; };
@@ -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 = "";
@@ -151,6 +181,18 @@
path = Pods;
sourceTree = "";
};
+ 76D71B682C6B817500DAFB84 /* Penguin */ = {
+ isa = PBXGroup;
+ children = (
+ 76D71B692C6B819000DAFB84 /* PenguinModel.swift */,
+ 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */,
+ 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */,
+ 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */,
+ 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */,
+ );
+ path = Penguin;
+ sourceTree = "";
+ };
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 = "";
@@ -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;
diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index fab8f735..b2d2f7e5 100644
--- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
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
+ }
+
+}
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 43474d39..13782c80 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -39,7 +39,7 @@
LSRequiresIPhoneOS
MinimumOSVersion
- 11.0
+ 13.0
NFCReaderUsageDescription
This app requires NFC Usage access to allow for Online CheckIn for appointments.
NSAppTransportSecurity
@@ -60,7 +60,7 @@
NSCalendarsUsageDescription
This app requires calendar access to set reminders for Virtual & Normal Appointments.
NSCalendarsWriteOnlyAccessUsageDescription
- This app requires calendar access to set reminders for Virtual & Normal Appointments.
+ This app requires calendar access to set reminders for Virtual & Normal Appointments.
NSCalendarsFullAccessUsageDescription
This app requires calendar access to set reminders for Virtual & Normal Appointments.
NSCameraUsageDescription
diff --git a/ios/Runner/Penguin/PenguinModel.swift b/ios/Runner/Penguin/PenguinModel.swift
new file mode 100644
index 00000000..e41979d6
--- /dev/null
+++ b/ios/Runner/Penguin/PenguinModel.swift
@@ -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
+ }
+}
diff --git a/ios/Runner/Penguin/PenguinNavigator.swift b/ios/Runner/Penguin/PenguinNavigator.swift
new file mode 100644
index 00000000..e7ce55b4
--- /dev/null
+++ b/ios/Runner/Penguin/PenguinNavigator.swift
@@ -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)
+ }
+ }
+ }
+}
diff --git a/ios/Runner/Penguin/PenguinPlugin.swift b/ios/Runner/Penguin/PenguinPlugin.swift
new file mode 100644
index 00000000..029bec35
--- /dev/null
+++ b/ios/Runner/Penguin/PenguinPlugin.swift
@@ -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")
+// }
+//}
diff --git a/ios/Runner/Penguin/PenguinView.swift b/ios/Runner/Penguin/PenguinView.swift
new file mode 100644
index 00000000..81377f7b
--- /dev/null
+++ b/ios/Runner/Penguin/PenguinView.swift
@@ -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)")
+
+ }
+
+
+
+
+}
diff --git a/ios/Runner/Penguin/PenguinViewFactory.swift b/ios/Runner/Penguin/PenguinViewFactory.swift
new file mode 100644
index 00000000..a88bb5d0
--- /dev/null
+++ b/ios/Runner/Penguin/PenguinViewFactory.swift
@@ -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()
+ }
+}
diff --git a/lib/config/config.dart b/lib/config/config.dart
index 7ceb29c6..605e449d 100644
--- a/lib/config/config.dart
+++ b/lib/config/config.dart
@@ -335,18 +335,25 @@ var GET_PATIENT_HEALTH_STATS = 'Services/Patients.svc/REST/Med_GetTransactionsSt
var SEND_CHECK_IN_NFC_REQUEST = 'Services/Patients.svc/REST/Patient_CheckAppointmentValidation_ForNFC';
+var CHECK_SCANNED_NFC_QR_CODE = 'Services/Patients.svc/REST/Patient_ValidationMachine_ForNFC';
+
var HAS_DENTAL_PLAN = 'Services/Doctors.svc/REST/Dental_IsPatientHasOnGoingEstimation';
var LASER_BODY_PARTS = 'Services/Patients.svc/REST/Laser_GetBodyPartsByCategory';
var INSERT_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Insert';
+
var UPDATE_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Update';
+var GET_PATIENT_SHARE_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForWalkIn';
+
+var CAN_PAY_FOR_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/CanPayForWalkinAppointment';
+
//URL to get medicine and pharmacies list
var CHANNEL = 3;
var GENERAL_ID = 'Cs2020@2016\$2958';
var IP_ADDRESS = '10.20.10.20';
-var VERSION_ID = 16.3;
+var VERSION_ID = 16.4;
var SETUP_ID = '91877';
var LANGUAGE = 2;
// var PATIENT_OUT_SA = 0;
@@ -603,9 +610,9 @@ var GET_DENTAL_APPOINTMENT_INVOICE = "Services/Patients.svc/REST/HIS_eInvoiceFor
var SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL = "Services/Notifications.svc/REST/SendInvoiceForDental";
-var GET_TAMARA_PLAN = 'https://mdlaboratories.com/tamaralive/Home/GetInstallments';
+var GET_TAMARA_PLAN = 'https://mdlaboratories.com/tamara/Home/GetInstallments';
-var GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
+var GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamara/api/OnlineTamara/order_status?orderid=';
var UPDATE_TAMARA_STATUS = 'Services/PayFort_Serv.svc/REST/Tamara_UpdateRequestStatus';
@@ -667,6 +674,8 @@ var GET_WE_CARE_TOUR_URL = 'Services/Consent.svc/Rest/Consent_VirtualJurny_Url_G
var GET_DENTAL_INSTRUCTIONS = 'Services/OUTPs.svc/Rest/getProcedureNotification';
+var INSERT_WALKIN_APPOINTMENT = "Services/Doctors.svc/REST/InsertWalkinAppointment";
+
//PAYFORT
var getPayFortProjectDetails = "Services/PayFort_Serv.svc/REST/GetPayFortProjectDetails";
var addPayFortApplePayResponse = "Services/PayFort_Serv.svc/REST/AddResponse";
diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart
index 31dee7cb..2765fd51 100644
--- a/lib/config/localized_values.dart
+++ b/lib/config/localized_values.dart
@@ -1981,5 +1981,16 @@ const Map localizedValues = {
"newAppointment":{"en":"New Appointment","ar":"موعد جديد"},
"proceedPackage":{"en":"Proceed with package","ar":"المضي قدما في الحزمة"},
+ "clinicLocation": {"en": "Clinic Location", "ar": "موقع العيادة"},
+ "waitingAppointment": {"en": "Waiting appointment", "ar": "انتظار الموعد"},
+ "whatWaitingAppointment": {"en": "What is Waiting appointment?", "ar": "ما هو انتظار الموعد؟"},
+ "waitingAppointmentText1": {"en": "The waiting appointments feature allows you to book an appointment while you are inside the hospital building, and in case there is no available slot in the doctor’s schedule.", "ar": "تتيح لك خاصية انتظار المواعيد حجز موعد أثناء تواجدك داخل مبنى المستشفى، وفي حالة عدم وجود وقت متاح في جدول الطبيب."},
+ "waitingAppointmentText2": {"en": "The appointment with the doctor is confirmed, but the time of entry is uncertain", "ar": "دخول الموعد مؤكد, التوقيت غير محدد."},
+ "waitingAppointmentText3": {"en": "Note: You must have to pay within 10 minutes of booking, otherwise your appointment will be cancelled automatically", "ar": "ملحوظة: يجب عليك الدفع خلال 10 دقائق من الحجز، وإلا سيتم إلغاء موعدك تلقائيًا"},
+ "waitingAppointmentVerificationMethod": {"en": "Please select verification method", "ar": "الرجاء تحديد طريقة التحقق"},
+ "howToUseVerificationMethod": {"en": "How to use verification methods?", "ar": "كيفية استخدام طرق التحقق؟"},
+ "addToWaitingList": {"en": "Add to waiting list", "ar": "اضافه الى قائمة الانتظار"},
"searchClinic": {"en": "Search Clinic", "ar": "بحث العيادة"},
+ "selectBranch":{"en":"Select Branch", "ar":"اختر الفرع"},
+ "searchByBranch":{"en":"Search By Branch Name", "ar":"البحث عن طريق اسم الفرع"}
};
diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart
index d8f30f0c..37a3a722 100644
--- a/lib/core/service/client/base_app_client.dart
+++ b/lib/core/service/client/base_app_client.dart
@@ -31,8 +31,7 @@ AppSharedPreferences sharedPref = new AppSharedPreferences();
/// onFailure: (String error, int statusCode) {},
/// body: Map();
///
-AuthenticatedUserObject authenticatedUserObject =
- locator();
+AuthenticatedUserObject authenticatedUserObject = locator();
VitalSignService _vitalSignService = locator();
class BaseAppClient {
@@ -40,12 +39,12 @@ class BaseAppClient {
post(String endPoint,
{required Map body,
- required Function(dynamic response, int statusCode) onSuccess,
- required Function(String error, int statusCode) onFailure,
- bool isAllowAny = false,
- bool isExternal = false,
- bool isRCService = false,
- bool bypassConnectionCheck = false}) async {
+ required Function(dynamic response, int statusCode) onSuccess,
+ required Function(String error, int statusCode) onFailure,
+ bool isAllowAny = false,
+ bool isExternal = false,
+ bool isRCService = false,
+ bool bypassConnectionCheck = false}) async {
String url;
if (isExternal) {
url = endPoint;
@@ -56,25 +55,20 @@ class BaseAppClient {
url = BASE_URL + endPoint;
}
try {
- String? pharmacyToken =
- await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
+ String? pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE);
- Map headers = {
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'
- };
+ Map headers = {'Content-Type': 'application/json', 'Accept': 'application/json'};
if (!isExternal) {
String? token = await sharedPref.getString(TOKEN);
- String? languageID =
- await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
+ String? languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
if (endPoint == SEND_ACTIVATION_CODE) {
languageID = 'en';
}
if (body.containsKey('SetupID')) {
body['SetupID'] = body.containsKey('SetupID')
? body['SetupID'] != null
- ? body['SetupID']
- : SETUP_ID
+ ? body['SetupID']
+ : SETUP_ID
: SETUP_ID;
}
@@ -87,8 +81,8 @@ class BaseAppClient {
body['LanguageID'] = body['LanguageID'] == 'ar'
? 1
: body['LanguageID'] == 'en'
- ? 2
- : body['LanguageID'];
+ ? 2
+ : body['LanguageID'];
} else {
body['LanguageID'] = Provider.of(AppGlobal.context, listen: false).isArabic ? 1 : 2;
}
@@ -120,16 +114,16 @@ class BaseAppClient {
if (body.containsKey('isDentalAllowedBackend')) {
body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend')
? body['isDentalAllowedBackend'] != null
- ? body['isDentalAllowedBackend']
- : IS_DENTAL_ALLOWED_BACKEND
+ ? body['isDentalAllowedBackend']
+ : IS_DENTAL_ALLOWED_BACKEND
: IS_DENTAL_ALLOWED_BACKEND;
}
body['DeviceTypeID'] = Platform.isIOS
? 1
: await Utils.isGoogleServicesAvailable()
- ? 2
- : 3;
+ ? 2
+ : 3;
if (!body.containsKey('IsPublicRequest')) {
// if (!body.containsKey('PatientType')) {
@@ -166,17 +160,14 @@ class BaseAppClient {
if (user != null) {
body['TokenID'] = body['TokenID'] != null ? body['TokenID'] : token;
- body['PatientID'] = body['PatientID'] != null
- ? body['PatientID']
- : user['PatientID'];
+ body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID'];
body['PatientOutSA'] = body.containsKey('PatientOutSA')
? body['PatientOutSA'] != null
- ? body['PatientOutSA']
- : user['OutSA']
+ ? body['PatientOutSA']
+ : user['OutSA']
: user['OutSA'];
- body['SessionID'] = getSessionId(
- body['TokenID'] != null ? body['TokenID'] : ""); //getSe
+ body['SessionID'] = getSessionId(body['TokenID'] != null ? body['TokenID'] : ""); //getSe
// body['SessionID'] = body['TokenID']; //getSe
// headers = {
@@ -193,7 +184,7 @@ class BaseAppClient {
// body['IdentificationNo'] = 1023854217;
// body['MobileNo'] = "531940021"; //0560717232
- // body['PatientID'] = 283093; //4609100
+ // body['PatientID'] = 4768303; //4609100
// body['TokenID'] = "@dm!n";
// Patient ID: 3027574
@@ -202,21 +193,23 @@ class BaseAppClient {
body.removeWhere((key, value) => key == null || value == null);
+ // if (url == 'https://uat.hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo') {
+ // url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo";
+ // body['TokenID'] = "@dm!n";
+ // }
+
// 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)) {
- final response = await http.post(Uri.parse(url.trim()),
- body: json.encode(body), headers: headers);
+ if (await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck)) {
+ final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers);
final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
- logApiEndpointError(
- endPoint, 'Error While Fetching data', statusCode);
+ logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
} else {
// var decoded = utf8.decode(response.bodyBytes);
var parsed = json.decode(utf8.decode(response.bodyBytes));
@@ -230,12 +223,8 @@ class BaseAppClient {
onSuccess(parsed, statusCode);
} else {
if (parsed['ErrorType'] == 4) {
- navigateToAppUpdate(
- AppGlobal.context, parsed['ErrorEndUserMessage']);
- logApiEndpointError(
- endPoint,
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
+ navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
+ logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
if (parsed['ErrorType'] == 2) {
await logout();
@@ -254,46 +243,28 @@ class BaseAppClient {
// if (parsed != null) {
// onSuccess(parsed, statusCode);
// } else {
- onFailure(
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
+ onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
// logout();
// }
}
- } else if (parsed['MessageStatus'] == 1 ||
- parsed['SMSLoginRequired'] == true) {
+ } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
onSuccess(parsed, statusCode);
- } else if (parsed['MessageStatus'] == 2 &&
- parsed['IsAuthenticated']) {
+ } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
if (parsed['SameClinicApptList'] != null) {
onSuccess(parsed, statusCode);
} else {
- if (parsed['message'] == null &&
- parsed['ErrorEndUserMessage'] == null) {
+ if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) {
- onFailure("Server Error found with no available message",
- statusCode);
- logApiEndpointError(
- endPoint,
- "Server Error found with no available message",
- statusCode);
+ onFailure("Server Error found with no available message", statusCode);
+ logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
} else {
onFailure(parsed['ErrorSearchMsg'], statusCode);
- logApiEndpointError(
- endPoint, parsed['ErrorSearchMsg'], statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
}
} else {
- onFailure(
- parsed['message'] ??
- parsed['ErrorEndUserMessage'] ??
- parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(endPoint,
- parsed['message'] ?? parsed['message'], statusCode);
+ onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
}
}
}
@@ -305,18 +276,11 @@ class BaseAppClient {
onSuccess(parsed, statusCode);
} else {
if (parsed['message'] != null) {
- onFailure(
- parsed['message'] ?? parsed['message'], statusCode);
- logApiEndpointError(endPoint,
- parsed['message'] ?? parsed['message'], statusCode);
+ onFailure(parsed['message'] ?? parsed['message'], statusCode);
+ logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
} else {
- onFailure(
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
+ onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
}
@@ -325,23 +289,17 @@ class BaseAppClient {
}
} else {
onFailure('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
} catch (e) {
print(e);
onFailure(e.toString(), -1);
- _analytics.errorTracking
- .log(endPoint, error: "api exception: $e - API Path: $url");
+ _analytics.errorTracking.log(endPoint, error: "api exception: $e - API Path: $url");
}
}
postPharmacy(String endPoint,
- {Map? body,
- Function(dynamic response, int statusCode)? onSuccess,
- Function(String error, int statusCode)? onFailure,
- bool isAllowAny = false,
- bool isExternal = false}) async {
+ {Map? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async {
var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE);
String url;
@@ -358,16 +316,13 @@ class BaseAppClient {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': pharmacyToken ?? '',
- 'Mobilenumber': user != null
- ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
- : "",
+ 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "",
};
if (!isExternal) {
String token = await sharedPref.getString(TOKEN);
- var languageID =
- await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
+ var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
// if (body.containsKey('SetupID')) {
// body['SetupID'] = body.containsKey('SetupID')
@@ -429,14 +384,12 @@ class BaseAppClient {
print("Headers : ${json.encode(headers)}");
if (await Utils.checkConnection()) {
- final response = await http.post(Uri.parse(url.trim()),
- body: json.encode(body), headers: headers);
+ final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode);
- logApiEndpointError(
- endPoint, 'Error While Fetching data', statusCode);
+ logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
} else {
// var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes));
@@ -444,12 +397,8 @@ class BaseAppClient {
onSuccess!(parsed, statusCode);
} else {
if (parsed['ErrorType'] == 4) {
- navigateToAppUpdate(
- AppGlobal.context, parsed['ErrorEndUserMessage']);
- logApiEndpointError(
- endPoint,
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
+ navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
+ logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
if (isAllowAny) {
onSuccess!(parsed, statusCode);
@@ -464,56 +413,29 @@ class BaseAppClient {
if (parsed != null) {
onSuccess!(parsed, statusCode);
} else {
- onFailure!(
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint, 'session logged out', statusCode);
+ onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, 'session logged out', statusCode);
logout();
}
}
- } else if (parsed['MessageStatus'] == 1 ||
- parsed['SMSLoginRequired'] == true) {
+ } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
onSuccess!(parsed, statusCode);
- } else if (parsed['MessageStatus'] == 2 &&
- parsed['IsAuthenticated']) {
+ } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
if (parsed['SameClinicApptList'] != null) {
onSuccess!(parsed, statusCode);
} else {
- if (parsed['message'] == null &&
- parsed['ErrorEndUserMessage'] == null) {
+ if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) {
- onFailure!("Server Error found with no available message",
- statusCode);
- logApiEndpointError(
- endPoint,
- "Server Error found with no available message",
- statusCode);
+ onFailure!("Server Error found with no available message", statusCode);
+ logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
} else {
onFailure!(parsed['ErrorSearchMsg'], statusCode);
- logApiEndpointError(
- endPoint,
- parsed['ErrorSearchMsg'] ??
- parsed['ErrorEndUserMessage'] ??
- parsed['ErrorMessage'],
- statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorSearchMsg'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
} else {
- onFailure!(
- parsed['message'] ??
- parsed['ErrorEndUserMessage'] ??
- parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['message'] ??
- parsed['ErrorEndUserMessage'] ??
- parsed['ErrorMessage'],
- statusCode);
+ onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
} else if (!parsed['IsAuthenticated']) {
@@ -525,22 +447,11 @@ class BaseAppClient {
onSuccess!(parsed, statusCode);
} else {
if (parsed['message'] != null) {
- onFailure!(
- parsed['message'] ?? parsed['message'], statusCode);
- logApiEndpointError(
- endPoint,
- parsed['message'] ??
- parsed['ErrorEndUserMessage'] ??
- parsed['ErrorMessage'],
- statusCode);
+ onFailure!(parsed['message'] ?? parsed['message'], statusCode);
+ logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
} else {
- onFailure!(
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
+ onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
}
@@ -548,8 +459,7 @@ class BaseAppClient {
}
} else {
onFailure!('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
} catch (e) {
print(e);
@@ -560,18 +470,18 @@ class BaseAppClient {
Future navigateToAppUpdate(context, String text) async {
Navigator.pushAndRemoveUntil(
- locator().navigatorKey.currentContext!,
+ locator().navigatorKey.currentContext!,
MaterialPageRoute(builder: (context) => AppUpdatePage(appUpdateText: text)),
- (Route route) => false,
+ (Route route) => false,
);
}
get(String endPoint,
{required Function(dynamic response, int statusCode) onSuccess,
- required Function(String error, int statusCode) onFailure,
- Map? queryParams,
- bool isExternal = false,
- bool isRCService = false}) async {
+ required Function(String error, int statusCode) onFailure,
+ Map? queryParams,
+ bool isExternal = false,
+ bool isRCService = false}) async {
String url;
if (isExternal) {
url = endPoint;
@@ -592,10 +502,7 @@ class BaseAppClient {
if (await Utils.checkConnection()) {
final response = await http.get(
Uri.parse(url.trim()),
- headers: {
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'
- },
+ headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
@@ -609,17 +516,16 @@ class BaseAppClient {
}
} else {
onFailure!('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
getPharmacy(String endPoint,
{required Function(dynamic response, int statusCode) onSuccess,
- required Function(String error, int statusCode) onFailure,
- bool isAllowAny = false,
- bool isExternal = false,
- Map? queryParams}) async {
+ required Function(String error, int statusCode) onFailure,
+ bool isAllowAny = false,
+ bool isExternal = false,
+ Map? queryParams}) async {
var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE);
@@ -642,9 +548,7 @@ class BaseAppClient {
'Content-Type': 'text/html; charset=utf-8',
'Accept': 'application/json',
'Authorization': token ?? '',
- 'Mobilenumber': user != null
- ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
- : "",
+ 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "",
// 'Host': "mdlaboratories.com",
@@ -654,19 +558,14 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) {
if (statusCode == 401) {
- onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin,
- statusCode);
- logApiEndpointError(
- endPoint,
- TranslationBase.of(AppGlobal.context).pharmacyRelogin,
- statusCode);
+ onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode);
+ logApiEndpointError(endPoint, TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode);
Navigator.of(AppGlobal.context).pushNamed(HOME);
} else {
var bodyUtf = json.decode(utf8.decode(response.bodyBytes));
// print(bodyUtf);
onFailure!(bodyUtf['error']['ErrorEndUserMsg'], statusCode);
- logApiEndpointError(
- endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode);
+ logApiEndpointError(endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode);
}
} else {
// var parsed = json.decode(response.body.toString());
@@ -675,25 +574,23 @@ class BaseAppClient {
}
} else {
onFailure!('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
simplePost(
- String fullUrl, {
- required Map body,
- required Map headers,
- required Function(dynamic response, int statusCode) onSuccess,
- required Function(String error, int statusCode) onFailure,
- }) async {
+ String fullUrl, {
+ required Map body,
+ required Map headers,
+ required Function(dynamic response, int statusCode) onSuccess,
+ required Function(String error, int statusCode) onFailure,
+ }) async {
String url = fullUrl;
// print("URL Query String: $url");
// print("body: $body");
if (await Utils.checkConnection()) {
- headers!.addAll(
- {'Content-Type': 'application/json', 'Accept': 'application/json'});
+ headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.post(
Uri.parse(url.trim()),
body: json.encode(body),
@@ -701,12 +598,7 @@ class BaseAppClient {
);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
- if (await handleUnauthorized(statusCode, forUrl: fullUrl))
- simplePost(fullUrl,
- onFailure: onFailure,
- onSuccess: onSuccess,
- body: body,
- headers: headers);
+ if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers);
// print(response.body.toString());
@@ -718,16 +610,12 @@ class BaseAppClient {
}
} else {
onFailure!('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
simpleGet(String fullUrl,
- {Function(dynamic response, int statusCode)? onSuccess,
- Function(String error, int statusCode)? onFailure,
- Map? queryParams,
- Map? headers}) async {
+ {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map? queryParams, Map? headers}) async {
headers = headers ?? {};
String url = fullUrl;
@@ -739,8 +627,7 @@ class BaseAppClient {
}
if (await Utils.checkConnection()) {
- headers.addAll(
- {'Content-Type': 'application/json', 'Accept': 'application/json'});
+ headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.get(
Uri.parse(url.trim()),
headers: headers,
@@ -748,12 +635,7 @@ class BaseAppClient {
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
- if (await handleUnauthorized(statusCode, forUrl: fullUrl))
- simpleGet(fullUrl,
- onFailure: onFailure,
- onSuccess: onSuccess,
- headers: headers,
- queryParams: queryParams);
+ if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams);
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode);
@@ -763,22 +645,17 @@ class BaseAppClient {
}
} else {
onFailure!('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
simplePut(String fullUrl,
- {Map? body,
- Map? headers,
- Function(dynamic response, int statusCode)? onSuccess,
- Function(String error, int statusCode)? onFailure}) async {
+ {Map? body, Map? headers, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure}) async {
String url = fullUrl;
// print("URL Query String: $url");
if (await Utils.checkConnection()) {
- headers!.addAll(
- {'Content-Type': 'application/json', 'Accept': 'application/json'});
+ headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.put(
Uri.parse(url.trim()),
body: json.encode(body),
@@ -787,12 +664,7 @@ class BaseAppClient {
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
- if (await handleUnauthorized(statusCode, forUrl: fullUrl))
- simplePut(fullUrl,
- onFailure: onFailure,
- onSuccess: onSuccess,
- headers: headers,
- body: body);
+ if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body);
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode);
@@ -802,16 +674,12 @@ class BaseAppClient {
}
} else {
onFailure!('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
simpleDelete(String fullUrl,
- {Function(dynamic response, int statusCode)? onSuccess,
- Function(String error, int statusCode)? onFailure,
- Map? queryParams,
- Map? headers}) async {
+ {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map? queryParams, Map? headers}) async {
String url = fullUrl;
// print("URL Query String: $url");
@@ -823,8 +691,7 @@ class BaseAppClient {
}
if (await Utils.checkConnection()) {
- headers!.addAll(
- {'Content-Type': 'application/json', 'Accept': 'application/json'});
+ headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.delete(
Uri.parse(url.trim()),
headers: headers,
@@ -832,12 +699,7 @@ class BaseAppClient {
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
- if (await handleUnauthorized(statusCode, forUrl: fullUrl))
- simpleDelete(fullUrl,
- onFailure: onFailure,
- onSuccess: onSuccess,
- queryParams: queryParams,
- headers: headers);
+ if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers);
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode);
@@ -847,13 +709,11 @@ class BaseAppClient {
}
} else {
onFailure!('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
- Future handleUnauthorized(int statusCode,
- {required String forUrl}) async {
+ Future handleUnauthorized(int statusCode, {required String forUrl}) async {
if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) {
final token = await generatePackagesToken();
packagesAuthHeader['Authorization'] = 'Bearer $token';
@@ -866,10 +726,8 @@ class BaseAppClient {
await sharedPref.remove(LOGIN_TOKEN_ID);
await sharedPref.remove(PHARMACY_CUSTOMER_ID);
await authenticatedUserObject.getUser();
- Provider.of(AppGlobal.context, listen: false).isLogin =
- false;
- var model =
- Provider.of(AppGlobal.context, listen: false);
+ Provider.of(AppGlobal.context, listen: false).isLogin = false;
+ var model = Provider.of(AppGlobal.context, listen: false);
_vitalSignService.weightKg = "";
_vitalSignService.heightCm = "";
model.setState(0, 0, false, null);
@@ -884,8 +742,7 @@ class BaseAppClient {
static defaultHttpParameters() async {
String token = await sharedPref.getString(TOKEN);
- var languageID =
- await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
+ var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
var user = await sharedPref.getObject(USER_PROFILE);
var params = {};
if (user != null) {
@@ -905,11 +762,7 @@ class BaseAppClient {
}
pharmacyPost(String endPoint,
- {Map? body,
- Function(dynamic response, int statusCode)? onSuccess,
- Function(String error, int statusCode)? onFailure,
- bool isAllowAny = false,
- bool isExternal = false}) async {
+ {Map? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async {
var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE);
String url;
@@ -921,14 +774,13 @@ class BaseAppClient {
try {
if (isExternal) {
String token = await sharedPref.getString(TOKEN);
- var languageID =
- await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
+ var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
var user = await sharedPref.getObject(USER_PROFILE);
if (body!.containsKey('SetupID')) {
body['SetupID'] = body.containsKey('SetupID')
? body['SetupID'] != null
- ? body['SetupID']
- : SETUP_ID
+ ? body['SetupID']
+ : SETUP_ID
: SETUP_ID;
}
@@ -940,15 +792,15 @@ class BaseAppClient {
body['generalid'] = GENERAL_ID;
body['PatientOutSA'] = body.containsKey('PatientOutSA')
? body['PatientOutSA'] != null
- ? body['PatientOutSA']
- : user['OutSA']
+ ? body['PatientOutSA']
+ : user['OutSA']
: user['OutSA'];
if (body.containsKey('isDentalAllowedBackend')) {
body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend')
? body['isDentalAllowedBackend'] != null
- ? body['isDentalAllowedBackend']
- : IS_DENTAL_ALLOWED_BACKEND
+ ? body['isDentalAllowedBackend']
+ : IS_DENTAL_ALLOWED_BACKEND
: IS_DENTAL_ALLOWED_BACKEND;
}
@@ -957,24 +809,22 @@ class BaseAppClient {
if (!body.containsKey('IsPublicRequest')) {
body['PatientType'] = body.containsKey('PatientType')
? body['PatientType'] != null
- ? body['PatientType']
- : user['PatientType'] != null
- ? user['PatientType']
- : user['PatientType']
+ ? body['PatientType']
+ : user['PatientType'] != null
+ ? user['PatientType']
+ : user['PatientType']
: user['PatientType'];
body['PatientTypeID'] = body.containsKey('PatientTypeID')
? body['PatientTypeID'] != null
- ? body['PatientTypeID']
- : user['PatientType'] != null
- ? user['PatientType']
- : user['PatientType']
+ ? body['PatientTypeID']
+ : user['PatientType'] != null
+ ? user['PatientType']
+ : user['PatientType']
: user['PatientType'];
if (user != null) {
body['TokenID'] = token;
- body['PatientID'] = body['PatientID'] != null
- ? body['PatientID']
- : user['PatientID'];
+ body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID'];
body['PatientOutSA'] = user['OutSA'];
// body['SessionID'] = SESSION_ID; //getSessionId(token);
}
@@ -986,14 +836,11 @@ class BaseAppClient {
var ss = json.encode(body);
if (await Utils.checkConnection()) {
- final response = await http
- .post(Uri.parse(url.trim()), body: json.encode(body), headers: {
+ final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': token ?? '',
- 'Mobilenumber': user != null
- ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
- : "",
+ 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "",
});
@@ -1001,15 +848,8 @@ class BaseAppClient {
// print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) {
var parsed = json.decode(utf8.decode(response.bodyBytes));
- onFailure!(
- parsed['error']['ErrorEndUserMsgN'] ??
- 'Error While Fetching data',
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['error']['ErrorEndUserMsgN'] ??
- 'Error While Fetching data',
- statusCode);
+ onFailure!(parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode);
+ logApiEndpointError(endPoint, parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode);
} else {
// var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes));
@@ -1017,8 +857,7 @@ class BaseAppClient {
onSuccess!(parsed, statusCode);
} else {
if (parsed['ErrorType'] == 4) {
- navigateToAppUpdate(
- AppGlobal.context, parsed['ErrorEndUserMessage']);
+ navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
}
if (isAllowAny) {
onSuccess!(parsed, statusCode);
@@ -1033,47 +872,25 @@ class BaseAppClient {
if (parsed != null) {
onSuccess!(parsed, statusCode);
} else {
- onFailure!(
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
+ onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logout();
}
}
- } else if (parsed['MessageStatus'] == 1 ||
- parsed['SMSLoginRequired'] == true) {
+ } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
onSuccess!(parsed, statusCode);
- } else if (parsed['MessageStatus'] == 2 &&
- parsed['IsAuthenticated']) {
- if (parsed['message'] == null &&
- parsed['ErrorEndUserMessage'] == null) {
+ } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
+ if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) {
- onFailure!("Server Error found with no available message",
- statusCode);
- logApiEndpointError(
- endPoint,
- "Server Error found with no available message",
- statusCode);
+ onFailure!("Server Error found with no available message", statusCode);
+ logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
} else {
onFailure!(parsed['ErrorSearchMsg'], statusCode);
- logApiEndpointError(
- endPoint, parsed['ErrorSearchMsg'], statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
}
} else {
- onFailure!(
- parsed['message'] ??
- parsed['ErrorEndUserMessage'] ??
- parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['message'] ??
- parsed['ErrorEndUserMessage'] ??
- parsed['ErrorMessage'],
- statusCode);
+ onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
} else if (!parsed['IsAuthenticated']) {
await logout();
@@ -1084,18 +901,11 @@ class BaseAppClient {
onSuccess!(parsed, statusCode);
} else {
if (parsed['message'] != null) {
- onFailure!(
- parsed['message'] ?? parsed['message'], statusCode);
- logApiEndpointError(endPoint,
- parsed['message'] ?? parsed['message'], statusCode);
+ onFailure!(parsed['message'] ?? parsed['message'], statusCode);
+ logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
} else {
- onFailure!(
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
- logApiEndpointError(
- endPoint,
- parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
- statusCode);
+ onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
+ logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
}
@@ -1103,8 +913,7 @@ class BaseAppClient {
}
} else {
onFailure!('Please Check The Internet Connection', -1);
- _analytics.errorTracking
- .log("internet_connectivity", error: "no internet available");
+ _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
} catch (e) {
print(e);
@@ -1116,15 +925,11 @@ class BaseAppClient {
Future generatePackagesToken() async {
var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN;
var body = {
- "api_client": {
- "client_id": "a4ab6be4-424f-4836-b032-46caed88e184",
- "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"
- }
+ "api_client": {"client_id": "a4ab6be4-424f-4836-b032-46caed88e184", "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"}
};
String? token;
final completer = Completer();
- simplePost(url, body: body, headers: {},
- onSuccess: (dynamic stringResponse, int statusCode) {
+ simplePost(url, body: body, headers: {}, onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
token = jsonResponse['auth_token'];
diff --git a/lib/core/viewModels/project_view_model.dart b/lib/core/viewModels/project_view_model.dart
index 7216da7b..d4707aa9 100644
--- a/lib/core/viewModels/project_view_model.dart
+++ b/lib/core/viewModels/project_view_model.dart
@@ -18,7 +18,10 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart';
+import '../../models/Appointments/DoctorListResponse.dart';
+
bool isAppArabic = false;
+
class ProjectViewModel extends BaseViewModel {
GAnalytics get analytics => locator();
@@ -45,6 +48,27 @@ class ProjectViewModel extends BaseViewModel {
GetAdmissionInfoResponseModel getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel();
GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel();
+ bool isIndoorNavigationEnabled = false;
+
+ int waitingAppointmentProjectID = 0;
+ DoctorList? waitingAppointmentDoctor;
+ String waitingAppointmentNFCCode = "";
+
+ setWaitingAppointmentDoctor(DoctorList waitingAppointmentDoctor) {
+ this.waitingAppointmentDoctor = waitingAppointmentDoctor;
+ notifyListeners();
+ }
+
+ setWaitingAppointmentNFCCode(String waitingAppointmentNFCCode) {
+ this.waitingAppointmentNFCCode = waitingAppointmentNFCCode;
+ notifyListeners();
+ }
+
+ setWaitingAppointmentProjectID(int projectID) {
+ this.waitingAppointmentProjectID = projectID;
+ notifyListeners();
+ }
+
void setIsAllAppointmentsLoaded(bool value) {
_isAllAppointmentsLoaded = value;
notifyListeners();
@@ -137,6 +161,11 @@ class ProjectViewModel extends BaseViewModel {
notifyListeners();
}
+ setIsIndoorNavigationEnabled(bool isEnabled) {
+ this.isIndoorNavigationEnabled = isEnabled;
+ notifyListeners();
+ }
+
setPatientHasAdmissionRequest(bool hasAdmissionRequest) {
this.patientHasAdmissionRequest = hasAdmissionRequest;
notifyListeners();
diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart
index f23d175d..420f08f1 100644
--- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart
+++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart
@@ -37,6 +37,7 @@ class _AllHabibMedicalSevicePage2State extends State
AuthProvider authProvider = new AuthProvider();
WeatherService _weatherService = WeatherService();
double weatherNum = 30;
+ late ProjectViewModel projectViewModel;
@override
void initState() {
@@ -235,7 +236,7 @@ class _AllHabibMedicalSevicePage2State extends State
itemCount: hmgServices.length,
padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) {
- return ServicesView(hmgServices[index], index, false);
+ return ServicesView(hmgServices[index], index, false, projectViewModel);
},
),
),
diff --git a/lib/pages/Blood/blood_donation_book_appointment.dart b/lib/pages/Blood/blood_donation_book_appointment.dart
index a0b9f6f7..6485b2d8 100644
--- a/lib/pages/Blood/blood_donation_book_appointment.dart
+++ b/lib/pages/Blood/blood_donation_book_appointment.dart
@@ -445,7 +445,7 @@ class _BloodDonationBookAppointmentState extends State {
bool isEligible = false;
bool isCash = false;
+ String? selectedPaymentMethod = "";
+ String? selectedInstallments = "";
+ String? tamaraPaymentStatus;
+ String? tamaraOrderID;
+ String? transID;
+ late MyInAppBrowser browser;
+
@override
void initState() {
// widget.authUser = new AuthenticatedUser();
@@ -213,13 +235,18 @@ class _BookConfirmState extends State {
elevation: 0,
onPressed: () async {
bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false;
- if (isLiveCareSchedule) {
- insertLiveCareScheduledAppointment(context, widget.doctor);
+
+ if (widget.isWalkinAppointment) {
+ getWalkinAppointmentPatientShare();
} else {
- checkPatientHasDermaPackage(widget.doctor, projectViewModel.user.patientID!);
+ if (isLiveCareSchedule) {
+ insertLiveCareScheduledAppointment(context, widget.doctor);
+ } else {
+ checkPatientHasDermaPackage(widget.doctor, projectViewModel.user.patientID!);
+ }
}
},
- child: Text(TranslationBase.of(context).bookAppo, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)),
+ child: Text(widget.isWalkinAppointment ? TranslationBase.of(context).addToWaitingList : TranslationBase.of(context).bookAppo, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)),
),
),
),
@@ -227,6 +254,405 @@ class _BookConfirmState extends State {
);
}
+ getWalkinAppointmentPatientShare() {
+ String errorMsg = "";
+ AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList();
+ GifLoaderDialogUtils.showMyDialog(context);
+ appo.doctorTitle = widget.doctor.doctorTitle;
+ appo.doctorNameObj = widget.doctor.name;
+ appo.appointmentDate = DateUtil.convertDateToString(DateTime.now());
+ appo.projectName = widget.doctor.projectName;
+
+ widget.service
+ .getPatientShareForWalkInAppointment(
+ widget.doctor.clinicID!,
+ widget.doctor.projectID!,
+ widget.doctor.doctorID!,
+ )
+ .then((res) {
+
+ widget.patientShareResponse = new PatientShareResponse.fromJson(res["OnlineCheckInAppointmentsWalkInModel"]);
+ GifLoaderDialogUtils.hideDialog(context);
+
+ isInsured = res["IsInsured"];
+ isEligible = res["IsEligible"];
+ isCash = res["IsCash"];
+
+ if (isCash) {
+ if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) {
+ openPaymentDialog(appo, widget.patientShareResponse!);
+ } else {
+ insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null);
+ }
+ } else {
+ if (isInsured && isEligible) {
+ if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) {
+ openPaymentDialog(appo, widget.patientShareResponse!);
+ } else {
+ insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null);
+ }
+ } else {
+ if (isInsured && !isEligible) {
+ errorMsg = TranslationBase.of(context).invalidEligibility;
+ } else {
+ errorMsg = TranslationBase.of(context).invalidInsurance;
+ }
+ ConfirmDialog dialog = new ConfirmDialog(
+ isDissmissable: false,
+ context: context,
+ confirmMessage: errorMsg,
+ okText: TranslationBase.of(context).updateInsuranceText,
+ cancelText: TranslationBase.of(context).continueCash,
+ okFunction: () => {openUpdateInsurance()},
+ cancelFunction: () => {continueAsCashForWalkIn(widget.doctor.projectID!)});
+ dialog.showAlertDialog(context);
+ }
+ }
+
+ // widget.patientShareResponse = new PatientShareResponse.fromJson(res["OnlineCheckInAppointmentsWalkInModel"]);
+ // GifLoaderDialogUtils.hideDialog(context);
+ // if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) {
+ // openPaymentDialog(appo, widget.patientShareResponse!);
+ // } else {
+ // insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null);
+ // }
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err);
+ print(err);
+ });
+ }
+
+ openPaymentDialog(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) {
+ showGeneralDialog(
+ barrierColor: Colors.black.withOpacity(0.5),
+ transitionBuilder: (context, a1, a2, widget) {
+ final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0;
+ return Transform(
+ transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0),
+ child: Opacity(
+ opacity: a1.value,
+ child: PaymentDialog(
+ appo: appo,
+ patientShareResponse: patientShareResponse,
+ isCashPatient: isCash,
+ onPaymentMethodSelected: () {},
+ ),
+ ),
+ );
+ },
+ transitionDuration: Duration(milliseconds: 500),
+ barrierDismissible: false,
+ barrierLabel: '',
+ context: context,
+ pageBuilder: (context, animation1, animation2) => SizedBox()).then((value) {
+ print(value);
+ if (value != null) {
+ navigateToPaymentMethod(context, value as PatientShareResponse);
+ // projectViewModel.analytics.todoList.to_do_list_confirm_payment_details(appo);
+ } else {
+ // projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo);
+ }
+ });
+ }
+
+ Future navigateToPaymentMethod(context, PatientShareResponse patientShareResponse) async {
+ AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList();
+ appo.projectID = widget.doctor.projectID;
+ appo.clinicID = widget.doctor.clinicID;
+ appo.clinicName = widget.doctor.clinicName;
+ appo.projectName = widget.doctor.projectName;
+ appo.appointmentNo = DateTime.now().millisecondsSinceEpoch;
+ appo.isLiveCareAppointment = false;
+ appo.doctorID = widget.doctor.doctorID;
+ appo.appointmentDate = DateUtil.convertDateToString(DateTime.now()); //widget.patientShareResponse.appointmentDate;
+ appo.serviceID = widget.patientShareResponse.serviceID;
+
+ Navigator.push(
+ context,
+ FadePage(
+ page: PaymentMethod(
+ onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) {
+ setState(() {});
+ },
+ patientShare: widget.patientShareResponse.patientShareWithTax)))
+ .then((value) {
+ selectedPaymentMethod = value[0];
+ if (value != null) {
+ if (selectedPaymentMethod == "ApplePay") {
+ if (projectViewModel.havePrivilege(103)) {
+ startApplePay(appo, patientShareResponse);
+ } else {
+ openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo);
+ }
+ } else {
+ openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo);
+ }
+ projectViewModel.analytics.appointment.payment_method(appointment_type: 'Walk-In', clinic: widget.doctor.clinicName, payment_method: value[0], payment_type: 'appointment');
+ }
+ });
+ }
+
+ void startApplePay(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) async {
+ transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo);
+ print("TransactionID: $transID");
+ GifLoaderDialogUtils.showMyDialog(context);
+
+ LiveCareService service = new LiveCareService();
+ ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest();
+
+ PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel;
+ await context.read().getProjectDetailsForPayfort(projectId: appo.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) {
+ payfortProjectDetailsRespModel = value!;
+ });
+
+ applePayInsertRequest.clientRequestID = transID;
+ applePayInsertRequest.clinicID = appo.clinicID;
+ applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR";
+ // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress;
+ applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com";
+ applePayInsertRequest.customerID = projectViewModel.user.patientID;
+ applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!;
+ applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN);
+ applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN);
+ applePayInsertRequest.doctorID = appo.doctorID;
+ applePayInsertRequest.projectID = appo.projectID.toString();
+ applePayInsertRequest.serviceID = ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum().toString();
+ applePayInsertRequest.channelID = 3;
+ applePayInsertRequest.patientID = projectViewModel.user.patientID;
+ applePayInsertRequest.patientTypeID = projectViewModel.user.patientType;
+ applePayInsertRequest.patientOutSA = projectViewModel.user.outSA;
+ applePayInsertRequest.appointmentDate = appo.appointmentDate;
+ applePayInsertRequest.appointmentNo = appo.appointmentNo;
+ applePayInsertRequest.orderDescription = "Appointment Payment";
+ applePayInsertRequest.liveServiceID = "0";
+ applePayInsertRequest.latitude = "0.0";
+ applePayInsertRequest.longitude = "0.0";
+ applePayInsertRequest.amount = patientShareResponse.patientShareWithTax.toString();
+ applePayInsertRequest.isSchedule = appo.isLiveCareAppointment! ? "1" : "0";
+ applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en';
+ applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2;
+ applePayInsertRequest.userName = projectViewModel.user.patientID;
+ applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html";
+ applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html";
+ applePayInsertRequest.paymentOption = "ApplePay";
+
+ applePayInsertRequest.isMobSDK = true;
+ applePayInsertRequest.merchantReference = transID;
+ applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier!;
+ applePayInsertRequest.commandType = "PURCHASE";
+ applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature;
+ applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode;
+ applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest;
+ applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse;
+ applePayInsertRequest.returnURL = "";
+
+ service.applePayInsertRequest(applePayInsertRequest, context).then((res) async {
+ if (res["MessageStatus"] == 1) {
+ await context.read().initiateApplePayWithPayfort(
+ customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!,
+ // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress,
+ customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com",
+ orderDescription: "Walk-In appointment payment",
+ orderAmount: double.parse(patientShareResponse.patientShareWithTax.toString()),
+ merchantReference: transID,
+ payfortProjectDetailsRespModel: payfortProjectDetailsRespModel,
+ currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR",
+ onFailed: (failureResult) async {
+ log("failureResult: ${failureResult.toString()}");
+ AppToast.showErrorToast(message: failureResult.toString());
+ },
+ onSuccess: (successResult) async {
+ log("Payfort: ${successResult.responseMessage}");
+ await context.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult);
+ checkPaymentStatus(appo);
+ },
+ projectId: appo.projectID,
+ serviceTypeEnum: ServiceTypeEnum.appointmentPayment,
+ );
+ } else {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: "An error occurred while processing your request");
+ }
+ }).catchError((err) {
+ print(err);
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err);
+ });
+ }
+
+ openPayment(List paymentMethod, AuthenticatedUser authenticatedUser, num amount, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) async {
+ browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context);
+ selectedPaymentMethod = paymentMethod[0];
+ selectedInstallments = paymentMethod[1];
+ transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo);
+ browser.openPaymentBrowser(
+ amount,
+ "Walk-In appointment payment",
+ transID!,
+ appo.projectID.toString(),
+ authenticatedUser.emailAddress!,
+ paymentMethod[0]!,
+ authenticatedUser.patientType,
+ authenticatedUser.firstName!,
+ authenticatedUser.patientID,
+ authenticatedUser,
+ browser,
+ widget.patientShareResponse.isLiveCareAppointment!,
+ "2",
+ widget.patientShareResponse.isLiveCareAppointment! ? widget.patientShareResponse.clinicID.toString() : "",
+ context,
+ widget.patientShareResponse.appointmentDate,
+ widget.patientShareResponse.appointmentNo,
+ widget.patientShareResponse.clinicID,
+ widget.patientShareResponse.doctorID,
+ paymentMethod[1]);
+ // }
+ }
+
+ onBrowserLoadStart(String url) {
+ if (selectedPaymentMethod == "TAMARA") {
+ if (Platform.isAndroid) {
+ Uri uri = new Uri.dataFromString(url);
+ tamaraPaymentStatus = uri.queryParameters['status'];
+ tamaraOrderID = uri.queryParameters['AuthorizePaymentId'];
+ } else {
+ Uri uri = new Uri.dataFromString(url);
+ tamaraPaymentStatus = uri.queryParameters['paymentStatus'];
+ tamaraOrderID = uri.queryParameters['orderId'];
+ }
+ }
+
+ MyInAppBrowser.successURLS.forEach((element) {
+ if (url.contains(element)) {
+ if (browser.isOpened()) browser.close();
+ MyInAppBrowser.isPaymentDone = true;
+ return;
+ }
+ });
+
+ MyInAppBrowser.errorURLS.forEach((element) {
+ if (url.contains(element)) {
+ if (browser.isOpened()) browser.close();
+ MyInAppBrowser.isPaymentDone = false;
+ return;
+ }
+ });
+ }
+
+ onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) {
+ try {
+ if (selectedPaymentMethod == "TAMARA") {
+ checkTamaraPaymentStatus(transID!, appo);
+ // if (tamaraPaymentStatus != null && tamaraPaymentStatus!.toLowerCase() == "approved") {
+ // updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID!, num.parse(selectedInstallments!), appo);
+ // } else {
+ // updateTamaraRequestStatus(
+ // "Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID! != null ? tamaraOrderID! : "", num.parse(selectedInstallments!), appo);
+ // }
+ } else {
+ checkPaymentStatus(appo);
+ }
+ } catch (err) {
+ print(err);
+ }
+ }
+
+ checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) {
+ GifLoaderDialogUtils.showMyDialog(context);
+ DoctorsListService service = new DoctorsListService();
+ service.getTamaraPaymentStatus(orderID).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ if (res["status"].toString().toLowerCase() == "success") {
+ updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID!, int.parse(selectedInstallments!), appo);
+ } else {
+ updateTamaraRequestStatus(
+ "Failed", "00", Utils.getAppointmentTransID(appo.projectID!, appo.clinicID!, appo.appointmentNo!), tamaraOrderID != null ? tamaraOrderID! : "", int.parse(selectedInstallments!), appo);
+ }
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err);
+ print(err);
+ });
+ }
+
+ updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, num selectedInstallments, AppoitmentAllHistoryResultList appo) {
+ GifLoaderDialogUtils.showMyDialog(context);
+ try {
+ DoctorsListService service = new DoctorsListService();
+ service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ if (tamaraPaymentStatus!.toLowerCase() == "approved") {
+ insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, tamaraOrderID);
+ }
+ }).catchError((err) {
+ print(err);
+ AppToast.showErrorToast(message: err);
+ GifLoaderDialogUtils.hideDialog(context);
+ });
+ } catch (err) {
+ print(err);
+ }
+ }
+
+ addAdvancedNumberRequestTamara(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) {
+ DoctorsListService service = new DoctorsListService();
+ service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {}).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err);
+ print(err);
+ });
+ }
+
+ markAppointmentForTamara(AppoitmentAllHistoryResultList appo) {
+ GifLoaderDialogUtils.showMyDialog(context);
+ DoctorsListService service = new DoctorsListService();
+ service.markAppointmentForTamara(appo.projectID!, appo.appointmentNo.toString()).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(appo.appointmentNo), projectViewModel.waitingAppointmentProjectID);
+ }).catchError((err) {
+ print(err);
+ AppToast.showErrorToast(message: err);
+ GifLoaderDialogUtils.hideDialog(context);
+ });
+ }
+
+ checkPaymentStatus(AppoitmentAllHistoryResultList appo) {
+ String txn_ref;
+ num amount;
+ String payment_method;
+ final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed';
+ GifLoaderDialogUtils.showMyDialog(context);
+ DoctorsListService service = new DoctorsListService();
+ service.checkPaymentStatus(transID!, false, context).then((res) {
+ String paymentInfo = res['Response_Message'];
+ if (paymentInfo == 'Success') {
+ txn_ref = res['Merchant_Reference'];
+ amount = res['Amount'];
+ payment_method = res['PaymentMethod'];
+ GifLoaderDialogUtils.hideDialog(context);
+ insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, res);
+ projectViewModel.analytics.appointment.payment_success(
+ appointment_type: 'Walk-In', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref);
+ } else {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: res['Response_Message']);
+ projectViewModel.analytics.appointment.payment_fail(
+ appointment_type: 'Walk-In',
+ payment_method: selectedPaymentMethod,
+ clinic: appo.clinicName,
+ hospital: appo.projectName,
+ txn_amount: widget.patientShareResponse.patientShareWithTax.toString(),
+ txn_currency: currency,
+ error_type: res['Response_Message']);
+ }
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err.toString());
+ print(err);
+ });
+ }
+
Widget showInfo(String title, String des) {
return Container(
child: Row(
@@ -266,7 +692,7 @@ class _BookConfirmState extends State {
if (isLiveCareSchedule != null && isLiveCareSchedule) {
insertLiveCareScheduledAppointment(context, widget.doctor);
} else {
- insertAppointment(widget.doctor, widget.initialSlotDuration, invoiceNumber: invoiceNumber, lineItemNo: lineItemNo);
+ insertAppointment(context, widget.doctor, widget.initialSlotDuration);
}
});
} else {
@@ -322,6 +748,111 @@ class _BookConfirmState extends State {
});
}
+ void continueAsCashForWalkIn(int projectID) {
+ GifLoaderDialogUtils.showMyDialog(context);
+ widget.service.convertPatientToCash(projectID).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ if (res["MessageStatus"] == 1) {
+ getWalkinAppointmentPatientShare();
+ } else {
+ AppToast.showErrorToast(message: res["ErrorEndUserMessage"]);
+ }
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err);
+ print(err);
+ });
+ }
+
+ insertWalkInAppointment(context, DoctorList docObject, int initialSlotDuration, paymentRes) async {
+ GifLoaderDialogUtils.showMyDialog(
+ context,
+ );
+ AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList();
+ appo.doctorID = docObject.doctorID;
+ appo.clinicID = docObject.clinicID;
+ appo.projectID = docObject.projectID;
+
+ widget.service
+ .insertWalkInAppointment(
+ docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, projectViewModel.isArabic ? 1 : 2, context)
+ .then((res) {
+ if (res['MessageStatus'] == 1) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess);
+ appo.appointmentNo = res["AppointmentNo"]; // Add appointment No to the appointment project
+ Future.delayed(Duration(milliseconds: 500), () {
+ if (selectedPaymentMethod == "TAMARA") {
+ markAppointmentForTamara(appo);
+ addAdvancedNumberRequestTamara("Tamara-Advance-0000", paymentRes, res["AppointmentNo"].toString(), appo);
+ } else {
+ if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) {
+ createAdvancePayment(paymentRes, appo);
+ } else {
+ sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(res["AppointmentNo"]), projectViewModel.waitingAppointmentProjectID);
+ }
+ }
+ });
+ } else {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
+ }
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err);
+ });
+ }
+
+ createAdvancePayment(res, AppoitmentAllHistoryResultList appo) {
+ GifLoaderDialogUtils.showMyDialog(
+ context,
+ );
+ DoctorsListService service = new DoctorsListService();
+ String paymentReference = res['Fort_id'].toString();
+ service.createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], context).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ addAdvancedNumberRequest(
+ Utils.isVidaPlusProject(projectViewModel, appo.projectID!)
+ ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString()
+ : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(),
+ paymentReference,
+ appo.appointmentNo.toString(),
+ appo);
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err);
+ print(err);
+ });
+ }
+
+ addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) {
+ GifLoaderDialogUtils.showMyDialog(
+ context,
+ );
+ DoctorsListService service = new DoctorsListService();
+ service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(appointmentID), projectViewModel.waitingAppointmentProjectID);
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err);
+ print(err);
+ });
+ }
+
+ sendNfcCheckInRequest(String nfcId, int checkInBy, int appoNo, int projectID) {
+ GifLoaderDialogUtils.showMyDialog(context);
+ DoctorsListService service = new DoctorsListService();
+ service.sendCheckinNfcRequest(appoNo, nfcId, projectID, checkInBy, context as int).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ _showMyDialog(res["SuccessMsg"], this.context);
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ print(err);
+ _showMyDialog(err, this.context);
+ });
+ }
+
checkPatientHasDermaPackage(DoctorList doctor, int patientID) {
GifLoaderDialogUtils.showMyDialog(context);
widget.service
@@ -358,11 +889,11 @@ class _BookConfirmState extends State {
});
}
- insertAppointment(DoctorList docObject, int initialSlotDuration, {int? invoiceNumber, int? lineItemNo}) async {
+ insertAppointment(context, DoctorList docObject, int initialSlotDuration) async {
final timeSlot = DocAvailableAppointments.selectedAppoDateTime;
String logs = await sharedPref.getString('selectedLogSlots');
List decodedLogs = json.decode(logs);
- GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: true);
+ GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false);
AppoitmentAllHistoryResultList appo;
widget.service
// .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, context, 'null', null, null, projectViewModel)
@@ -613,4 +1144,32 @@ class _BookConfirmState extends State {
),
);
}
+
+ Future _showMyDialog(String message, BuildContext context) async {
+ return showDialog(
+ context: context,
+ barrierDismissible: true, // user must tap button!
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: const Text('Alert'),
+ content: SingleChildScrollView(
+ child: ListBody(
+ children: [
+ Text(message),
+ ],
+ ),
+ ),
+ actions: [
+ TextButton(
+ child: const Text('OK'),
+ onPressed: () {
+ Navigator.of(context).pop();
+ Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false);
+ },
+ ),
+ ],
+ );
+ },
+ );
+ }
}
diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart
index f1738c85..1674c43d 100644
--- a/lib/pages/BookAppointment/DoctorProfile.dart
+++ b/lib/pages/BookAppointment/DoctorProfile.dart
@@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart';
import 'package:diplomaticquarterapp/models/header_model.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/doctor_post_pre_images_page.dart';
+import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart';
import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
@@ -520,15 +521,9 @@ class _DoctorProfileState extends State with TickerProviderStateM
// if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17) {
// navigateToDentalComplaints(context);
// } else {
- if (DocAvailableAppointments.areSlotsAvailable) {
+ if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) {
if (projectViewModel.isLogin) {
- if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17 && projectViewModel.user!.age! > 12) {
- navigateToDentalComplaints(context);
- } else {
- final timeSlot = DocAvailableAppointments.selectedAppoDateTime;
- navigateToBookConfirm(context);
- projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor);
- }
+ canPayForWalkInAppointment();
} else {
ConfirmDialog dialog = new ConfirmDialog(
context: context,
@@ -539,9 +534,30 @@ class _DoctorProfileState extends State with TickerProviderStateM
cancelFunction: () => {});
dialog.showAlertDialog(context);
}
- } else
- AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot);
- // }
+ } else {
+ if (DocAvailableAppointments.areSlotsAvailable) {
+ if (projectViewModel.isLogin) {
+ if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17 && projectViewModel.user!.age! > 12) {
+ navigateToDentalComplaints(context);
+ } else {
+ final timeSlot = DocAvailableAppointments.selectedAppoDateTime;
+ navigateToBookConfirm(context);
+ projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor);
+ }
+ } else {
+ ConfirmDialog dialog = new ConfirmDialog(
+ context: context,
+ confirmMessage: TranslationBase.of(context).loginToUseService,
+ okText: TranslationBase.of(context).confirm,
+ cancelText: TranslationBase.of(context).cancel_nocaps,
+ okFunction: () => {navigateToLogin()},
+ cancelFunction: () => {});
+ dialog.showAlertDialog(context);
+ }
+ } else {
+ AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot);
+ }
+ }
}
Future navigateToDentalComplaints(BuildContext context) async {
@@ -586,8 +602,33 @@ class _DoctorProfileState extends State with TickerProviderStateM
selectedDate: DocAvailableAppointments.selectedDate!,
selectedTime: DocAvailableAppointments.selectedTime!,
initialSlotDuration: DocAvailableAppointments.initialSlotDuration!,
+ isWalkinAppointment: false,
),
),
);
}
+
+ Future navigateToWaitingAppointment(context) async {
+ projectViewModel.setWaitingAppointmentProjectID(widget.doctor.projectID!);
+ projectViewModel.setWaitingAppointmentDoctor(widget.doctor);
+ Navigator.push(
+ context,
+ FadePage(
+ page: WaitingAppointmentInfo(),
+ ),
+ );
+ }
+
+ canPayForWalkInAppointment() {
+ DoctorsListService service = new DoctorsListService();
+ GifLoaderDialogUtils.showMyDialog(context);
+ service.canPayForWalkInAppointment(widget.doctor.clinicID!, widget.doctor.projectID!, widget.doctor.doctorID!).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ navigateToWaitingAppointment(context);
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err, localContext: context);
+ print(err);
+ });
+ }
}
diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart
index a2940ce8..d44eee92 100644
--- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart
+++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart
@@ -60,6 +60,8 @@ class _DocAvailableAppointmentsState extends State wit
var language;
bool isLiveCareSchedule = false;
+ bool isWaitingAppointmentAvailable = false;
+
// String selectedLogSlots ='';
@override
@@ -198,7 +200,7 @@ class _DocAvailableAppointmentsState extends State wit
_events.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(hours: 2));
- meetings.add(Meeting("", startTime, endTime, CustomColors.green, false));
+ meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, ""));
});
return meetings;
}
@@ -206,7 +208,9 @@ class _DocAvailableAppointmentsState extends State wit
openTimeSlotsPickerForDate(DateTime dateStart, List freeSlots) {
dayEvents.clear();
DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0);
-
+ if (isWaitingAppointmentAvailable && DateUtils.isSameDay(dateStart, DateTime.now())) {
+ dayEvents.add(TimeSlot(isoTime: TranslationBase.of(context).waitingAppointment, start: DateTime.now(), end: DateTime.now(), vidaDate: ""));
+ }
freeSlots.forEach((v) {
if (v.start == dateStartObj) dayEvents.add(v);
});
@@ -349,20 +353,22 @@ class _DocAvailableAppointmentsState extends State wit
GifLoaderDialogUtils.hideDialog(context);
if (res['MessageStatus'] == 1) {
if (res['FreeTimeSlots'].length != 0) {
+ isWaitingAppointmentAvailable = res['IsAllowToBookWaitingAppointment']; // true;
+ // isWaitingAppointmentAvailable = true; // true;
DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration'];
DocAvailableAppointments.areAppointmentsAvailable = true;
freeSlotsResponse = res['FreeTimeSlots'];
_getJSONSlots().then((value) {
- setState(() => {
- _events.clear(),
- _events = value,
+ setState(() {
+ _events.clear();
+ _events = value;
if (widget.doctorSchedule != null)
{
- _onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])),
+ _onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date']));
_calendarController.selectedDate = DateUtil.convertStringToDate(
widget.doctorSchedule['Date'],
- )
- }
+ );
+ };
});
});
} else {
@@ -464,11 +470,12 @@ class MeetingDataSource extends CalendarDataSource {
}
class Meeting {
- Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay);
+ Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes);
String eventName;
DateTime from;
DateTime to;
Color background;
bool isAllDay;
+ String notes;
}
diff --git a/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart
new file mode 100644
index 00000000..f1f8d934
--- /dev/null
+++ b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart
@@ -0,0 +1,113 @@
+import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart';
+import 'package:diplomaticquarterapp/theme/colors.dart';
+import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
+import 'package:diplomaticquarterapp/uitl/utils_new.dart';
+import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
+import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
+import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+class WaitingAppointmentInfo extends StatelessWidget {
+ const WaitingAppointmentInfo({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return AppScaffold(
+ appBarTitle: TranslationBase.of(context).waitingAppointment,
+ isShowAppBar: true,
+ isShowDecPage: false,
+ showNewAppBar: true,
+ showNewAppBarTitle: true,
+ backgroundColor: CustomColors.appBackgroudGreyColor,
+ body: SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Container(
+ width: MediaQuery.of(context).size.width,
+ decoration: containerRadius(Colors.white, 10),
+ child: Padding(
+ padding: const EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SvgPicture.asset(
+ "assets/images/new/waitingAppo.svg",
+ width: 52.0,
+ height: 52.0,
+ ),
+ mHeight(11),
+ Text(
+ TranslationBase.of(context).whatWaitingAppointment,
+ maxLines: 1,
+ style: TextStyle(fontSize: 17, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24),
+ ),
+ mHeight(11),
+ Container(
+ width: MediaQuery.of(context).size.width * 0.8,
+ child: Text(
+ TranslationBase.of(context).waitingAppointmentText1,
+ style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
+ ),
+ ),
+ mHeight(18),
+ Container(
+ width: MediaQuery.of(context).size.width * 0.8,
+ child: Text(
+ TranslationBase.of(context).waitingAppointmentText2,
+ style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
+ ),
+ ),
+ mHeight(24),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Icon(
+ Icons.warning,
+ size: 20,
+ color: Color(0xffA78618),
+ ),
+ mWidth(10),
+ Container(
+ width: MediaQuery.of(context).size.width * 0.7,
+ child: Text(
+ TranslationBase.of(context).waitingAppointmentText3,
+ style: TextStyle(
+ fontSize: 14, fontStyle: FontStyle.italic, fontWeight: FontWeight.w600, color: Color(0xffA78618), letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ bottomSheet: Container(
+ height: 80,
+ color: CustomColors.white,
+ padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0),
+ child: Container(
+ child: DefaultButton(
+ TranslationBase.of(context).continues,
+ () {
+ Navigator.push(
+ context,
+ FadePage(
+ page: WaitingAppointmentVerification(),
+ ),
+ );
+ },
+ color: CustomColors.accentColor,
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart
new file mode 100644
index 00000000..6853c6d9
--- /dev/null
+++ b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart
@@ -0,0 +1,292 @@
+import 'package:barcode_scan2/barcode_scan2.dart';
+import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart';
+import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
+import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart';
+import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
+import 'package:diplomaticquarterapp/theme/colors.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/location_util.dart';
+import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
+import 'package:diplomaticquarterapp/uitl/utils_new.dart';
+import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
+import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart';
+import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
+import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:intl/intl.dart';
+import 'package:provider/provider.dart';
+
+import '../../../uitl/utils.dart';
+
+class WaitingAppointmentVerification extends StatefulWidget {
+ const WaitingAppointmentVerification({super.key});
+
+ @override
+ State createState() => _WaitingAppointmentVerificationState();
+}
+
+class _WaitingAppointmentVerificationState extends State {
+ String selectedVerificationMethod = "QR";
+
+ late ProjectViewModel projectViewModel;
+ late LocationUtils locationUtils;
+ ProjectDetailListModel projectDetailListModel = ProjectDetailListModel();
+
+ @override
+ Widget build(BuildContext context) {
+ projectViewModel = Provider.of(context);
+ return AppScaffold(
+ appBarTitle: TranslationBase.of(context).waitingAppointment,
+ isShowAppBar: true,
+ isShowDecPage: false,
+ showNewAppBar: true,
+ showNewAppBarTitle: true,
+ backgroundColor: CustomColors.appBackgroudGreyColor,
+ body: SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ mHeight(11),
+ Text(
+ TranslationBase.of(context).waitingAppointmentVerificationMethod,
+ maxLines: 1,
+ style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.04, height: 35 / 24),
+ ),
+ mHeight(12),
+ Container(
+ width: MediaQuery.of(context).size.width,
+ decoration: containerRadius(Colors.white, 10),
+ child: Padding(
+ padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ InkWell(
+ onTap: () {
+ setState(() {
+ selectedVerificationMethod = "QR";
+ });
+ },
+ child: Row(
+ children: [
+ Container(
+ width: 20,
+ height: 20,
+ decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "QR" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5),
+ ),
+ mWidth(6),
+ Container(
+ height: 40.0,
+ width: 40.0,
+ padding: EdgeInsets.all(7.0),
+ child: SvgPicture.asset(
+ "assets/images/new/services/qr_code.svg",
+ ),
+ ),
+ Text(
+ TranslationBase.of(context).pharmaLiveCareScanQR,
+ style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
+ ),
+ ],
+ ),
+ ),
+ Divider(),
+ InkWell(
+ onTap: () {
+ setState(() {
+ selectedVerificationMethod = "NFC";
+ });
+ },
+ child: Row(
+ children: [
+ Container(
+ width: 20,
+ height: 20,
+ decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "NFC" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5),
+ ),
+ mWidth(6),
+ Container(
+ height: 40.0,
+ width: 40.0,
+ padding: EdgeInsets.all(7.0),
+ child: SvgPicture.asset(
+ "assets/images/new/services/contactless.svg",
+ ),
+ ),
+ Text(
+ TranslationBase.of(context).scanNFC,
+ style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
+ ),
+ ],
+ ),
+ ),
+ Divider(),
+ InkWell(
+ onTap: () {
+ setState(() {
+ selectedVerificationMethod = "Location";
+ });
+ },
+ child: Row(
+ children: [
+ Container(
+ width: 20,
+ height: 20,
+ decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "Location" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5),
+ ),
+ mWidth(6),
+ Container(
+ height: 40.0,
+ width: 40.0,
+ padding: EdgeInsets.all(7.0),
+ child: SvgPicture.asset(
+ "assets/images/new/services/location.svg",
+ ),
+ ),
+ Text(
+ TranslationBase.of(context).checkInViaLocation,
+ style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
+ ),
+ ],
+ ),
+ ),
+ mHeight(6),
+ ],
+ ),
+ ),
+ ),
+ mHeight(12),
+ Container(
+ width: MediaQuery.of(context).size.width,
+ decoration: containerRadius(Colors.white, 10),
+ child: Padding(
+ padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ mHeight(12),
+ Text(
+ TranslationBase.of(context).howToUseVerificationMethod,
+ maxLines: 1,
+ style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -1.04, height: 35 / 24),
+ ),
+ mHeight(12),
+ Image.asset(
+ 'assets/images/new/NFCCheckIn_QR_gps_HMG.png',
+ fit: BoxFit.fitWidth,
+ width: MediaQuery.of(context).size.width,
+ ),
+ mHeight(12),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ bottomSheet: Container(
+ height: 80,
+ color: CustomColors.white,
+ padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0),
+ child: Container(
+ child: DefaultButton(
+ TranslationBase.of(context).continues,
+ () {
+ startVerification();
+ },
+ color: CustomColors.accentColor,
+ ),
+ ),
+ ),
+ );
+ }
+
+ startVerification() {
+ switch (selectedVerificationMethod) {
+ case "QR":
+ startQRCodeScan();
+ break;
+ case "NFC":
+ startNFCScan();
+ break;
+ case "Location":
+ startLocationCheckIn();
+ break;
+ }
+ }
+
+ checkScannedNFCAndQRCode(String nfcId) {
+ GifLoaderDialogUtils.showMyDialog(context);
+ DoctorsListService service = new DoctorsListService();
+ service.checkScannedNFCAndQRCode(nfcId, projectViewModel.waitingAppointmentDoctor!.projectID!).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ projectViewModel.setWaitingAppointmentNFCCode(nfcId);
+ if (res["returnValue"] == 1) {
+ navigateToBookConfirm(context);
+ } else {
+ AppToast.showErrorToast(message: "Invalid verification point scanned.");
+ }
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ print(err);
+ });
+ }
+
+ Future navigateToBookConfirm(context) async {
+ final DateFormat formatter = DateFormat('yyyy-MM-dd');
+ Navigator.push(
+ context,
+ FadePage(
+ page: BookConfirm(
+ doctor: projectViewModel.waitingAppointmentDoctor!,
+ isLiveCareAppointment: false,
+ selectedDate: formatter.format(DateTime.now()),
+ selectedTime: TranslationBase.of(context).waitingAppointment,
+ initialSlotDuration: 15,
+ isWalkinAppointment: true,
+ ),
+ ),
+ );
+ }
+
+ startLocationCheckIn() async {
+ locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context);
+ locationUtils.getCurrentLocation(callBack: (value) {
+ projectDetailListModel = Utils.getProjectDetailObj(projectViewModel, projectViewModel.waitingAppointmentProjectID);
+ double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000;
+ projectViewModel.setWaitingAppointmentNFCCode(projectDetailListModel.checkInQrCode!);
+ print(dist);
+ if (dist <= projectDetailListModel.geofenceRadius!) {
+ navigateToBookConfirm(context);
+ } else {
+ AppToast.showErrorToast(message: TranslationBase.of(context).locationCheckInError);
+ }
+ });
+ }
+
+ startNFCScan() {
+ Future.delayed(const Duration(milliseconds: 500), () {
+ showNfcReader(context, onNcfScan: (String nfcId) {
+ Future.delayed(const Duration(milliseconds: 100), () {
+ checkScannedNFCAndQRCode(nfcId);
+ });
+ }, onCancel: () {
+ // Navigator.of(context).pop();
+ // locator().todoList.to_do_list_nfc_cancel(widget.appointment!);
+ });
+ });
+ }
+
+ startQRCodeScan() async {
+ String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent));
+ if (onlineCheckInQRCode != "") {
+ checkScannedNFCAndQRCode(onlineCheckInQRCode);
+ } else {}
+ }
+}
diff --git a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart
index a9a16ce7..88be72dd 100644
--- a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart
+++ b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart
@@ -260,7 +260,7 @@ class _CovidTimeSlotsState extends State with TickerProviderStat
_events.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(minutes: 20));
- meetings.add(Meeting("", startTime, endTime, CustomColors.green, false));
+ meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, ""));
});
return meetings;
}
@@ -584,11 +584,12 @@ class MeetingDataSource extends CalendarDataSource {
}
class Meeting {
- Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay);
+ Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes);
String eventName;
DateTime from;
DateTime to;
Color background;
bool isAllDay;
+ String notes;
}
diff --git a/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart b/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart
index 82e6ab96..8281450b 100644
--- a/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart
+++ b/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart
@@ -272,7 +272,7 @@ class _InPatientPendingAdvancePaymentState extends State with SingleTick
}
void goToBookConfirm() {
- if (DocAvailableAppointments.areSlotsAvailable)
- navigateToBookConfirm(context);
- else
- AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot);
+ if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) {
+ canPayForWalkInAppointment();
+ } else {
+ if (DocAvailableAppointments.areSlotsAvailable)
+ navigateToBookConfirm(context);
+ else
+ AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot);
+ }
+ }
+
+ canPayForWalkInAppointment() {
+ DoctorsListService service = new DoctorsListService();
+ GifLoaderDialogUtils.showMyDialog(context);
+ service.canPayForWalkInAppointment(widget.appo.clinicID!, widget.appo.projectID!, widget.appo.doctorID!).then((res) {
+ GifLoaderDialogUtils.hideDialog(context);
+ navigateToWaitingAppointment(context);
+ }).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
+ AppToast.showErrorToast(message: err, localContext: context);
+ print(err);
+ });
+ }
+
+ Future navigateToWaitingAppointment(context) async {
+ DoctorList doctor = new DoctorList();
+ doctor.name = widget.appo.doctorNameObj;
+ doctor.clinicID = widget.appo.clinicID;
+ doctor.projectID = widget.appo.projectID;
+ doctor.doctorID = widget.appo.doctorID;
+ doctor.clinicName = widget.appo.clinicName;
+ doctor.projectName = widget.appo.projectName;
+ doctor.doctorTitle = widget.appo.doctorTitle;
+ doctor.doctorImageURL = widget.appo.doctorImageURL;
+ doctor.speciality = widget.appo.doctorSpeciality;
+ doctor.nationalityFlagURL = "";
+ doctor.doctorRate = widget.appo.doctorRate;
+ doctor.noOfPatientsRate = widget.appo.noOfPatientsRate;
+
+ projectViewModel?.setWaitingAppointmentProjectID(widget.appo.projectID!);
+ projectViewModel?.setWaitingAppointmentDoctor(doctor);
+ Navigator.push(
+ context,
+ FadePage(
+ page: WaitingAppointmentInfo(),
+ ),
+ );
}
Future navigateToBookConfirm(context) async {
Navigator.push(
- context,
- FadePage(
- page: BookConfirm(
+ context,
+ FadePage(
+ page: BookConfirm(
doctor: getDoctorObject(),
isLiveCareAppointment: widget.appo.isLiveCareAppointment!,
selectedDate: DocAvailableAppointments.selectedDate!,
selectedTime: DocAvailableAppointments.selectedTime!,
initialSlotDuration: 0,
- )));
+ isWalkinAppointment: false,
+ ),
+ ),
+ );
}
void getDoctorRatingsDetails() {
diff --git a/lib/pages/MyAppointments/models/BookedButtons.dart b/lib/pages/MyAppointments/models/BookedButtons.dart
index 66e4366f..39aed7cc 100644
--- a/lib/pages/MyAppointments/models/BookedButtons.dart
+++ b/lib/pages/MyAppointments/models/BookedButtons.dart
@@ -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"}
];
}
diff --git a/lib/pages/MyAppointments/models/ConfirmedButtons.dart b/lib/pages/MyAppointments/models/ConfirmedButtons.dart
index 7ba3ce1c..d49723e9 100644
--- a/lib/pages/MyAppointments/models/ConfirmedButtons.dart
+++ b/lib/pages/MyAppointments/models/ConfirmedButtons.dart
@@ -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"}
];
}
diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart
index 6347d3f4..fcb698b3 100644
--- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart
+++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart
@@ -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 {
navigateToInsertComplaint();
locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint');
break;
+
+ case "goToNavigation":
+ initPenguinSDK();
+ locator().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 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);
+ });
}
}
diff --git a/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart b/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart
index 38c09047..9660a616 100644
--- a/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart
+++ b/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart
@@ -253,7 +253,7 @@ class _CovidTimeSlotsState extends State with TickerProviderSta
_events!.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(minutes: 20));
- meetings.add(Meeting("", startTime, endTime, CustomColors.green, false));
+ meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, ""));
});
return meetings;
}
@@ -534,11 +534,12 @@ class MeetingDataSource extends CalendarDataSource {
}
class Meeting {
- Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay);
+ Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes);
String eventName;
DateTime from;
DateTime to;
Color background;
bool isAllDay;
+ String notes;
}
diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart
index 44b0b022..5b8c6801 100644
--- a/lib/pages/ToDoList/ToDo.dart
+++ b/lib/pages/ToDoList/ToDo.dart
@@ -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 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 with SingleTickerProviderStateMixin {
);
}
+ initPenguinSDK(NavigationClinicDetails data) async {
+ final bool permited = await AppPermission.askPenguinPermissions();
+ if (!permited) {
+ Map 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:
@@ -1115,7 +1166,6 @@ class _ToDoState extends State with SingleTickerProviderStateMixin {
projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo);
}
});
-
projectViewModel.analytics.todoList.to_do_list_pay_now(appo);
}
@@ -1465,7 +1515,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin {
}).catchError((err) {
print(err);
GifLoaderDialogUtils.hideDialog(context);
- AppToast.showErrorToast(message: err);
+ AppToast.showErrorToast(message: err.toString());
});
}
diff --git a/lib/pages/insurance/insurance_update_screen.dart b/lib/pages/insurance/insurance_update_screen.dart
index 191170ef..4c4d5686 100644
--- a/lib/pages/insurance/insurance_update_screen.dart
+++ b/lib/pages/insurance/insurance_update_screen.dart
@@ -167,7 +167,7 @@ class _InsuranceUpdateState extends State with SingleTickerProv
Container(
margin: EdgeInsets.only(top: 6.5, left: 2.0),
child: Text(
- model.insuranceUpdate[index].statusDescription!,
+ model.insuranceUpdate[index].statusDescription ?? "",
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w600,
diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart
index c1c922ac..7711b4ff 100644
--- a/lib/pages/landing/fragments/home_page_fragment2.dart
+++ b/lib/pages/landing/fragments/home_page_fragment2.dart
@@ -52,7 +52,11 @@ class _HomePageFragment2State extends State {
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 {
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 {
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 {
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 {
flex: 1,
child: InkWell(
onTap: () {
- if (projectViewModel.havePrivilege(100))
- widget.onPharmacyClick!();
+ if (projectViewModel.havePrivilege(100)) widget.onPharmacyClick!();
},
child: Stack(children: [
Container(
diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart
index 6fe004fc..05d90571 100644
--- a/lib/pages/landing/landing_page.dart
+++ b/lib/pages/landing/landing_page.dart
@@ -22,7 +22,8 @@ import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doct
import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart';
-import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart' as family;
+import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart'
+ as family;
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart';
import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart';
@@ -43,7 +44,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 +665,7 @@ class _LandingPageState extends State 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)) {
diff --git a/lib/pages/landing/widgets/services_view.dart b/lib/pages/landing/widgets/services_view.dart
index 5635a4a6..c69f772c 100644
--- a/lib/pages/landing/widgets/services_view.dart
+++ b/lib/pages/landing/widgets/services_view.dart
@@ -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();
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 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 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().hmgServices.logServiceName('emergency service');
+ // initPenguinSDK();
+ if (projectViewModel.isIndoorNavigationEnabled) {
+ if (!isLocked) openNavigationProjectSelection(context);
+ } else {
+ Navigator.push(context, FadePage(page: ErOptions(isAppbar: true)));
+ locator().hmgServices.logServiceName('emergency service');
+ }
} else if (hmgServices.action == 3) {
Navigator.push(context, FadePage(page: HomeHealthCarePage()));
locator().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().hmgServices.logServiceName('latest news');
diff --git a/lib/pages/livecare/video-call-web-page.dart b/lib/pages/livecare/video-call-web-page.dart
index 46a29924..f755d1b0 100644
--- a/lib/pages/livecare/video-call-web-page.dart
+++ b/lib/pages/livecare/video-call-web-page.dart
@@ -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(
diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart
index 44ad58b0..76d70885 100644
--- a/lib/pages/livecare/widgets/clinic_list.dart
+++ b/lib/pages/livecare/widgets/clinic_list.dart
@@ -373,15 +373,17 @@ class _clinic_listState extends State {
String pharmaLiveCareQRCodeValue = widget.pharmacyLiveCareQRCode;
Navigator.push(
- context,
- FadePage(
- page: PaymentMethod(
+ context,
+ FadePage(
+ page: PaymentMethod(
onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) {
setState(() {});
},
patientShare: num.parse(getERAppointmentFeesList.total!),
isFromAdvancePayment: widget.isPharmacyLiveCare,
- ))).then((value) {
+ ),
+ ),
+ ).then((value) {
if (value != null) {
selectedPaymentMethod = value[0];
print(value);
diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart
index 5eed62b2..e4a55d25 100644
--- a/lib/pages/login/confirm-login.dart
+++ b/lib/pages/login/confirm-login.dart
@@ -393,7 +393,7 @@ class _ConfirmLogin extends State {
var availableBiometrics;
try {
availableBiometrics = await auth.getAvailableBiometrics();
- print(availableBiometrics);
+ // print(availableBiometrics);
} on PlatformException catch (e) {
AppToast.showErrorToast(message: e.message!);
print(e);
@@ -1125,7 +1125,6 @@ class _ConfirmLogin extends State {
}
bool checkIfBiometricAvailable(BiometricType biometricType) {
- print(biometricType);
bool isAvailable = false;
if (_availableBiometrics != null) {
for (var i = 0; i < _availableBiometrics.length; i++) {
diff --git a/lib/pages/login/register-info.dart b/lib/pages/login/register-info.dart
index cbff3f9b..e3d2f020 100644
--- a/lib/pages/login/register-info.dart
+++ b/lib/pages/login/register-info.dart
@@ -455,10 +455,10 @@ class _RegisterInfo extends State {
this
.authService
.registerUser(request)
- .then((result) => {
- GifLoaderDialogUtils.hideDialog(context),
+ .then((result) async => {
if (result is String)
{
+ GifLoaderDialogUtils.hideDialog(context),
new ConfirmDialog(
context: context,
confirmMessage: result,
@@ -480,14 +480,14 @@ class _RegisterInfo extends State {
sharedPref.remove(FAMILY_FILE),
result.list.isFamily = false,
- sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""),
+ await sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""),
authenticatedUserObject.user = result.list,
projectViewModel.setPrivilege(privilegeList: res),
- sharedPref.setObject(MAIN_USER, result.list),
- sharedPref.setObject(USER_PROFILE, result.list),
+ await sharedPref.setObject(MAIN_USER, result.list),
+ await sharedPref.setObject(USER_PROFILE, result.list),
- sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID),
- sharedPref.setString(TOKEN, result.authenticationTokenID),
+ await sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID),
+ await sharedPref.setString(TOKEN, result.authenticationTokenID),
AppToast.showSuccessToast(message: TranslationBase.of(context).successRegister),
checkIfUserAgreedBefore(result),
projectViewModel.analytics.loginRegistration.registration_confirmation()
@@ -695,6 +695,7 @@ class _RegisterInfo extends State {
insertIMEI() async {
var selectedOption = await sharedPref.getInt(LAST_LOGIN);
authService.insertDeviceImei(selectedOption).then((value) => {goToHome()}).catchError((err) {
+ GifLoaderDialogUtils.hideDialog(context);
print(err);
});
}
@@ -705,45 +706,70 @@ class _RegisterInfo extends State {
projectViewModel.isLogin = true;
projectViewModel.user = authenticatedUserObject.user;
await authenticatedUserObject.getUser(getUser: true);
- int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2;
- appointmentRateViewModel.getIsLastAppointmentRatedList(languageID).then((value) {
- getToDoCount();
- GifLoaderDialogUtils.hideDialog(AppGlobal.context);
- if (appointmentRateViewModel.isHaveAppointmentNotRate) {
- Navigator.pushAndRemoveUntil(
+ getToDoCount();
+ GifLoaderDialogUtils.hideDialog(AppGlobal.context);
+ ConfirmDialog dialog = new ConfirmDialog(
+ context: context,
+ confirmMessage: TranslationBase.of(context).validInsurance,
+ okText: TranslationBase.of(context).yes,
+ cancelText: TranslationBase.of(context).no,
+ okFunction: () {
+ ConfirmDialog.closeAlertDialog(context);
+ Navigator.pushAndRemoveUntil(
context,
- FadePage(
- page: RateAppointmentDoctor(isFromRegistration: true),
- ),
- (r) => false);
- } else {
- ConfirmDialog dialog = new ConfirmDialog(
- context: context,
- confirmMessage: TranslationBase.of(context).validInsurance,
- okText: TranslationBase.of(context).yes,
- cancelText: TranslationBase.of(context).no,
- okFunction: () {
- ConfirmDialog.closeAlertDialog(context);
- Navigator.pushAndRemoveUntil(
- context,
- MaterialPageRoute(builder: (context) => LandingPage()),
+ MaterialPageRoute(builder: (context) => LandingPage()),
(Route route) => false,
- );
- Navigator.push(context, FadePage(page: InsuranceUpdate()));
- },
- cancelFunction: () {
- Navigator.pushAndRemoveUntil(
- context,
- MaterialPageRoute(builder: (context) => LandingPage()),
- (Route route) => false,
- );
- });
- dialog.showAlertDialog(context);
- }
- }).catchError((err) {
- print(err);
- //GifLoaderDialogUtils.hideDialog(context);
- });
+ );
+ Navigator.push(context, FadePage(page: InsuranceUpdate()));
+ },
+ cancelFunction: () {
+ Navigator.pushAndRemoveUntil(
+ context,
+ MaterialPageRoute(builder: (context) => LandingPage()),
+ (Route route) => false,
+ );
+ });
+ dialog.showAlertDialog(context);
+
+ // int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2;
+ // appointmentRateViewModel.getIsLastAppointmentRatedList(languageID).then((value) {
+ // getToDoCount();
+ // GifLoaderDialogUtils.hideDialog(AppGlobal.context);
+ // if (appointmentRateViewModel.isHaveAppointmentNotRate) {
+ // Navigator.pushAndRemoveUntil(
+ // context,
+ // FadePage(
+ // page: RateAppointmentDoctor(isFromRegistration: true),
+ // ),
+ // (r) => false);
+ // } else {
+ // ConfirmDialog dialog = new ConfirmDialog(
+ // context: context,
+ // confirmMessage: TranslationBase.of(context).validInsurance,
+ // okText: TranslationBase.of(context).yes,
+ // cancelText: TranslationBase.of(context).no,
+ // okFunction: () {
+ // ConfirmDialog.closeAlertDialog(context);
+ // Navigator.pushAndRemoveUntil(
+ // context,
+ // MaterialPageRoute(builder: (context) => LandingPage()),
+ // (Route route) => false,
+ // );
+ // Navigator.push(context, FadePage(page: InsuranceUpdate()));
+ // },
+ // cancelFunction: () {
+ // Navigator.pushAndRemoveUntil(
+ // context,
+ // MaterialPageRoute(builder: (context) => LandingPage()),
+ // (Route route) => false,
+ // );
+ // });
+ // dialog.showAlertDialog(context);
+ // }
+ // }).catchError((err) {
+ // print(err);
+ // //GifLoaderDialogUtils.hideDialog(context);
+ // });
// SMSOTP.showLoadingDialog(context, false),
}
diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart
index a010150d..2dd32163 100644
--- a/lib/pages/login/register.dart
+++ b/lib/pages/login/register.dart
@@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/analytics/flows/login_registration.dart';
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/config/size_config.dart';
+import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/models/Authentication/check_user_status_reponse.dart';
import 'package:diplomaticquarterapp/models/Authentication/check_user_status_req.dart';
@@ -25,6 +26,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart';
import 'package:intl/intl.dart' as intl;
+import 'package:provider/provider.dart';
class Register extends StatefulWidget {
final Function? changePageViewIndex;
@@ -297,8 +299,9 @@ class _Register extends State {
}
checkPatientForRegisteration(request) {
+ int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2;
GifLoaderDialogUtils.showMyDialog(context);
- this.authService.checkPatientForRegisteration(request).then((response) => {checkUserStatus(response, request)}).catchError((err) {
+ this.authService.checkPatientForRegisteration(request, languageID).then((response) => {checkUserStatus(response, request)}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
ConfirmDialog dialog = new ConfirmDialog(
context: context,
diff --git a/lib/pages/medical/smart_watch_health_data/syncHealthData.dart b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart
index e6ec5c9a..6d6fdf4f 100644
--- a/lib/pages/medical/smart_watch_health_data/syncHealthData.dart
+++ b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart
@@ -34,7 +34,7 @@ class _syncHealthDataButtonState extends State {
int MedCategoryID = 0;
- HealthFactory health = HealthFactory();
+ // HealthFactory health = HealthFactory();
List types = [HealthDataType.STEPS, HealthDataType.HEART_RATE, Platform.isAndroid ? HealthDataType.DISTANCE_DELTA : HealthDataType.DISTANCE_WALKING_RUNNING];
@override
@@ -48,29 +48,29 @@ class _syncHealthDataButtonState extends State {
}
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 {
DateTime startDate = DateTime.now().subtract(new Duration(days: 30));
try {
- List healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types);
- _healthDataList.addAll(healthData);
+ // List 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) {
diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart
index 98d49db1..2d75be28 100644
--- a/lib/services/appointment_services/GetDoctorsList.dart
+++ b/lib/services/appointment_services/GetDoctorsList.dart
@@ -334,6 +334,58 @@ class DoctorsListService extends BaseService {
return Future.value(localRes);
}
+ Future