Merge pull request 'Main_App_Replacement' (#391) from Main_App_Replacement into master

Reviewed-on: https://34.17.182.140/Haroon6138/HMG_Patient_App_New/pulls/391
master
Haroon6138 1 week ago
commit 33a7ed34b0

@ -1 +1,74 @@
{"agcgw":{"url":"connect-drcn.dbankcloud.cn","backurl":"connect-drcn.hispace.hicloud.com","websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn","websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com"},"agcgw_all":{"SG":"connect-dra.dbankcloud.cn","SG_back":"connect-dra.hispace.hicloud.com","CN":"connect-drcn.dbankcloud.cn","CN_back":"connect-drcn.hispace.hicloud.com","RU":"connect-drru.hispace.dbankcloud.ru","RU_back":"connect-drru.hispace.dbankcloud.cn","DE":"connect-dre.dbankcloud.cn","DE_back":"connect-dre.hispace.hicloud.com"},"websocketgw_all":{"SG":"connect-ws-dra.hispace.dbankcloud.cn","SG_back":"connect-ws-dra.hispace.dbankcloud.com","CN":"connect-ws-drcn.hispace.dbankcloud.cn","CN_back":"connect-ws-drcn.hispace.dbankcloud.com","RU":"connect-ws-drru.hispace.dbankcloud.ru","RU_back":"connect-ws-drru.hispace.dbankcloud.cn","DE":"connect-ws-dre.hispace.dbankcloud.cn","DE_back":"connect-ws-dre.hispace.dbankcloud.com"},"client":{"cp_id":"2640966000002322881","product_id":"736430079244816567","client_id":"563735388191982656","client_secret":"650C7C799812AFFD53A10C7756CF05FB9F215A7E49032ABA8EBF3E14B77535CF","project_id":"736430079244816567","app_id":"116912301","api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI","package_name":"com.cloudsolutions.HMGPatientApp"},"oauth_client":{"client_id":"116912301","client_type":1},"app_info":{"app_id":"116912301","package_name":"com.cloudsolutions.HMGPatientApp"},"service":{"analytics":{"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn","collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com","collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn","resource_id":"p1","channel_id":""},"ml":{"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"},"cloudstorage":{"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg":"https://ops-dra.agcstorage.link","storage_url_de":"https://ops-dre.agcstorage.link","storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia","storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu","storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn"},"search":{"url":"https://search-drcn.cloud.huawei.com"},"edukit":{"edu_url":"edukit.cloud.huawei.com.cn","dh_url":"edukit.cloud.huawei.com.cn"}},"region":"CN","configuration_version":"3.0","appInfos":[{"package_name":"com.cloudsolutions.HMGPatientApp","client":{"app_id":"116912301"},"app_info":{"package_name":"com.cloudsolutions.HMGPatientApp","app_id":"116912301"},"oauth_client":{"client_type":1,"client_id":"116912301"}},{"package_name":"com.ejada.hmg","client":{"app_id":"102857389"},"app_info":{"package_name":"com.ejada.hmg","app_id":"102857389"},"oauth_client":{"client_type":1,"client_id":"102857389"}}]}
{
"agcgw":{
"backurl":"connect-drcn.hispace.hicloud.com",
"url":"connect-drcn.dbankcloud.cn",
"websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com",
"websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn"
},
"agcgw_all":{
"CN":"connect-drcn.dbankcloud.cn",
"CN_back":"connect-drcn.hispace.hicloud.com",
"DE":"connect-dre.dbankcloud.cn",
"DE_back":"connect-dre.hispace.hicloud.com",
"RU":"connect-drru.dbankcloud.cn",
"RU_back":"connect-drru.hispace.hicloud.com",
"SG":"connect-dra.dbankcloud.cn",
"SG_back":"connect-dra.hispace.hicloud.com"
},
"client":{
"cp_id":"2640966000002322881",
"product_id":"736430079244816567",
"client_id":"563735388191982656",
"client_secret":"650C7C799812AFFD53A10C7756CF05FB9F215A7E49032ABA8EBF3E14B77535CF",
"project_id":"736430079244816567",
"app_id":"102857389",
"api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI",
"package_name":"com.ejada.hmg"
},
"oauth_client":{
"client_id":"102857389",
"client_type":1
},
"app_info":{
"app_id":"102857389",
"package_name":"com.ejada.hmg"
},
"service":{
"analytics":{
"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
"collector_url_ru":"datacollector-drru.dt.hicloud.com,datacollector-drru.dt.dbankcloud.cn",
"collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn",
"collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
"resource_id":"p1",
"channel_id":""
},
"search":{
"url":"https://search-drcn.cloud.huawei.com"
},
"cloudstorage":{
"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn"
},
"ml":{
"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"
}
},
"region":"CN",
"configuration_version":"3.0",
"appInfos":[
{
"package_name":"com.ejada.hmg",
"client":{
"app_id":"102857389"
},
"app_info":{
"package_name":"com.ejada.hmg",
"app_id":"102857389"
},
"oauth_client":{
"client_type":1,
"client_id":"102857389"
}
}
]
}

@ -19,7 +19,8 @@ if (keystorePropertiesFile.exists()) {
}
android {
namespace = "com.cloudsolutions.HMGPatientApp"
// namespace = "com.cloudsolutions.HMGPatientApp"
namespace = "com.ejada.hmg"
compileSdk = 36
// Using NDK 26 for better compatibility with Zoom SDK native libraries
// ndkVersion = "27.0.12077973"
@ -33,7 +34,8 @@ android {
}
defaultConfig {
applicationId = "com.cloudsolutions.HMGPatientApp"
// applicationId = "com.cloudsolutions.HMGPatientApp"
applicationId = "com.ejada.hmg"
// minSdk = 24
minSdk = 29
targetSdk = 36
@ -141,6 +143,10 @@ flutter {
source = "../.."
}
configurations.all {
exclude(group = "org.jetbrains.kotlin", module = "kotlin-android-extensions-runtime")
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.20")
implementation("com.google.firebase:firebase-messaging:24.1.2")

@ -3,45 +3,9 @@
"project_number": "815750722565",
"firebase_url": "https://api-project-815750722565.firebaseio.com",
"project_id": "api-project-815750722565",
"storage_bucket": "api-project-815750722565.firebasestorage.app"
"storage_bucket": "api-project-815750722565.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:fa20b3a2401e08633c186c",
"android_client_info": {
"package_name": "com.cloudsolutions.HMGPatientApp"
}
},
"oauth_client": [
{
"client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.void.demo"
}
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063",

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.cloudsolutions.HMGPatientApp">
package="com.ejada.hmg">
<!--
io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
@ -133,7 +133,7 @@
android:name=".Application"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher_local"
android:label="Dr. Alhabib Beta"
android:label="Dr. Alhabib"
android:screenOrientation="sensorPortrait"
android:showOnLockScreen="true"
android:usesCleartextTraffic="true"
@ -267,6 +267,9 @@
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng" />
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="appid=116912301" />
<!--
Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java

@ -1,5 +1,5 @@
//package com.cloud.diplomaticquarterapp
package com.cloudsolutions.HMGPatientApp
package com.ejada.hmg
import io.flutter.app.FlutterApplication

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp
package com.ejada.hmg
import android.content.Intent
import android.content.pm.PackageManager
@ -7,7 +7,8 @@ import android.util.Log
import android.view.WindowManager
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi
import com.cloudsolutions.HMGPatientApp.watch.samsung_watch.SamsungWatch
import com.ejada.hmg.watch.samsung_watch.SamsungWatch
import com.ejada.hmg.watch.huawei.HuaweiWatch
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
@ -24,6 +25,7 @@ class MainActivity: FlutterFragmentActivity() {
PenguinInPlatformBridge(flutterEngine, this).create()
SamsungWatch(flutterEngine, this)
HuaweiWatch(flutterEngine, this)
}
override fun onRequestPermissionsResult(

@ -1,14 +1,14 @@
package com.cloudsolutions.HMGPatientApp
package com.ejada.hmg
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.cloudsolutions.HMGPatientApp.penguin.PenguinView
import com.ejada.hmg.penguin.PenguinView
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import com.cloudsolutions.HMGPatientApp.PermissionManager.HostNotificationPermissionManager
import com.cloudsolutions.HMGPatientApp.PermissionManager.HostBgLocationManager
import com.cloudsolutions.HMGPatientApp.PermissionManager.HostGpsStateManager
import com.ejada.hmg.PermissionManager.HostNotificationPermissionManager
import com.ejada.hmg.PermissionManager.HostBgLocationManager
import com.ejada.hmg.PermissionManager.HostGpsStateManager
import io.flutter.plugin.common.MethodChannel
class PenguinInPlatformBridge(

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.PermissionManager;
package com.ejada.hmg.PermissionManager;
import android.content.Context;
import android.content.SharedPreferences;

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.PermissionManager;
package com.ejada.hmg.PermissionManager;
import android.Manifest;
import android.app.Activity;

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.PermissionManager;
package com.ejada.hmg.PermissionManager;
import android.Manifest;
import android.app.Activity;

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.PermissionManager;
package com.ejada.hmg.PermissionManager;
import android.app.Activity;
import android.content.pm.PackageManager;

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.PermissionManager
package com.ejada.hmg.PermissionManager
import android.Manifest

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.PermissionManager
package com.ejada.hmg.PermissionManager
import android.app.Activity
import android.content.Context

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.PermissionManager
package com.ejada.hmg.PermissionManager
// PermissionResultReceiver.kt
import android.content.BroadcastReceiver

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.penguin
package com.ejada.hmg.penguin
enum class PenguinMethod {
// initializePenguin("initializePenguin"),

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.penguin
package com.ejada.hmg.penguin
import android.content.Context
import com.google.gson.Gson

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.penguin
package com.ejada.hmg.penguin
import android.app.Activity
import android.content.Context
@ -12,10 +12,10 @@ import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.cloudsolutions.HMGPatientApp.PermissionManager.PermissionManager
import com.cloudsolutions.HMGPatientApp.PermissionManager.PermissionResultReceiver
import com.cloudsolutions.HMGPatientApp.MainActivity
import com.cloudsolutions.HMGPatientApp.PermissionManager.PermissionHelper
import com.ejada.hmg.PermissionManager.PermissionManager
import com.ejada.hmg.PermissionManager.PermissionResultReceiver
import com.ejada.hmg.MainActivity
import com.ejada.hmg.PermissionManager.PermissionHelper
import com.peng.pennavmap.PlugAndPlayConfiguration
import com.peng.pennavmap.PlugAndPlaySDK
import com.peng.pennavmap.enums.InitializationErrorType

@ -0,0 +1,87 @@
package com.ejada.hmg.watch.huawei
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.ejada.hmg.watch.samsung_watch.model.Vitals
import com.huawei.hms.adapter.AvailableAdapter
import com.huawei.hms.adapter.internal.AvailableCode
import com.samsung.android.sdk.health.data.HealthDataStore
import com.samsung.android.sdk.health.data.permission.AccessType
import com.samsung.android.sdk.health.data.permission.Permission
import com.samsung.android.sdk.health.data.request.DataType
import com.samsung.android.sdk.health.data.request.DataTypes
import com.samsung.android.sdk.health.data.request.LocalTimeFilter
import com.samsung.android.sdk.health.data.request.LocalTimeGroup
import com.samsung.android.sdk.health.data.request.LocalTimeGroupUnit
import com.samsung.android.sdk.health.data.request.Ordering
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import java.time.LocalDateTime
import java.time.LocalTime
import com.huawei.hms.hihealth.HuaweiHiHealth
import com.ejada.hmg.MainActivity
class HuaweiWatch(
private var flutterEngine: FlutterEngine,
private var mainActivity: MainActivity
) {
private lateinit var channel: MethodChannel
private lateinit var dataStore: HealthDataStore
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val TAG = "HuaweiWatch"
private lateinit var vitals: MutableMap<String, List<Vitals>>
companion object {
private const val CHANNEL = "huawei_watch"
}
init{
create()
}
@RequiresApi(Build.VERSION_CODES.O)
fun create() {
Log.d(TAG, "create: is called")
// openTok = OpenTok(mainActivity, flutterEngine)
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
when (call.method) {
"init" -> {
init(result)
}
else -> {
result.notImplemented()
}
}
}
}
fun init(result: MethodChannel.Result) {
Log.d(TAG, "onMethodCall: init called")
val mSettingController = HuaweiHiHealth.getSettingController(mainActivity);
val availableAdapter = AvailableAdapter(60400312)
val results= availableAdapter.isHuaweiMobileServicesAvailable(mainActivity) // context indicates a context object.
if (results != AvailableCode.SUCCESS) {
availableAdapter.startResolution(mainActivity, object : AvailableAdapter.AvailableCallBack {
override fun onComplete(result: Int) {
Log.d(TAG, "onComplete result: " + result)
}
})
}
result.success("init success")
}
}

@ -1,12 +1,12 @@
package com.cloudsolutions.HMGPatientApp.watch.samsung_watch
package com.ejada.hmg.watch.samsung_watch
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.cloudsolutions.HMGPatientApp.MainActivity
import com.cloudsolutions.HMGPatientApp.watch.samsung_watch.model.Vitals
import com.ejada.hmg.MainActivity
import com.ejada.hmg.watch.samsung_watch.model.Vitals
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import com.samsung.android.sdk.health.data.HealthDataService
@ -75,12 +75,22 @@ class SamsungWatch(
Permission.of(DataTypes.ACTIVITY_SUMMARY, AccessType.READ),
Permission.of(DataTypes.SLEEP, AccessType.READ),
Permission.of(DataTypes.BODY_TEMPERATURE, AccessType.READ),
Permission.of(DataTypes.EXERCISE, AccessType.READ),
// Permission.of(DataTypes.EXERCISE, AccessType.READ),
// Permission.of(DataTypes.SKIN_TEMPERATURE, AccessType.READ),
// Permission.of(DataTypes.NUTRITION, AccessType.READ),
)
scope.launch {
val typesToTest = listOf(
DataTypes.HEART_RATE,
DataTypes.STEPS,
DataTypes.BLOOD_OXYGEN,
DataTypes.ACTIVITY_SUMMARY,
DataTypes.SLEEP,
DataTypes.BODY_TEMPERATURE,
// DataTypes.EXERCISE
)
scope.launch(Dispatchers.IO) {
try {
var granted = dataStore.getGrantedPermissions(permSet)
@ -89,6 +99,17 @@ class SamsungWatch(
return@launch
}
// for (type in typesToTest) {
// try {
// val result = dataStore.requestPermissions(
// setOf(Permission.of(type, AccessType.READ)),
// mainActivity
// )
// Log.d("PermCheck", "OK: $type and the result is $result")
// } catch (e: Exception) {
// Log.e("PermCheck", "FAILED: $type -> ${e.message}")
// }
// }
granted = dataStore.requestPermissions(permSet, mainActivity)
if (granted.containsAll(permSet)) {
@ -111,7 +132,7 @@ class SamsungWatch(
.setOrdering(Ordering.DESC)
.build()
scope.launch {
scope.launch(Dispatchers.IO) {
val heartRateList = dataStore.readData(readRequest).dataList
processHeartVital(heartRateList)
Log.d("TAG"," the data is ${vitals}")
@ -128,7 +149,7 @@ class SamsungWatch(
.setLocalTimeFilter(localTimeFilter)
.setOrdering(Ordering.ASC)
.build()
scope.launch {
scope.launch(Dispatchers.IO) {
val sleepData = dataStore.readData(readRequest).dataList
processSleepVital(sleepData)
print("the data is $vitals")
@ -147,7 +168,7 @@ class SamsungWatch(
.setOrdering(Ordering.ASC)
.build()
scope.launch {
scope.launch(Dispatchers.IO) {
val steps = dataStore.aggregateData(aggregateRequest)
processStepsCount(steps)
print("the data is $vitals")
@ -166,7 +187,7 @@ class SamsungWatch(
.setOrdering(Ordering.DESC)
.build()
scope.launch {
scope.launch(Dispatchers.IO) {
val activityResult = dataStore.aggregateData(readRequest).dataList
processActivity(activityResult)
Log.d("TAG"," the data is ${vitals}")
@ -201,7 +222,7 @@ class SamsungWatch(
.setOrdering(Ordering.DESC)
.build()
scope.launch {
scope.launch(Dispatchers.IO) {
val bloodOxygenList = dataStore.readData(readRequest).dataList
processBloodOxygen(bloodOxygenList)
Log.d("TAG"," the data is ${vitals}")
@ -219,7 +240,7 @@ class SamsungWatch(
.setOrdering(Ordering.DESC)
.build()
scope.launch {
scope.launch(Dispatchers.IO) {
val bodyTemperatureList = dataStore.readData(readRequest).dataList
processBodyTemperature(bodyTemperatureList)
Log.d("TAG"," the data is ${vitals}")
@ -237,7 +258,7 @@ class SamsungWatch(
.setOrdering(Ordering.DESC)
.build()
scope.launch {
scope.launch(Dispatchers.IO) {
val activityResult = dataStore.aggregateData(readRequest).dataList
processDistance(activityResult)
Log.d("TAG"," the data is ${vitals}")

@ -1,4 +1,4 @@
package com.cloudsolutions.HMGPatientApp.watch.samsung_watch.model
package com.ejada.hmg.watch.samsung_watch.model
data class Vitals(
var value : String = "",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.cloudsolutions.HMGPatientApp">
package="com.cloudsolutions.hmg">
<!--
io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.

@ -54,12 +54,24 @@ allprojects {
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "21"
// kotlinOptions {
// jvmTarget = "21"
// }
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
}
}
subprojects {
project.buildscript.repositories {
google()
mavenCentral()
}
project.repositories {
google()
mavenCentral()
}
afterEvaluate {
if (project.hasProperty("android")) {
project.extensions.findByName("android")?.let { androidExt ->
@ -83,8 +95,11 @@ allprojects {
targetCompatibility = JavaVersion.VERSION_21.toString()
}
project.tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "21"
// kotlinOptions {
// jvmTarget = "21"
// }
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
}
}
}

File diff suppressed because one or more lines are too long

@ -3,9 +3,16 @@ android.enableR8=true
android.enableR8.fullMode=true
android.enableJetifier=true
android.useDeprecatedNdk=true
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:MaxMetaspaceSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
android.useAndroidX=true
android.enableImpeller=false
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
# Enabled parallel sync for Gradle 9.4+
org.gradle.tooling.parallel=true

@ -3,4 +3,4 @@ distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-all.zip

@ -16,14 +16,34 @@ pluginManagement {
}
}
dependencyResolutionManagement {
// repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
repositories {
google()
mavenCentral()
maven {
url = uri("https://storage.googleapis.com/download.flutter.io")
}
// Huawei HMS repo
maven {
url = uri("https://developer.huawei.com/repo/")
}
// Mapbox repo
maven {
url = uri("https://api.mapbox.com/downloads/v2/releases/maven")
}
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
// id("com.android.application") version "8.9.3" apply false
// START: FlutterFire Configuration
id("com.google.gms.google-services") version("4.4.1") apply false
// END: FlutterFire Configuration
id("com.android.application") version "8.9.3" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
id("com.android.application") version "8.11.1" apply false
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
}
include(":app")

@ -1533,6 +1533,7 @@
"vatPercent": "ضريبة القيمة المضافة (15%)",
"proceedToPayment": "المتابعة للدفع",
"supportedSmartWatches": "كيف تعمل؟",
"smartwatchHowItWorks": "كيف تعمل الساعة الذكية",
"pleaseMakeSureSamsungWatchConnected": "يرجى التأكد من أن ساعة Samsung الخاصة بك متصلة بهاتفك، ومتزامنة ومحدثة بشكل نشط.",
"beforeSyncingDataFollowInstructions": "قبل مزامنة البيانات، يرجى التأكد من اتباع التعليمات بشكل صحيح.",
"viewWatchInstructions": "عرض تعليمات الساعة",
@ -1544,6 +1545,18 @@
"seconds": "ثواني",
"secs": "ثواني",
"noAllergiesDataFound": "لم يتم العثور على بيانات الحساسية...",
"allHealthData": "جميع البيانات الصحية",
"activityCalories": "سعرات النشاط",
"activityCaloriesDescription": "توفر حلقات النشاط مرجعًا بصريًا سريعًا لمدى نشاطك خلال كل يوم.",
"steps": "الخطوات",
"distanceCovered": "المسافة المقطوعة",
"distanceCoveredDescription": "المسافة المقطوعة على مدار اليوم",
"sleepScore": "مؤشر النوم",
"sleepScoreDescription": "يتتبع هذا عدد ساعات نومك خلال اليوم",
"bloodOxygen": "أكسجين الدم",
"bloodOxygenTrackingDescription": "يتتبع هذا مستوى أكسجين الدم لمراقبة السجل الصحي وتحديثه",
"bodyTemperature": "درجة حرارة الجسم",
"bodyTemperatureTrackingDescription": "يتتبع هذا درجة حرارة الجسم لمراقبة السجل الصحي وتحديثه",
"heartRateDescription": "معدل ضربات قلبك يشير إلى عدد المرات التي ينبض فيها قلبك في الدقيقة",
"bloodOxygenDescription": "مستوى الأكسجين في الدم يشير إلى كمية الأكسجين التي تحملها خلايا الدم الحمراء",
"stepsDescription": "عدد الخطوات المتخذة على مدار اليوم",

@ -1526,6 +1526,7 @@
"vatPercent": "VAT (15%)",
"proceedToPayment": "Proceed to Payment",
"supportedSmartWatches": "Supported Smart Watches",
"smartwatchHowItWorks": "How does it work",
"pleaseMakeSureSamsungWatchConnected": "Please make sure that your Samsung Watch is connected to your Phone, is actively synced & updated.",
"beforeSyncingDataFollowInstructions": "Before syncing data, please make sure that you have followed the instructions properly.",
"viewWatchInstructions": "View watch instructions",
@ -1537,6 +1538,18 @@
"seconds": "Seconds",
"secs": "Secs",
"noAllergiesDataFound": "No allergies data found...",
"allHealthData": "All Health Data",
"activityCalories": "Activity Calories",
"activityCaloriesDescription": "Activity rings give you a quick visual reference of how active you are each day.",
"steps": "Steps",
"distanceCovered": "Distance Covered",
"distanceCoveredDescription": "Distance covered throughout the day",
"sleepScore": "Sleep Score",
"sleepScoreDescription": "This keeps track of how many hours you sleep in a day",
"bloodOxygen": "Blood Oxygen",
"bloodOxygenTrackingDescription": "This tracks your blood oxygen to monitor and update your health history",
"bodyTemperature": "Body Temperature",
"bodyTemperatureTrackingDescription": "This tracks your body temperature to monitor and update your health history",
"heartRateDescription": "Your heart rate indicates how many times your heart beats per minute",
"bloodOxygenDescription": "Blood oxygen level indicates how much oxygen your red blood cells are carrying",
"stepsDescription": "Number of steps taken throughout the day",

@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt</string>
<key>ANDROID_CLIENT_ID</key>
<string>815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com</string>
<key>API_KEY</key>
@ -11,11 +15,11 @@
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.cloudsolutions.HMGPatientApp</string>
<string>com.HMG.HMG-Smartphone</string>
<key>PROJECT_ID</key>
<string>api-project-815750722565</string>
<key>STORAGE_BUCKET</key>
<string>api-project-815750722565.firebasestorage.app</string>
<string>api-project-815750722565.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
@ -27,7 +31,7 @@
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:815750722565:ios:34ec03c09e02e21f3c186c</string>
<string>1:815750722565:ios:328ec247a81a2ca23c186c</string>
<key>DATABASE_URL</key>
<string>https://api-project-815750722565.firebaseio.com</string>
</dict>

@ -3,15 +3,15 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 60;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
37D27FAF2C38AC83B852680C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
478CFA942E638C8E0064F3D7 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */; };
5D5A1F80D389375644C4D0DC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56E413AB2A2E9765749CACD1 /* Pods_Runner.framework */; };
61243B492EC5FA3700D46FA0 /* PenguinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */; };
61243B4C2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */; };
61243B502EC5FA3700D46FA0 /* PenguinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B452EC5FA3700D46FA0 /* PenguinView.swift */; };
@ -26,10 +26,10 @@
76B1D2542F91BF8000DBBD1B /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D24F2F91BF8000DBBD1B /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
76B1D2552F91BF8000DBBD1B /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D2502F91BF8000DBBD1B /* PenNavUI.xcframework */; };
76B1D2562F91BF8000DBBD1B /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D2502F91BF8000DBBD1B /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
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 */; };
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -56,18 +56,27 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
76B714E4300E58B2004DE37A /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
05E1B2A0E6844572ADA81174 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3EAE1F31D8D0AA94CA6C11EB /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
478CFA952E6E20A60064F3D7 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
56E413AB2A2E9765749CACD1 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = "<group>"; };
61243B422EC5FA3700D46FA0 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = "<group>"; };
61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = "<group>"; };
@ -81,8 +90,10 @@
76B1D24E2F91BF8000DBBD1B /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = "<group>"; };
76B1D24F2F91BF8000DBBD1B /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenguinINRenderer.xcframework; path = Frameworks/PenguinINRenderer.xcframework; sourceTree = "<group>"; };
76B1D2502F91BF8000DBBD1B /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = "<group>"; };
76B714CF300E58B1004DE37A /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
76B714D1300E58B1004DE37A /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7BEF44ABFEF585D64D3F266C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -90,8 +101,9 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
BCE5BC40273DCC009E2FACB7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
C6416282AC56269448D7DA99 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
C6FD350374F47AFA34911C58 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -103,7 +115,7 @@
76B1D2512F91BF8000DBBD1B /* Penguin.xcframework in Frameworks */,
76B1D2552F91BF8000DBBD1B /* PenNavUI.xcframework in Frameworks */,
76B1D2532F91BF8000DBBD1B /* PenguinINRenderer.xcframework in Frameworks */,
37D27FAF2C38AC83B852680C /* Pods_Runner.framework in Frameworks */,
5D5A1F80D389375644C4D0DC /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -144,7 +156,9 @@
76B1D24E2F91BF8000DBBD1B /* Penguin.xcframework */,
76B1D24F2F91BF8000DBBD1B /* PenguinINRenderer.xcframework */,
76B1D2502F91BF8000DBBD1B /* PenNavUI.xcframework */,
A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */,
76B714CF300E58B1004DE37A /* WidgetKit.framework */,
76B714D1300E58B1004DE37A /* SwiftUI.framework */,
56E413AB2A2E9765749CACD1 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -152,9 +166,9 @@
79DD2093A1D9674C94359FC8 /* Pods */ = {
isa = PBXGroup;
children = (
3EAE1F31D8D0AA94CA6C11EB /* Pods-Runner.debug.xcconfig */,
05E1B2A0E6844572ADA81174 /* Pods-Runner.release.xcconfig */,
7BEF44ABFEF585D64D3F266C /* Pods-Runner.profile.xcconfig */,
BCE5BC40273DCC009E2FACB7 /* Pods-Runner.debug.xcconfig */,
C6416282AC56269448D7DA99 /* Pods-Runner.release.xcconfig */,
C6FD350374F47AFA34911C58 /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@ -234,27 +248,28 @@
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
packageProductDependencies = (
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
EA10FC42B68E41E75A052FAA /* [CP] Check Pods Manifest.lock */,
511FFA76807DE636962DBF91 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
765A5A922F35CD8B0003FF7D /* Embed Frameworks */,
76B714E4300E58B2004DE37A /* Embed Foundation Extensions */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
5D78F615DF2D966539B34DE2 /* [CP] Embed Pods Frameworks */,
4AA9AE39AD56A64A1F16E548 /* [CP] Copy Pods Resources */,
C7E5B2C65EE0A4D64ECC826B /* [CP] Embed Pods Frameworks */,
DF2C78ED8C8F648520DF8C43 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
packageProductDependencies = (
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
@ -263,12 +278,10 @@
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
);
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 2610;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
@ -291,6 +304,9 @@
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
);
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
@ -339,77 +355,77 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
};
4AA9AE39AD56A64A1F16E548 /* [CP] Copy Pods Resources */ = {
511FFA76807DE636962DBF91 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
5D78F615DF2D966539B34DE2 /* [CP] Embed Pods Frameworks */ = {
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
C7E5B2C65EE0A4D64ECC826B /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "Run Script";
outputPaths = (
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
EA10FC42B68E41E75A052FAA /* [CP] Check Pods Manifest.lock */ = {
DF2C78ED8C8F648520DF8C43 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@ -511,7 +527,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@ -539,8 +555,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.0.12;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.HMGPatientApp;
MARKETING_VERSION = 4.6.044;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -645,7 +661,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -696,7 +712,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@ -726,8 +742,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.0.12;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.HMGPatientApp;
MARKETING_VERSION = 4.6.044;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -756,8 +772,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.0.12;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.HMGPatientApp;
MARKETING_VERSION = 4.6.044;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -800,12 +816,14 @@
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
isa = XCSwiftPackageProductDependency;

@ -0,0 +1,194 @@
{
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
"version" : "1.2024072200.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "3e33dd27dd4c69bd81c7c81fe61d8ccf58846902",
"version" : "11.3.1"
}
},
{
"identity" : "dkcamera",
"kind" : "remoteSourceControl",
"location" : "https://github.com/zhangao0086/DKCamera",
"state" : {
"branch" : "master",
"revision" : "5c691d11014b910aff69f960475d70e65d9dcc96"
}
},
{
"identity" : "dkimagepickercontroller",
"kind" : "remoteSourceControl",
"location" : "https://github.com/zhangao0086/DKImagePickerController",
"state" : {
"branch" : "4.3.9",
"revision" : "0bdfeacefa308545adde07bef86e349186335915"
}
},
{
"identity" : "dkphotogallery",
"kind" : "remoteSourceControl",
"location" : "https://github.com/zhangao0086/DKPhotoGallery",
"state" : {
"branch" : "master",
"revision" : "311c1bc7a94f1538f82773a79c84374b12a2ef3d"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "fdc352fabaf5916e7faa1f96ad02b1957e93e5a5",
"version" : "11.15.0"
}
},
{
"identity" : "flutterfire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/flutterfire",
"state" : {
"revision" : "dadb0fd27bc9afe4dee4f23326a4a9ba238258ac",
"version" : "3.15.2-firebase-core-swift"
}
},
{
"identity" : "google-ads-on-device-conversion-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/googleads/google-ads-on-device-conversion-ios-sdk",
"state" : {
"revision" : "a2d0f1f1666de591eb1a811f40b1706f5c63a2ed",
"version" : "2.3.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "45ce435e9406d3c674dd249a042b932bee006f60",
"version" : "11.15.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "ba3358d3c3dbae8ef230b58a46b97ad65e84e974",
"version" : "10.1.1"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "9f183ae842be978784f2963a343682e0c46d8fb3",
"version" : "8.1.2"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "75b31c842f664a0f46a2e590a570e370249fd8f6",
"version" : "1.69.1"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "c756a29784521063b6a1202907e2cc47f41b667c",
"version" : "4.5.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
"version" : "101.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "3851d94a41890dea16dc3db34caf60e585cb4163",
"version" : "2.30910.1"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "f4a19a3c313dc2616c70bb49d29a799fb16be837",
"version" : "2.4.1"
}
},
{
"identity" : "sdwebimage",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SDWebImage/SDWebImage",
"state" : {
"revision" : "2de3a496eaf6df9a1312862adcfd54acd73c39c0",
"version" : "5.21.7"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "55d7a1cc5666b85c13464aea1c4b4a90feccb4c8",
"version" : "1.38.1"
}
},
{
"identity" : "swiftygif",
"kind" : "remoteSourceControl",
"location" : "https://github.com/kirualex/SwiftyGif.git",
"state" : {
"revision" : "4430cbc148baa3907651d40562d96325426f409a",
"version" : "5.4.5"
}
},
{
"identity" : "tocropviewcontroller",
"kind" : "remoteSourceControl",
"location" : "https://github.com/TimOliver/TOCropViewController",
"state" : {
"revision" : "d4a6d8100f4b886fdbc8ae399bf144ff3e9afb7e",
"version" : "2.8.0"
}
}
],
"version" : 2
}

@ -0,0 +1,194 @@
{
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
"version" : "1.2024072200.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "3e33dd27dd4c69bd81c7c81fe61d8ccf58846902",
"version" : "11.3.1"
}
},
{
"identity" : "dkcamera",
"kind" : "remoteSourceControl",
"location" : "https://github.com/zhangao0086/DKCamera",
"state" : {
"branch" : "master",
"revision" : "5c691d11014b910aff69f960475d70e65d9dcc96"
}
},
{
"identity" : "dkimagepickercontroller",
"kind" : "remoteSourceControl",
"location" : "https://github.com/zhangao0086/DKImagePickerController",
"state" : {
"branch" : "4.3.9",
"revision" : "0bdfeacefa308545adde07bef86e349186335915"
}
},
{
"identity" : "dkphotogallery",
"kind" : "remoteSourceControl",
"location" : "https://github.com/zhangao0086/DKPhotoGallery",
"state" : {
"branch" : "master",
"revision" : "311c1bc7a94f1538f82773a79c84374b12a2ef3d"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "fdc352fabaf5916e7faa1f96ad02b1957e93e5a5",
"version" : "11.15.0"
}
},
{
"identity" : "flutterfire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/flutterfire",
"state" : {
"revision" : "dadb0fd27bc9afe4dee4f23326a4a9ba238258ac",
"version" : "3.15.2-firebase-core-swift"
}
},
{
"identity" : "google-ads-on-device-conversion-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/googleads/google-ads-on-device-conversion-ios-sdk",
"state" : {
"revision" : "a2d0f1f1666de591eb1a811f40b1706f5c63a2ed",
"version" : "2.3.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "45ce435e9406d3c674dd249a042b932bee006f60",
"version" : "11.15.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "ba3358d3c3dbae8ef230b58a46b97ad65e84e974",
"version" : "10.1.1"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "9f183ae842be978784f2963a343682e0c46d8fb3",
"version" : "8.1.2"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "75b31c842f664a0f46a2e590a570e370249fd8f6",
"version" : "1.69.1"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "c756a29784521063b6a1202907e2cc47f41b667c",
"version" : "4.5.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
"version" : "101.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "3851d94a41890dea16dc3db34caf60e585cb4163",
"version" : "2.30910.1"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "f4a19a3c313dc2616c70bb49d29a799fb16be837",
"version" : "2.4.1"
}
},
{
"identity" : "sdwebimage",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SDWebImage/SDWebImage",
"state" : {
"revision" : "2de3a496eaf6df9a1312862adcfd54acd73c39c0",
"version" : "5.21.7"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "55d7a1cc5666b85c13464aea1c4b4a90feccb4c8",
"version" : "1.38.1"
}
},
{
"identity" : "swiftygif",
"kind" : "remoteSourceControl",
"location" : "https://github.com/kirualex/SwiftyGif.git",
"state" : {
"revision" : "4430cbc148baa3907651d40562d96325426f409a",
"version" : "5.4.5"
}
},
{
"identity" : "tocropviewcontroller",
"kind" : "remoteSourceControl",
"location" : "https://github.com/TimOliver/TOCropViewController",
"state" : {
"revision" : "d4a6d8100f4b886fdbc8ae399bf144ff3e9afb7e",
"version" : "2.8.0"
}
}
],
"version" : 2
}

@ -4,22 +4,58 @@ import FirebaseCore
import FirebaseMessaging
import GoogleMaps
@main
@objc class AppDelegate: FlutterAppDelegate {
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
func didInitializeImplicitFlutterEngine(_ engineBridge: any FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
// GMSServices.provideAPIKey("AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng")
// FirebaseApp.configure()
// initializePlatformChannels()
}
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng")
FirebaseApp.configure()
// FirebaseApp.configure()
initializePlatformChannels()
GeneratedPluginRegistrant.register(with: self)
// GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func initializePlatformChannels(){
if let mainViewController = window?.rootViewController as? FlutterViewController{ // platform initialization suppose to be in foreground
HMGPenguinInPlatformBridge.initialize(flutterViewController: mainViewController)
}
}
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
// 1. Try accessing window via AppDelegate (legacy/single-window setup)
var controller = self.window?.rootViewController as? FlutterViewController
// 2. Fallback to UIWindowScene active window (modern iOS architecture)
if controller == nil {
controller = UIApplication.shared.connectedScenes
.compactMap { $0 as? UIWindowScene }
.flatMap { $0.windows }
.first(where: { $0.isKeyWindow })?
.rootViewController as? FlutterViewController
}
// 3. Perform initialization once FlutterViewController is available
if let mainViewController = controller {
HMGPenguinInPlatformBridge.initialize(flutterViewController: mainViewController)
} else {
print("⚠️ FlutterViewController not ready yet for initializePlatformChannels.")
}
}
// if let mainViewController = window?.rootViewController as? FlutterViewController{ // platform initialization suppose to be in foreground
// HMGPenguinInPlatformBridge.initialize(flutterViewController: mainViewController)
// }
}
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){
// Messaging.messaging().apnsToken = deviceToken
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)

@ -1 +1,128 @@
{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"}]}
{
"images" : [
{
"filename" : "Icon-App-20x20@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "Icon-App-20x20@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "Icon-App-29x29@1x.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "Icon-App-29x29@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "Icon-App-29x29@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "Icon-App-40x40@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "Icon-App-40x40@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "Icon-App-60x60@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "Icon-App-60x60@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "Icon-App-20x20@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "Icon-App-20x20@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "Icon-App-29x29@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "Icon-App-29x29@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "Icon-App-40x40@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "Icon-App-40x40@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "Icon-App-76x76@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "Icon-App-76x76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "Icon-App-83.5x83.5@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "icon.jpg",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
},
{
"filename" : "Icon-App-76x76@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "76x76"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt</string>
<key>ANDROID_CLIENT_ID</key>
<string>815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com</string>
<key>API_KEY</key>
@ -11,11 +15,11 @@
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.cloudsolutions.HMGPatientApp</string>
<string>com.HMG.HMG-Smartphone</string>
<key>PROJECT_ID</key>
<string>api-project-815750722565</string>
<key>STORAGE_BUCKET</key>
<string>api-project-815750722565.firebasestorage.app</string>
<string>api-project-815750722565.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
@ -27,7 +31,7 @@
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:815750722565:ios:34ec03c09e02e21f3c186c</string>
<string>1:815750722565:ios:328ec247a81a2ca23c186c</string>
<key>DATABASE_URL</key>
<string>https://api-project-815750722565.firebaseio.com</string>
</dict>

@ -35,6 +35,7 @@
<string>comgooglemaps</string>
<string>baidumap</string>
<string>iosamap</string>
<string>whatsapp</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
@ -86,17 +87,38 @@
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access to enable virtual consultation between patient &amp; doctor</string>
<key>NSMotionUsageDescription</key>
<string>This app requires access to motion detection to count your daily steps.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to select image as document &amp; upload it.</string>
<string>This app requires motion detection access to function properly.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app requires photo library access to upload profile picture and documents.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to select image as document &amp; upload it.</string>
<key>NSRemindersUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>This app requires speech recognition access to access voice command features.</string>
<key>NSUserActivityTypes</key>
<array/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneDelegateClassName</key>
<string>FlutterSceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>

@ -209,8 +209,8 @@ class ApiClientImp implements ApiClient {
body['TokenID'] = "@dm!n";
}
body['TokenID'] = "@dm!n";
// body['PatientID'] = 7000792;
// body['TokenID'] = "@dm!n";
// body['PatientID'] = 1009156;
// body['PatientID'] = 53320;
// body['PatientTypeID'] = 1;
// body['PatientOutSA'] = 0;
@ -223,9 +223,9 @@ class ApiClientImp implements ApiClient {
// body['PatientID'] = 809289;
}
if (!url.contains("/paymentApi")) {
body['IsNewFlutterApp'] = true;
}
// if (!url.contains("/paymentApi")) {
// body['IsNewFlutterApp'] = true;
// }
body.removeWhere((key, value) => value == null);
}

@ -316,8 +316,8 @@ class ApiConsts {
static String googleCloudStorageENTranslationFileBaseURL = "https://storage.googleapis.com/hmg-patientapp-translations";
// ************ static values for Api ****************
static final double appVersionID = 22.4;
// static final double appVersionID = 21.9;
static final double appVersionID = 21.5;
// static final double appVersionID = 50.7;
static final int appChannelId = 3;

@ -52,12 +52,12 @@ class AppState {
// bool isMyFatoorahEnabled = true;
void setIsPaytabsEnabled(bool value) {
isPaytabsEnabled = value;
isPaytabsEnabled = false;
// isPaytabsEnabled = true;
}
void setIsMyFatoorahEnabled(bool value) {
isMyFatoorahEnabled = value;
isMyFatoorahEnabled = false;
// isMyFatoorahEnabled = true;
}
@ -70,7 +70,7 @@ class AppState {
bool isChildLoggedIn = false;
bool isGMSAvailable = true;
bool isAndroid = true;
bool isRatedVisible =false;
bool isRatedVisible = false;
void setAuthenticatedUser(AuthenticatedUser? authenticatedUser, {bool isFamily = false}) {
if (isFamily) {
_authenticatedChildUser = authenticatedUser;

@ -2,12 +2,13 @@ import 'package:freerasp/freerasp.dart';
final talsecConfig = TalsecConfig(
androidConfig: AndroidConfig(
packageName: 'com.cloudsolutions.HMGPatientApp',
signingCertHashes: ['6tvWaoN5coG4SnfxGbdQlcLmM0J4ePQwDjrKIg+QkV0=', 'j6VEqVhrypHMIiXiFdRLDdGwjGaMGWY7KAdBJA+Z4Pc='], // Must be the release cert hash
packageName: 'com.ejada.hmg',
signingCertHashes: ['6tvWaoN5coG4SnfxGbdQlcLmM0J4ePQwDjrKIg+QkV0=', 'j6VEqVhrypHMIiXiFdRLDdGwjGaMGWY7KAdBJA+Z4Pc=', 'EKw2Bd3VYz//DYjDnJLxEh3uGqhNDIWubLmpwAx/A7U='], // Must be the release cert hash
supportedStores: ['com.android.vending'], // Google Play Store
),
iosConfig: IOSConfig(
bundleIds: ['com.cloudsolutions.HMGPatientApp'], // iOS Bundle ID
// bundleIds: ['com.cloudsolutions.HMGPatientApp'], // iOS Bundle ID
bundleIds: ['com.HMG.HMG-Smartphone'], // iOS Bundle ID
teamId: '3A359E86ZF', // Found in Apple Developer portal
),
watcherMail: '', // Required to receive security alerts

@ -27,6 +27,7 @@ import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:uuid/uuid.dart';
import 'package:huawei_push/huawei_push.dart' as h_push;
// Global tracking variables for call state
bool _isCallInProgress = false;
@ -425,10 +426,30 @@ class PushNotificationHandler {
if (Platform.isAndroid) {
try {
final fcmToken = await FirebaseMessaging.instance.getToken().catchError((err) {
log(err);
});
if (fcmToken != null) onToken(fcmToken);
if (!(await Utils.isGoogleServicesAvailable())) {
h_push.Push.enableLogger();
final result = await h_push.Push.setAutoInitEnabled(true);
h_push.Push.onNotificationOpenedApp.listen((message) {
// newMessage(toFirebaseRemoteMessage(message));
}, onError: (e) => print(e.toString()));
h_push.Push.onMessageReceivedStream.listen((message) {
// newMessage(toFirebaseRemoteMessage(message));
}, onError: (e) => print(e.toString()));
h_push.Push.getTokenStream.listen((token) {
onToken(token);
}, onError: (e) => print(e.toString()));
h_push.Push.getToken('');
h_push.Push.registerBackgroundMessageHandler(backgroundMessageHandler);
} else {
final fcmToken = await FirebaseMessaging.instance.getToken().catchError((err) {
log(err);
});
if (fcmToken != null) onToken(fcmToken);
}
// }
} catch (ex) {
log("Notification Exception: $ex");

@ -1421,7 +1421,8 @@ class AuthenticationViewModel extends ChangeNotifier {
if (value) {
LoaderBottomSheet.showLoader();
success();
loginTypeEnum = (_appState.deviceTypeID == 1 ? LoginTypeEnum.face : LoginTypeEnum.fingerprint);
// loginTypeEnum = (_appState.deviceTypeID == 1 ? LoginTypeEnum.face : LoginTypeEnum.fingerprint);
loginTypeEnum = (Platform.isIOS ? LoginTypeEnum.face : LoginTypeEnum.fingerprint);
if (!_appState.isAuthenticated) {
//commenting this api to check either the same flow working or not because this api does not needed further if work fine we will remove this
await getPatientDeviceData(loginTypeEnum.toInt);

@ -37,7 +37,7 @@ abstract class BookAppointmentsRepo {
Future<Either<Failure, GenericApiModel<dynamic>>> getDoctorFreeSlots(int clinicID, int projectID, int doctorId, bool isBookingForLiveCare,
{bool continueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError});
Future<Either<Failure, GenericApiModel<dynamic>>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel});
Future<Either<Failure, GenericApiModel<dynamic>>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false});
Future<Either<Failure, GenericApiModel<dynamic>>> insertSpecificAppointment(
{required int docID,
@ -483,12 +483,12 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo {
}
@override
Future<Either<Failure, GenericApiModel>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}) async {
Future<Either<Failure, GenericApiModel>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false}) async {
Map<String, dynamic> requestBody = {
"AppointmentID": patientAppointmentHistoryResponseModel.appointmentNo,
"ClinicID": patientAppointmentHistoryResponseModel.clinicID,
"ProjectID": patientAppointmentHistoryResponseModel.projectID,
"CancelToReschadual": false,
"CancelToReschadual": isReschedule,
"EndTime": patientAppointmentHistoryResponseModel.endTime,
"StartTime": patientAppointmentHistoryResponseModel.startTime,
"DoctorID": patientAppointmentHistoryResponseModel.doctorID,

@ -948,8 +948,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
);
}
Future<void> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await bookAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
Future<void> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await bookAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: isReschedule);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@ -1011,7 +1011,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
appointmentDate: apiResponse.data["SameClinicApptList"][0]['AppointmentDate'],
);
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async {
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: true).then((val) async {
// LoaderBottomSheet.hideLoader();
Future.delayed(Duration(milliseconds: 50)).then((value) async {});
// LoaderBottomSheet.showLoader(loadingText: LocaleKeys.bookingYourAppointment.tr());
@ -1069,7 +1069,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
// loadingText: LocaleKeys.reschedulingAppo.tr(context: navigationService.navigatorKey.currentContext!),
loadingText: LocaleKeys.loadingText.tr(context: navigationService.navigatorKey.currentContext!),
);
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async {
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: true).then((val) async {
LoaderBottomSheet.hideLoader();
Future.delayed(Duration(milliseconds: 50)).then((value) async {});
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.bookingYourAppointment.tr());
@ -1174,7 +1174,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
isCloseButtonVisible: false,
isDismissible: false,
isFullScreen: false);
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async {
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: true).then((val) async {
navigationService.pop();
Future.delayed(Duration(milliseconds: 50)).then((value) async {});
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.bookingYourAppointment.tr());

@ -44,7 +44,7 @@ abstract class MyAppointmentsRepo {
Future<Either<Failure, GenericApiModel<dynamic>>> generateAppointmentQR({required int clinicID, required int projectID, required String appointmentNo, required int isFollowUp});
Future<Either<Failure, GenericApiModel<dynamic>>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel});
Future<Either<Failure, GenericApiModel<dynamic>>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false});
Future<Either<Failure, GenericApiModel<dynamic>>> confirmAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel});
@ -341,12 +341,12 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo {
}
@override
Future<Either<Failure, GenericApiModel>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}) async {
Future<Either<Failure, GenericApiModel>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false}) async {
Map<String, dynamic> requestBody = {
"AppointmentID": patientAppointmentHistoryResponseModel.appointmentNo,
"ClinicID": patientAppointmentHistoryResponseModel.clinicID,
"ProjectID": patientAppointmentHistoryResponseModel.projectID,
"CancelToReschadual": false,
"CancelToReschadual": isReschedule,
"EndTime": patientAppointmentHistoryResponseModel.endTime,
"StartTime": patientAppointmentHistoryResponseModel.startTime,
"DoctorID": patientAppointmentHistoryResponseModel.doctorID,

@ -639,8 +639,8 @@ class MyAppointmentsViewModel extends ChangeNotifier {
);
}
Future<void> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
Future<void> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: isReschedule);
result.fold(
// (failure) async => await errorHandlerService.handleError(failure: failure),

@ -578,4 +578,27 @@ class PayfortViewModel extends ChangeNotifier {
);
}
Future<void> addApplePayPayfortResponse(dynamic paymentMap) async {
PayfortResponseInsertModel payfortResponseInsertModel = PayfortResponseInsertModel();
payfortResponseInsertModel.fortId = paymentMap['fort_id'] ?? "";
payfortResponseInsertModel.commandType = paymentMap['command'] ?? "";
payfortResponseInsertModel.amount = num.tryParse(paymentMap['amount'] ?? "0") ?? 0;
payfortResponseInsertModel.sadadOLP = "";
payfortResponseInsertModel.paymentOption = paymentMap['payment_option'] ?? "";
payfortResponseInsertModel.customerIP = paymentMap['customer_ip'] ?? "";
payfortResponseInsertModel.eCI = paymentMap['eci'] ?? "";
payfortResponseInsertModel.responseMessage = paymentMap['response_message'] ?? "";
payfortResponseInsertModel.cardNumber = paymentMap['card_number'] ?? "";
payfortResponseInsertModel.cardBin = paymentMap['card_bin'] ?? "";
payfortResponseInsertModel.installmentsNumber = int.tryParse(paymentMap['installments_number'] ?? "0") ?? 0;
payfortResponseInsertModel.status = paymentMap['status'] ?? "";
payfortResponseInsertModel.merchantRef = paymentMap['merchant_reference'] ?? "";
payfortResponseInsertModel.isRefund = false;
payfortResponseInsertModel.remmeberMe = true;
payfortResponseInsertModel.reconciliationReference = "";
payfortResponseInsert(payfortResponseInsertModel: payfortResponseInsertModel);
}
}

@ -1,4 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:health/health.dart';
import 'package:hmg_patient_app_new/core/common_models/data_points.dart';
import 'package:hmg_patient_app_new/core/common_models/smart_watch.dart';
@ -119,15 +120,22 @@ class HealthProvider with ChangeNotifier {
void initDevice() async {
LoaderBottomSheet.showLoader();
notifyListeners();
error = null;
final result = await _healthService.initDevice();
isLoading = false;
LoaderBottomSheet.hideLoader();
// LoaderBottomSheet.hideLoader();
if (result.isError) {
error = 'Error initializing device: ${result.asError}';
LoaderBottomSheet.hideLoader();
final rawError = result.asError?.error;
if (rawError is PlatformException) {
error = 'Error initializing device: ${rawError.message ?? rawError.toString()}';
} else {
error = 'Error initializing device: ${rawError?.toString() ?? 'Unknown error'}';
}
} else {
LoaderBottomSheet.showLoader();
// LoaderBottomSheet.showLoader();
await getVitals();
// LoaderBottomSheet.hideLoader();
LoaderBottomSheet.hideLoader();
// await Future.delayed(Duration(seconds: 5));
getIt.get<NavigationService>().pushPage(page: SmartWatchesHealthDataScreen());
}
@ -286,4 +294,9 @@ class HealthProvider with ChangeNotifier {
}
return formattedString;
}
void clearError(){
error = null;
notifyListeners();
}
}

@ -22,6 +22,7 @@ class Vitals {
if (timestamp.isEmpty) {
timestamp = DateTime.now().toIso8601String();
}
timestamp = DateTime.parse(timestamp).toLocal().toIso8601String();
return Vitals(
value: map['value'] ?? "",
timestamp: timestamp,

@ -0,0 +1 @@
class IllegalWatchTypeException implements Exception {}

@ -6,6 +6,8 @@ import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connec
import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/samsung_health.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/watch_helper.dart';
import 'IllegalWatchTypeException.dart';
class CreateWatchHelper {
static WatchHelper getWatchName(SmartWatchTypes watchType) {
/// if running device is ios
@ -16,7 +18,7 @@ class CreateWatchHelper {
case SmartWatchTypes.huawei:
return HuaweiHealthDataConnector();
default:
return SamsungHealth();
throw IllegalWatchTypeException();
}
}
}

@ -1,86 +1,403 @@
import 'dart:async';
import 'dart:convert';
import 'package:async/src/result/result.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/model/vitals_data_model.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/watch_helper.dart';
import 'package:http/http.dart';
import 'package:huawei_health/huawei_health.dart';
class HuaweiHealthDataConnector extends WatchHelper{
final MethodChannel _channel = MethodChannel('huawei_watch');
@override
Future<Result<bool>> initDevice() async{
try{
await _channel.invokeMethod('init');
}catch(e){
DataController? _dataController;
final Map<String, List<Vitals>> mappedData = <String, List<Vitals>>{};
DateTime get _defaultEndDate => DateTime.now();
DateTime get _defaultStartDate => _defaultEndDate.subtract(const Duration(days: 365));
@override
Future<Result<bool>> initDevice() async {
try {
await _channel.invokeMethod('init');
} catch (e) {
debugPrint('Huawei channel init failed: $e');
}
// List of scopes to ask for authorization.
// Note: These scopes should also be authorized on the Huawei Developer Console.
List<Scope> scopes = [
Scope.HEALTHKIT_STEP_READ, Scope.HEALTHKIT_OXYGEN_SATURATION_READ, // View and store height and weight data in Health Service Kit.
Scope.HEALTHKIT_HEARTRATE_READ, Scope.HEALTHKIT_SLEEP_READ,
Scope.HEALTHKIT_BODYTEMPERATURE_READ, Scope.HEALTHKIT_CALORIES_READ
final List<Scope> scopes = <Scope>[
Scope.HEALTHKIT_ACTIVITY_READ,
Scope.HEALTHKIT_ACTIVITY_WRITE,
Scope.HEALTHKIT_BLOODGLUCOSE_READ,
Scope.HEALTHKIT_BLOODGLUCOSE_WRITE,
Scope.HEALTHKIT_CALORIES_READ,
Scope.HEALTHKIT_CALORIES_WRITE,
Scope.HEALTHKIT_DISTANCE_READ,
Scope.HEALTHKIT_DISTANCE_WRITE,
Scope.HEALTHKIT_HEARTRATE_READ,
Scope.HEALTHKIT_HEARTRATE_WRITE,
Scope.HEALTHKIT_HEIGHTWEIGHT_READ,
Scope.HEALTHKIT_HEIGHTWEIGHT_WRITE,
Scope.HEALTHKIT_LOCATION_READ,
Scope.HEALTHKIT_LOCATION_WRITE,
Scope.HEALTHKIT_PULMONARY_READ,
Scope.HEALTHKIT_PULMONARY_WRITE,
Scope.HEALTHKIT_SLEEP_READ,
Scope.HEALTHKIT_SLEEP_WRITE,
Scope.HEALTHKIT_SPEED_READ,
Scope.HEALTHKIT_SPEED_WRITE,
Scope.HEALTHKIT_STEP_READ,
Scope.HEALTHKIT_STEP_WRITE,
Scope.HEALTHKIT_STRENGTH_READ,
Scope.HEALTHKIT_STRENGTH_WRITE,
Scope.HEALTHKIT_BODYFAT_READ,
Scope.HEALTHKIT_BODYFAT_WRITE,
Scope.HEALTHKIT_NUTRITION_READ,
Scope.HEALTHKIT_NUTRITION_WRITE,
Scope.HEALTHKIT_BLOODPRESSURE_READ,
Scope.HEALTHKIT_BLOODPRESSURE_WRITE,
Scope.HEALTHKIT_BODYTEMPERATURE_READ,
Scope.HEALTHKIT_BODYTEMPERATURE_WRITE,
Scope.HEALTHKIT_OXYGENSTATURATION_READ,
Scope.HEALTHKIT_OXYGENSTATURATION_WRITE,
Scope.HEALTHKIT_REPRODUCTIVE_READ,
Scope.HEALTHKIT_REPRODUCTIVE_WRITE,
Scope.HEALTHKIT_ACTIVITY_RECORD_READ,
Scope.HEALTHKIT_ACTIVITY_RECORD_WRITE,
Scope.HEALTHKIT_HEARTRATE_REALTIME,
Scope.HEALTHKIT_STEP_REALTIME,
Scope.HEALTHKIT_HEARTHEALTH_WRITE,
Scope.HEALTHKIT_HEARTHEALTH_READ,
Scope.HEALTHKIT_STRESS_WRITE,
Scope.HEALTHKIT_STRESS_READ,
Scope.HEALTHKIT_OXYGEN_SATURATION_WRITE,
Scope.HEALTHKIT_OXYGEN_SATURATION_READ,
Scope.HEALTHKIT_HISTORYDATA_OPEN_WEEK,
Scope.HEALTHKIT_HISTORYDATA_OPEN_MONTH,
Scope.HEALTHKIT_HISTORYDATA_OPEN_YEAR,
];
try {
bool? result = await SettingController.getHealthAppAuthorization();
debugPrint(
'Granted Scopes for result == is $result}',
);
await HealthAuth.signIn(scopes);
_dataController = await DataController.init();
if (_dataController == null) {
return Result.error(false);
}
return Result.value(true);
} on PlatformException catch (e) {
debugPrint('Error on Huawei authorization: $e');
return Result.error(false);
} catch (e) {
debugPrint('Error on authorization, Error:${e.toString()}');
debugPrint('Unexpected Huawei init error: $e');
return Result.error(false);
}
}
@override
Future<void> getActivity() async {
DataType dataTypeResult = await SettingController.readDataType(
DataType.DT_CONTINUOUS_STEPS_DELTA.name
);
try {
final ReadReply? data = await readDataType(
DataType.DT_CONTINUOUS_CALORIES_BURNT,
_defaultStartDate,
_defaultEndDate,
);
addDataToMap('activity', data, preferredKeys: const <String>['calories', 'calories_total']);
} catch (e) {
debugPrint('Error getting activity data: $e');
mappedData['activity'] = <Vitals>[];
}
}
@override
Future getBloodOxygen() {
throw UnimplementedError();
Future<void> getBloodOxygen() async {
try {
final ReadReply? data = await readDataType(
HealthDataTypes.DT_INSTANTANEOUS_SPO2,
_defaultStartDate,
_defaultEndDate,
);
addDataToMap(
'bloodOxygen',
data,
preferredKeys: const <String>['saturation', 'saturation_last', 'saturation_avg'],
transform: _normalizeSpo2,
);
} catch (e) {
debugPrint('Error getting blood oxygen data: $e');
mappedData['bloodOxygen'] = <Vitals>[];
}
}
@override
Future<void> getBodyTemperature() async {
try {
final ReadReply? data = await readDataType(
HealthDataTypes.DT_INSTANTANEOUS_BODY_TEMPERATURE,
_defaultStartDate,
_defaultEndDate,
);
addDataToMap('bodyTemperature', data, preferredKeys: const <String>['temperature']);
} catch (e) {
debugPrint('Error getting body temperature data: $e');
mappedData['bodyTemperature'] = <Vitals>[];
}
}
@override
Future getBodyTemperature() {
FutureOr<void> getHeartRate() async {
try {
final ReadReply? data = await readDataType(
DataType.DT_INSTANTANEOUS_HEART_RATE,
_defaultStartDate,
_defaultEndDate,
);
addDataToMap('heartRate', data, preferredKeys: const <String>['bpm']);
} catch (e) {
debugPrint('Error getting heart rate data: $e');
mappedData['heartRate'] = <Vitals>[];
}
}
throw UnimplementedError();
@override
FutureOr<void> getSleep() async {
try {
final ReadReply? data = await readDataType(
DataType.DT_CONTINUOUS_SLEEP,
_defaultStartDate,
_defaultEndDate,
);
addSleepDataToMap(data);
} catch (e) {
debugPrint('Error getting sleep data: $e');
mappedData['sleep'] = <Vitals>[];
}
}
@override
FutureOr<void> getHeartRate() {
throw UnimplementedError();
FutureOr<void> getSteps() async {
try {
final ReadReply? data = await readDataType(
DataType.DT_CONTINUOUS_STEPS_DELTA,
_defaultStartDate,
_defaultEndDate,
);
addDataToMap('steps', data, preferredKeys: const <String>['steps_delta', 'steps', 'step_rate']);
} catch (e) {
debugPrint('Error getting steps data: $e');
mappedData['steps'] = <Vitals>[];
}
}
@override
FutureOr<void> getSleep() {
throw UnimplementedError();
Future<Result<String>> retrieveData() async {
return Result.value(getMappedData());
}
@override
FutureOr<void> getSteps() {
throw UnimplementedError();
FutureOr<void> getDistance() async {
try {
final ReadReply? data = await readDataType(
DataType.DT_CONTINUOUS_DISTANCE_DELTA,
_defaultStartDate,
_defaultEndDate,
);
addDataToMap('distance', data, preferredKeys: const <String>['distance_delta', 'distance']);
} catch (e) {
debugPrint('Error getting distance data: $e');
mappedData['distance'] = <Vitals>[];
}
}
Future<ReadReply?> readDataType(
DataType dataType,
DateTime startTime,
DateTime endTime,
) async {
final DataCollector dataCollector = DataCollector(
dataType: dataType,
dataGenerateType: DataGenerateType.DATA_TYPE_RAW,
);
@override
Future retrieveData() {
throw UnimplementedError();
final ReadOptions readOptions = ReadOptions(
dataCollectors: <DataCollector>[dataCollector],
startTime: startTime,
endTime: endTime,
allowRemoteInquiry: true,
)..groupByTime(1, timeUnit: TimeUnit.HOURS);
try {
return await _dataController?.read(readOptions);
} on PlatformException catch (e) {
debugPrint('Huawei read error for ${dataType.name}: $e');
return null;
}
}
@override
FutureOr<void> getDistance() {
// TODO: implement getDistance
throw UnimplementedError();
void addDataToMap(
String key,
ReadReply? data, {
List<String> preferredKeys = const <String>[],
double Function(double value)? transform,
}) {
mappedData[key] = <Vitals>[];
if (data == null) {
return;
}
if (data.groups.isNotEmpty) {
for (final Group group in data.groups) {
for (final SampleSet sampleSet in group.sampleSets ?? <SampleSet>[]) {
for (final SamplePoint samplePoint in sampleSet.samplePoints) {
_addNumericSampleToMappedData(
key: key,
samplePoint: samplePoint,
preferredKeys: preferredKeys,
groupStartTime: group.startTime,
transform: transform,
);
}
}
}
return;
}
for (final SampleSet sampleSet in data.sampleSets) {
for (final SamplePoint samplePoint in sampleSet.samplePoints) {
_addNumericSampleToMappedData(
key: key,
samplePoint: samplePoint,
preferredKeys: preferredKeys,
transform: transform,
);
}
}
}
void addSleepDataToMap(ReadReply? data) {
mappedData['sleep'] = <Vitals>[];
if (data == null) {
return;
}
void appendSleepPoint(SamplePoint samplePoint, {DateTime? groupStart, DateTime? groupEnd}) {
final DateTime? start = samplePoint.startTime ?? groupStart;
final DateTime? end = samplePoint.endTime ?? groupEnd;
double? value;
if (start != null && end != null && end.isAfter(start)) {
value = end.difference(start).inMinutes / 60;
}
value ??= _extractNumericValue(
samplePoint,
const <String>['sleep_state', 'all_sleep_time', 'deep_sleep_time', 'light_sleep_time'],
);
if (value == null) {
return;
}
final String timestamp =
(start ?? samplePoint.samplingTime ?? DateTime.now()).toIso8601String();
mappedData['sleep']?.add(
Vitals(
value: value.toStringAsFixed(2),
timestamp: timestamp,
),
);
}
if (data.groups.isNotEmpty) {
for (final Group group in data.groups) {
for (final SampleSet sampleSet in group.sampleSets ?? <SampleSet>[]) {
for (final SamplePoint samplePoint in sampleSet.samplePoints) {
appendSleepPoint(
samplePoint,
groupStart: group.startTime,
groupEnd: group.endTime,
);
}
}
}
return;
}
for (final SampleSet sampleSet in data.sampleSets) {
for (final SamplePoint samplePoint in sampleSet.samplePoints) {
appendSleepPoint(samplePoint);
}
}
}
void _addNumericSampleToMappedData({
required String key,
required SamplePoint samplePoint,
required List<String> preferredKeys,
DateTime? groupStartTime,
double Function(double value)? transform,
}) {
final double? numericValue = _extractNumericValue(samplePoint, preferredKeys);
if (numericValue == null) {
return;
}
final double transformedValue = transform?.call(numericValue) ?? numericValue;
final String timestamp =
(samplePoint.samplingTime ?? samplePoint.startTime ?? groupStartTime ?? DateTime.now())
.toIso8601String();
mappedData[key]?.add(
Vitals(
value: transformedValue.toStringAsFixed(2),
timestamp: timestamp,
),
);
}
double? _extractNumericValue(SamplePoint samplePoint, List<String> preferredKeys) {
final Map<String, dynamic> values = <String, dynamic>{
...samplePoint.pairs,
...?samplePoint.fieldValues,
};
for (final String key in preferredKeys) {
final dynamic value = values[key];
if (value is num) {
return value.toDouble();
}
}
for (final dynamic value in values.values) {
if (value is num) {
return value.toDouble();
}
}
return null;
}
double _normalizeSpo2(double value) {
if (value <= 1) {
return value * 100;
}
return value;
}
String getMappedData() {
return jsonEncode(<String, dynamic>{
'heartRate': (mappedData['heartRate'] ?? <Vitals>[]).map((Vitals v) => v.toJson()).toList(),
'sleep': (mappedData['sleep'] ?? <Vitals>[]).map((Vitals v) => v.toJson()).toList(),
'steps': (mappedData['steps'] ?? <Vitals>[]).map((Vitals v) => v.toJson()).toList(),
'activity': (mappedData['activity'] ?? <Vitals>[]).map((Vitals v) => v.toJson()).toList(),
'bloodOxygen':
(mappedData['bloodOxygen'] ?? <Vitals>[]).map((Vitals v) => v.toJson()).toList(),
'bodyTemperature':
(mappedData['bodyTemperature'] ?? <Vitals>[]).map((Vitals v) => v.toJson()).toList(),
'distance': (mappedData['distance'] ?? <Vitals>[]).map((Vitals v) => v.toJson()).toList(),
});
}
}
}

@ -57,7 +57,8 @@ class DefaultFirebaseOptions {
databaseURL: 'https://api-project-815750722565.firebaseio.com',
storageBucket: 'api-project-815750722565.firebasestorage.app',
androidClientId: '815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com',
iosBundleId: 'com.cloudsolutions.HMGPatientApp',
// iosBundleId: 'com.cloudsolutions.HMGPatientApp',
iosBundleId: 'com.HMG.HMG-Smartphone',
);
}

@ -132,6 +132,7 @@ Future<void> callInitializations() async {
} catch (e) {
// If it doesn't exist, initialize it.
await Firebase.initializeApp(
name: "api-project-815750722565",
options: DefaultFirebaseOptions.currentPlatform,
);
}

@ -338,6 +338,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
myAppointmentsViewModel.updateListWRTTab(0);
await myAppointmentsViewModel.cancelAppointment(
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
isReschedule: false,
onSuccess: (apiResponse) async {
LoaderBottomSheet.hideLoader();
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);

@ -1283,6 +1283,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED",
onFailed: (failureResult) async {
log("failureResult: ${failureResult.message.toString()}");
payfortViewModel.addApplePayPayfortResponse(failureResult.response);
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
@ -1293,10 +1294,94 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
);
},
onSucceeded: (successResult) async {
payfortViewModel.addApplePayPayfortResponse(successResult);
LoaderBottomSheet.hideLoader();
log("successResult: ${successResult.responseMessage.toString()}");
selectedPaymentMethod = successResult.paymentOption ?? "VISA";
checkPaymentStatus();
// LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingPaymentStatusPleaseWait.tr(context: context));
// await myAppointmentsViewModel.createAdvancePayment(
// paymentMethodName: selectedPaymentMethod,
// projectID: widget.patientAppointmentHistoryResponseModel.projectID,
// clinicID: widget.patientAppointmentHistoryResponseModel.clinicID,
// appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(),
// payedAmount: num.parse(myAppointmentsViewModel.patientAppointmentShareResponseModel!.patientShareWithTax!.toString()),
// paymentReference: successResult.fortId!,
// patientID: appState.getAuthenticatedUser()!.patientId.toString(),
// patientType: appState.getAuthenticatedUser()!.patientType!,
// onSuccess: (value) async {
// print(value);
// await myAppointmentsViewModel.addAdvanceNumberRequest(
// advanceNumber: Utils.isVidaPlusProject(widget.patientAppointmentHistoryResponseModel.projectID)
// ? value.data['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString()
// : value.data['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(),
// paymentReference: successResult.fortId!,
// appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(),
// onSuccess: (value) async {
// if (widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!) {
// //TODO: Implement LiveCare Check-In API Call
// await myAppointmentsViewModel.insertLiveCareVIDARequest(
// clientRequestID: transID,
// patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
// onSuccess: (apiResponse) {
// Future.delayed(Duration(milliseconds: 500), () {
// myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);
// myAppointmentsViewModel.initAppointmentsViewModel();
// myAppointmentsViewModel.getPatientAppointments(true, false);
//
// getIt.get<HabibWalletViewModel>().setIsWalletAmountToBeLoaded(true);
// getIt.get<HabibWalletViewModel>().initHabibWalletProvider();
// getIt.get<HabibWalletViewModel>().getPatientBalanceAmount();
//
// LoaderBottomSheet.hideLoader();
// Navigator.pushAndRemoveUntil(
// context,
// CustomPageRoute(
// page: LandingNavigation(),
// ),
// (r) => false);
// });
// },
// onError: (error) {});
// } else {
// await myAppointmentsViewModel.generateAppointmentQR(
// clinicID: widget.patientAppointmentHistoryResponseModel.clinicID,
// projectID: widget.patientAppointmentHistoryResponseModel.projectID,
// appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(),
// isFollowUp: myAppointmentsViewModel.patientAppointmentShareResponseModel!.isFollowup!,
// onSuccess: (apiResponse) {
// Future.delayed(Duration(milliseconds: 500), () {
// myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);
// myAppointmentsViewModel.initAppointmentsViewModel();
// myAppointmentsViewModel.getPatientAppointments(true, false);
//
// getIt.get<HabibWalletViewModel>().setIsWalletAmountToBeLoaded(true);
// getIt.get<HabibWalletViewModel>().initHabibWalletProvider();
// getIt.get<HabibWalletViewModel>().getPatientBalanceAmount();
//
// LoaderBottomSheet.hideLoader();
// Navigator.pushAndRemoveUntil(
// context,
// CustomPageRoute(
// page: LandingNavigation(),
// ),
// (r) => false);
// });
// });
// }
// });
// },
// onError: (err) {
// LoaderBottomSheet.hideLoader();
// showCommonBottomSheetWithoutHeight(
// context,
// child: Utils.getErrorWidget(loadingText: err.toString()),
// callBackFunc: () {},
// isFullScreen: false,
// isCloseButtonVisible: true,
// );
// });
},
// projectId: appo.projectID,
// serviceTypeEnum: ServiceTypeEnum.appointmentPayment,

@ -1077,6 +1077,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED",
onFailed: (failureResult) async {
log("failureResult: ${failureResult.message.toString()}");
payfortViewModel.addApplePayPayfortResponse(failureResult.response);
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
@ -1087,6 +1088,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
);
},
onSucceeded: (successResult) async {
payfortViewModel.addApplePayPayfortResponse(successResult);
LoaderBottomSheet.hideLoader();
log("successResult: ${successResult.responseMessage.toString()}");
selectedPaymentMethod = successResult.paymentOption ?? "VISA";

@ -904,6 +904,7 @@ class _WaitingAppointmentPaymentPageState extends State<WaitingAppointmentPaymen
applePayShaRequestPhrase: payfortViewModel.payfortProjectDetailsRespModel!.shaRequest,
currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED",
onFailed: (failureResult) async {
payfortViewModel.addApplePayPayfortResponse(failureResult.response);
log("failureResult: ${failureResult.message.toString()}");
Navigator.of(context).pop();
showCommonBottomSheetWithoutHeight(
@ -915,6 +916,7 @@ class _WaitingAppointmentPaymentPageState extends State<WaitingAppointmentPaymen
);
},
onSucceeded: (successResult) async {
payfortViewModel.addApplePayPayfortResponse(successResult);
log("successResult: ${successResult.responseMessage.toString()}");
selectedPaymentMethod = successResult.paymentOption ?? "VISA";
checkPaymentStatus();

@ -7,7 +7,6 @@ import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_amazonpaymentservices/flutter_amazonpaymentservices.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
@ -668,6 +667,7 @@ class _WalletPaymentConfirmPageState extends State<WalletPaymentConfirmPage> {
currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED",
onFailed: (failureResult) async {
log("failureResult: ${failureResult.message.toString()}");
payfortViewModel.addApplePayPayfortResponse(failureResult.response);
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: failureResult.message.toString()),
@ -678,6 +678,7 @@ class _WalletPaymentConfirmPageState extends State<WalletPaymentConfirmPage> {
},
onSucceeded: (successResult) async {
log("successResult: ${successResult.responseMessage.toString()}");
payfortViewModel.addApplePayPayfortResponse(successResult);
selectedPaymentMethod = successResult.paymentOption ?? "VISA";
checkPaymentStatus();
},
@ -830,28 +831,4 @@ class _WalletPaymentConfirmPageState extends State<WalletPaymentConfirmPage> {
"",
"3");
}
Future<void> runSafePayment(Map<String, dynamic> requestParam, {String sdkToken = ""}) async {
dynamic result;
try {
// Force a 100ms microtask buffer to isolate the UI rendering channel
await Future.delayed(const Duration(milliseconds: 350));
result = await FlutterAmazonpaymentservices.normalPay(requestParam, ApiConsts.payFortEnvironmentType, isShowResponsePage: true);
print("Payment Success Data: ${result.toString()}");
} on PlatformException catch (e) {
// If the error is the MethodChannel duplicate reply bug, handle it safely
if (e.message != null && e.message!.contains("Reply already submitted")) {
print("Swallowed native channel race-condition crash safely.");
return;
}
// Process real payment rejection errors here
print("Actual Payment Failure: ${e.details.toString()}");
} catch (error) {
print("Generic Error: $error");
}
}
}

@ -76,14 +76,15 @@ class AppUpdatePage extends StatelessWidget {
}
if (Platform.isIOS) {
Utils.openWebView(
// url: "https://itunes.apple.com/app/id733503978",
url: "https://itunes.apple.com/app/id6758851027",
url: "https://itunes.apple.com/app/id733503978",
// url: "https://itunes.apple.com/app/id6758851027",
);
}
}
Future<void> _handleAndroidAppUpdate() async {
const fallbackUrl = "https://play.google.com/store/apps/details?id=com.cloudsolutions.HMGPatientApp";
// const fallbackUrl = "https://play.google.com/store/apps/details?id=com.cloudsolutions.HMGPatientApp";
const fallbackUrl = "https://play.google.com/store/apps/details?id=com.ejada.hmg";
try {
final info = await InAppUpdate.checkForUpdate();
print("InAppUpdate.checkForUpdate -> $info");

@ -280,7 +280,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
AppCustomChipWidget(
icon: AppAssets.blood_icon,
labelText: appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup,
iconColor: AppColors.primaryRedColor,
iconColor: AppColors.primaryRedColorBase,
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
padding: EdgeInsets.zero,
),

@ -459,7 +459,7 @@ class _FamilyCardsState extends State<FamilyCards> {
isCircular: true,
isFamilyMember: true, // Prevent AppState fallback
),
SizedBox(height: 4.h),
SizedBox(height: 3.h),
(profile.patientName ?? "Unknown").toText14(isBold: true, isCenter: true, maxlines: 1),
// SizedBox(height: 8.h),
// CustomChipWidget(

@ -1,5 +1,6 @@
import 'dart:math';
import 'package:easy_localization/easy_localization.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
@ -43,7 +44,7 @@ class _ActivityDetailsState extends State<ActivityDetails> {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: "All Health Data".needTranslation,
title: "allHealthData".tr(),
child: Column(
spacing: 16.h,
children: [
@ -113,8 +114,8 @@ class _ActivityDetailsState extends State<ActivityDetails> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.sectionName.capitalizeFirstofEach.toText32(isBold: true, color: AppColors.textColor),
"Average".toText12(isBold: true, color: AppColors.greyTextColor)
widget.sectionName.capitalizeFirstofEach.tr().toText32(isBold: true, color: AppColors.textColor),
"average".tr().needTranslation.toText12(isBold: true, color: AppColors.greyTextColor)
],
),
Selector<HealthProvider, Tuple2<double?, String?>>(
@ -242,6 +243,7 @@ class _ActivityDetailsState extends State<ActivityDetails> {
builder: (_, data, __) {
// if (context.read<HealthProvider>().selectedData.values.toList().first.isEmpty == true) return SizedBox();
if (context.read<HealthProvider>().selectedData.values.toList().isEmpty == true) return SizedBox();
if (context.read<HealthProvider>().selectedData.values.toList().first.isEmpty == true) return SizedBox();
return CustomBarChart(
dataPoints: context.read<HealthProvider>().selectedData.values.toList().first,

@ -1,3 +1,4 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
@ -20,14 +21,14 @@ class SmartWatchesHealthDataScreen extends StatelessWidget {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: "All Health Data".needTranslation,
title: "allHealthData".tr(context: context),
child: Column(
spacing: 16.h,
children: [
resultItem(
leadingIcon: AppAssets.watchActivity,
title: "Activity Calories".needTranslation,
description: "Activity rings give you a quick visual reference of how active you are each day. ".needTranslation,
title: "activityCalories".tr(context: context),
description: "activityCaloriesDescription".tr(context: context),
trailingIcon: AppAssets.watchActivityTrailing,
result: context.read<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.activity ?? []),
unitsOfMeasure: "Kcal")
@ -36,12 +37,12 @@ class SmartWatchesHealthDataScreen extends StatelessWidget {
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("activity");
context.read<HealthProvider>().saveSelectedSection("activity");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().navigateToDetails("activity", sectionName: "Activity Calories", uom: "Kcal");
context.read<HealthProvider>().navigateToDetails("activity", sectionName: "activityCalories".tr(), uom: "Kcal");
}),
resultItem(
leadingIcon: AppAssets.watchSteps,
title: "Steps".needTranslation,
description: "Step count is the number of steps you take throughout the day.".needTranslation,
title: "steps".tr(context: context),
description: "stepsDescription".tr(context: context),
trailingIcon: AppAssets.watchStepsTrailing,
result: context.read<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.step ?? []),
unitsOfMeasure: "Steps")
@ -60,12 +61,12 @@ class SmartWatchesHealthDataScreen extends StatelessWidget {
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("steps");
context.read<HealthProvider>().saveSelectedSection("steps");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().navigateToDetails("steps", sectionName: "Steps", uom: "Steps");
context.read<HealthProvider>().navigateToDetails("steps", sectionName: "steps".tr(), uom: "Steps");
}),
resultItem(
leadingIcon: AppAssets.watchSteps,
title: "Distance Covered".needTranslation,
description: "Step count is the distance you take throughout the day.".needTranslation,
title: "distanceCovered".tr(context: context),
description: "distanceCoveredDescription".tr(context: context),
trailingIcon: AppAssets.watchStepsTrailing,
result: context.read<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.distance ?? []),
unitsOfMeasure: "Km")
@ -74,12 +75,12 @@ class SmartWatchesHealthDataScreen extends StatelessWidget {
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("distance");
context.read<HealthProvider>().saveSelectedSection("distance");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().navigateToDetails("distance", sectionName: "Distance Covered", uom: "km");
context.read<HealthProvider>().navigateToDetails("distance", sectionName: "distanceCovered".tr(), uom: "km");
}),
resultItem(
leadingIcon: AppAssets.watchSleep,
title: "Sleep Score".needTranslation,
description: "This will keep track of how much hours you sleep in a day".needTranslation,
title: "sleepScore".tr(context: context),
description: "sleepScoreDescription".tr(context: context),
trailingIcon: AppAssets.watchSleepTrailing,
result: DateUtil.millisToHourMin(
int.parse(context.read<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.sleep ?? [])))
@ -94,12 +95,12 @@ class SmartWatchesHealthDataScreen extends StatelessWidget {
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("sleep");
context.read<HealthProvider>().saveSelectedSection("sleep");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().navigateToDetails("sleep", sectionName: "Sleep Score", uom: "");
context.read<HealthProvider>().navigateToDetails("sleep", sectionName: "sleepScore".tr(), uom: "");
}),
resultItem(
leadingIcon: AppAssets.watchWeight,
title: "Blood Oxygen".needTranslation,
description: "This will calculate your Blood Oxygen to keep track and update history".needTranslation,
title: "bloodOxygen".tr(context: context),
description: "bloodOxygenTrackingDescription".tr(context: context),
trailingIcon: AppAssets.watchWeightTrailing,
result: context.read<HealthProvider>().firstNonEmptyValue(
context.read<HealthProvider>().vitals?.bodyOxygen ?? [],
@ -110,12 +111,12 @@ class SmartWatchesHealthDataScreen extends StatelessWidget {
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("bodyOxygen");
context.read<HealthProvider>().saveSelectedSection("bodyOxygen");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().navigateToDetails("bodyOxygen", uom: "%", sectionName: "Blood Oxygen");
context.read<HealthProvider>().navigateToDetails("bodyOxygen", uom: "%", sectionName: "bloodOxygen".tr());
}),
resultItem(
leadingIcon: AppAssets.watchWeight,
title: "Body temperature".needTranslation,
description: "This will calculate your Body temprerature to keep track and update history".needTranslation,
title: "bodyTemperature".tr(context: context),
description: "bodyTemperatureTrackingDescription".tr(context: context),
trailingIcon: AppAssets.watchWeightTrailing,
result: context.read<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.bodyTemperature ?? []),
unitsOfMeasure: "C")
@ -124,7 +125,7 @@ class SmartWatchesHealthDataScreen extends StatelessWidget {
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("bodyTemperature");
context.read<HealthProvider>().saveSelectedSection("bodyTemperature");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().navigateToDetails("bodyTemperature", sectionName: "Body temperature".capitalizeFirstofEach, uom: "C");
context.read<HealthProvider>().navigateToDetails("bodyTemperature", sectionName: "bodyTemperature".tr().capitalizeFirstofEach, uom: "C");
}),
],
).paddingSymmetrical(24.w, 24.h),

@ -25,203 +25,269 @@ class SmartwatchHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: LocaleKeys.smartWatches.tr(),
bottomChild: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
return Consumer<HealthProvider>(builder: (context, healthProvider, child) {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: LocaleKeys.smartWatches.tr(),
bottomChild: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: CustomButton(
text: LocaleKeys.supportedSmartWatches.tr(context: context),
onPressed: () {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.supportedSmartWatches.tr(context: context),
context,
child: SupportedWatchesList(),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
},
backgroundColor: AppColors.infoColor.withAlpha(40),
borderColor: AppColors.infoColor.withAlpha(0),
textColor: AppColors.infoColor,
fontSize: 16.f,
isBold: true,
borderRadius: 12.r,
height: 50.h,
icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.infoColor,
iconSize: 18.h,
).paddingSymmetrical(24.w, 30.h),
),
child: CustomButton(
text: LocaleKeys.supportedSmartWatches.tr(context: context),
onPressed: () {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.supportedSmartWatches.tr(context: context),
context,
child: SupportedWatchesList(),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
},
backgroundColor: AppColors.infoColor.withAlpha(40),
borderColor: AppColors.infoColor.withAlpha(0),
textColor: AppColors.infoColor,
fontSize: 16.f,
isBold: true,
borderRadius: 12.r,
height: 50.h,
icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.infoColor,
iconSize: 18.h,
).paddingSymmetrical(24.w, 30.h),
),
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 24.h),
child: GridView(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 16.h,
mainAxisSpacing: 16.w,
childAspectRatio: isFoldable ? 1.1 : (isTablet ? 1.3 : 0.7),
),
children: [
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: Column(
children: [
Utils.buildImgWithAssets(icon: "assets/images/png/smartwatches/apple-watch-5.jpg", width: 136.h, height: 136.h).paddingSymmetrical(24.w, 8.h),
"Apple Watch".needTranslation.toText16(isBold: true),
CustomButton(
text: LocaleKeys.selectSmartWatch.tr(context: context),
onPressed: () {
context
.read<HealthProvider>()
.setSelectedWatchType(SmartWatchTypes.apple, "assets/images/png/smartwatches/apple-watch-5.jpg");
getIt.get<NavigationService>().pushPage(
page: SmartwatchInstructionsPage(
smartwatchDetails: SmartwatchDetails(
SmartWatchTypes.apple,
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding:
EdgeInsets.symmetric(horizontal: 24.w, vertical: 24.h),
child: GridView(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 16.h,
mainAxisSpacing: 16.w,
childAspectRatio:
isFoldable ? 1.1 : (isTablet ? 1.3 : 0.7),
),
children: [
Container(
decoration:
RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: Column(
children: [
Utils.buildImgWithAssets(
icon:
"assets/images/png/smartwatches/apple-watch-5.jpg",
AppAssets.bluetooth,
LocaleKeys.applehealthapplicationshouldbeinstalledinyourphone.tr(context: context),
LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
LocaleKeys.applewatchshouldbeconnected.tr(context: context)),
));
},
backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
isBold: true,
borderRadius: 12.r,
height: 40.h,
).paddingSymmetrical(16.w, 12.h),
],
width: 136.h,
height: 136.h)
.paddingSymmetrical(24.w, 8.h),
"applewatch"
.tr()
.needTranslation
.toText16(isBold: true),
CustomButton(
text: LocaleKeys.selectSmartWatch
.tr(context: context),
onPressed: () {
context.read<HealthProvider>().setSelectedWatchType(
SmartWatchTypes.apple,
"assets/images/png/smartwatches/apple-watch-5.jpg");
getIt.get<NavigationService>().pushPage(
page: SmartwatchInstructionsPage(
smartwatchDetails: SmartwatchDetails(
SmartWatchTypes.apple,
"assets/images/png/smartwatches/apple-watch-5.jpg",
AppAssets.bluetooth,
LocaleKeys
.applehealthapplicationshouldbeinstalledinyourphone
.tr(context: context),
LocaleKeys
.unabletodetectapplicationinstalledpleasecomebackonceinstalled
.tr(context: context),
LocaleKeys.applewatchshouldbeconnected
.tr(context: context)),
));
},
backgroundColor:
AppColors.primaryRedColor.withAlpha(40),
borderColor:
AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
isBold: true,
borderRadius: 12.r,
height: 40.h,
).paddingSymmetrical(16.w, 12.h),
],
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
child: Column(
children: [
Utils.buildImgWithAssets(icon: "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg", fit: BoxFit.contain, width: 136.w, height: 136.h)
.paddingSymmetrical(24.w, 8.h),
"Samsung Watch".needTranslation.toText16(isBold: true),
CustomButton(
text: LocaleKeys.selectSmartWatch.tr(context: context),
onPressed: () {
context
.read<HealthProvider>()
.setSelectedWatchType(SmartWatchTypes.samsung, "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg");
getIt.get<NavigationService>().pushPage(
page: SmartwatchInstructionsPage(
smartwatchDetails: SmartwatchDetails(
SmartWatchTypes.samsung,
Container(
decoration: RoundedRectangleBorder()
.toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r),
child: Column(
children: [
Utils.buildImgWithAssets(
icon:
"assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg",
AppAssets.bluetooth,
LocaleKeys.samsunghealthapplicationshouldbeinstalledinyourphone.tr(context: context),
LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
LocaleKeys.samsungwatchshouldbeconnected.tr(context: context)),
));
},
backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
isBold: true,
borderRadius: 12.r,
height: 40.h,
).paddingSymmetrical(16.w, 12.h),
],
fit: BoxFit.contain,
width: 136.w,
height: 136.h)
.paddingSymmetrical(24.w, 8.h),
"samsungwatch"
.tr()
.needTranslation
.toText16(isBold: true),
CustomButton(
text: LocaleKeys.selectSmartWatch
.tr(context: context),
onPressed: () {
context.read<HealthProvider>().setSelectedWatchType(
SmartWatchTypes.samsung,
"assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg");
getIt.get<NavigationService>().pushPage(
page: SmartwatchInstructionsPage(
smartwatchDetails: SmartwatchDetails(
SmartWatchTypes.samsung,
"assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg",
AppAssets.bluetooth,
LocaleKeys
.samsunghealthapplicationshouldbeinstalledinyourphone
.tr(context: context),
LocaleKeys
.unabletodetectapplicationinstalledpleasecomebackonceinstalled
.tr(context: context),
LocaleKeys
.samsungwatchshouldbeconnected
.tr(context: context)),
));
},
backgroundColor:
AppColors.primaryRedColor.withAlpha(40),
borderColor:
AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
isBold: true,
borderRadius: 12.r,
height: 40.h,
).paddingSymmetrical(16.w, 12.h),
],
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
Container(
decoration:
RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: Column(
children: [
Utils.buildImgWithAssets(
icon:
"assets/images/png/smartwatches/Huawei_Watch.png",
width: 136.w,
height: 136.h)
.paddingSymmetrical(24.w, 8.h),
"huaweiwatch"
.tr()
.needTranslation
.toText16(isBold: true),
CustomButton(
text: LocaleKeys.selectSmartWatch
.tr(context: context),
onPressed: () {
// context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.huawei, "assets/images/png/smartwatches/Huawei_Watch.png");
// getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage(
// smartwatchDetails: SmartwatchDetails(SmartWatchTypes.huawei,
// "assets/images/png/smartwatches/Huawei_Watch.png",
// AppAssets.bluetooth,
// LocaleKeys.huaweihealthapplicationshouldbeinstalledinyourphone.tr(context: context),
// LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
// LocaleKeys.huaweiwatchshouldbeconnected.tr(context: context)),
// ));
showUnavailableDialog(context);
},
backgroundColor:
AppColors.primaryRedColor.withAlpha(40),
borderColor:
AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
isBold: true,
borderRadius: 12.r,
height: 40.h,
).paddingSymmetrical(16.w, 12.h),
],
),
),
child: Column(
children: [
Utils.buildImgWithAssets(icon: "assets/images/png/smartwatches/Huawei_Watch.png", width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h),
"Huawei Watch".needTranslation.toText16(isBold: true),
CustomButton(
text: LocaleKeys.selectSmartWatch.tr(context: context),
onPressed: () {
// context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.huawei, "assets/images/png/smartwatches/Huawei_Watch.png");
// getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage(
// smartwatchDetails: SmartwatchDetails(SmartWatchTypes.huawei,
// "assets/images/png/smartwatches/Huawei_Watch.png",
// AppAssets.bluetooth,
// LocaleKeys.huaweihealthapplicationshouldbeinstalledinyourphone.tr(context: context),
// LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
// LocaleKeys.huaweiwatchshouldbeconnected.tr(context: context)),
// ));
showUnavailableDialog(context);
},
backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
isBold: true,
borderRadius: 12.r,
height: 40.h,
).paddingSymmetrical(16.w, 12.h),
],
Container(
decoration:
RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: Column(
children: [
Utils.buildImgWithAssets(
icon:
"assets/images/png/smartwatches/Whoop_Watch.png",
width: 136.w,
height: 136.h)
.paddingSymmetrical(24.w, 8.h),
"whoopwatch"
.tr()
.needTranslation
.toText16(isBold: true),
CustomButton(
text: LocaleKeys.selectSmartWatch
.tr(context: context),
onPressed: () {
showUnavailableDialog(context);
// context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.whoop, "assets/images/png/smartwatches/Whoop_Watch.png");
// getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage(
// smartwatchDetails: SmartwatchDetails(SmartWatchTypes.whoop,
// "assets/images/png/smartwatches/Whoop_Watch.png",
// AppAssets.bluetooth,
// LocaleKeys.whoophealthapplicationshouldbeinstalledinyourphone.tr(context: context),
// LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
// LocaleKeys.whoopwatchshouldbeconnected.tr(context: context)),
// ));
},
backgroundColor:
AppColors.primaryRedColor.withAlpha(40),
borderColor:
AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
isBold: true,
borderRadius: 12.r,
height: 40.h,
).paddingSymmetrical(16.w, 12.h),
],
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: Column(
children: [
Utils.buildImgWithAssets(icon: "assets/images/png/smartwatches/Whoop_Watch.png", width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h),
"Whoop Watch".needTranslation.toText16(isBold: true),
CustomButton(
text: LocaleKeys.selectSmartWatch.tr(context: context),
onPressed: () {
showUnavailableDialog(context);
// context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.whoop, "assets/images/png/smartwatches/Whoop_Watch.png");
// getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage(
// smartwatchDetails: SmartwatchDetails(SmartWatchTypes.whoop,
// "assets/images/png/smartwatches/Whoop_Watch.png",
// AppAssets.bluetooth,
// LocaleKeys.whoophealthapplicationshouldbeinstalledinyourphone.tr(context: context),
// LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
// LocaleKeys.whoopwatchshouldbeconnected.tr(context: context)),
// ));
},
backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
isBold: true,
borderRadius: 12.r,
height: 40.h,
).paddingSymmetrical(16.w, 12.h),
],
),
),
],
],
),
),
),
],
],
),
),
),
),
);
);
});
}
void showUnavailableDialog(BuildContext context) {
@ -229,7 +295,8 @@ class SmartwatchHomePage extends StatelessWidget {
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.featureComingSoonDescription.tr(context: context),
loadingText:
LocaleKeys.featureComingSoonDescription.tr(context: context),
isShowActionButtons: false,
showOkButton: true,
onConfirmTap: () async {

@ -21,65 +21,76 @@ class SmartwatchInstructionsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: "How does it work".needTranslation,
bottomChild: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: CustomButton(
text: LocaleKeys.getStarted.tr(context: context),
onPressed: () {
context.read<HealthProvider>().initDevice();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 16.f,
isBold: true,
borderRadius: 12.r,
height: 50.h,
).paddingSymmetrical(24.w, 30.h),
),
child: Column(
mainAxisSize: MainAxisSize.max,
spacing: 18.h,
children: [
Utils.buildImgWithAssets(
icon: smartwatchDetails.watchIcon,
fit: BoxFit.contain,
height: 280.h,
width: 280.w,
return Consumer<HealthProvider>(builder: (context, healthProvider, child) {
final errorMessage = healthProvider.error;
if (errorMessage != null && errorMessage.isNotEmpty) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Utils.showToast(errorMessage, longDuration: false);
healthProvider.clearError();
});
}
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: "smartwatchHowItWorks".tr(context: context),
bottomChild: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: CustomButton(
text: LocaleKeys.getStarted.tr(context: context),
onPressed: () {
context.read<HealthProvider>().initDevice();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 16.f,
isBold: true,
borderRadius: 12.r,
height: 50.h,
).paddingSymmetrical(24.w, 30.h),
),
DecoratedBox(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
child: Column(
children: [
watchContentDetails(
title: smartwatchDetails.detailsTitle,
description: smartwatchDetails.details,
icon: smartwatchDetails.smallIcon,
descriptionTextColor: AppColors.primaryRedColor,
),
Divider(
color: AppColors.dividerColor,
thickness: 1.h,
).paddingOnly(top: 16.h, bottom: 16.h),
watchContentDetails(
title: smartwatchDetails.secondTitle,
description: LocaleKeys.updatetheinformation.tr(),
icon: AppAssets.bluetooth,
descriptionTextColor: AppColors.greyTextColor,
),
],
).paddingSymmetrical(16.w, 16.h),
)
],
).paddingSymmetrical(24.w, 16.h),
),
child: Column(
mainAxisSize: MainAxisSize.max,
spacing: 18.h,
children: [
Utils.buildImgWithAssets(
icon: smartwatchDetails.watchIcon,
fit: BoxFit.contain,
height: 280.h,
width: 280.w,
),
DecoratedBox(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
child: Column(
children: [
watchContentDetails(
title: smartwatchDetails.detailsTitle,
// description: smartwatchDetails.details,
description: "",
icon: smartwatchDetails.smallIcon,
descriptionTextColor: AppColors.primaryRedColor,
),
Divider(
color: AppColors.dividerColor,
thickness: 1.h,
).paddingOnly(top: 16.h, bottom: 16.h),
watchContentDetails(
title: smartwatchDetails.secondTitle,
description: LocaleKeys.updatetheinformation.tr(),
icon: AppAssets.bluetooth,
descriptionTextColor: AppColors.greyTextColor,
),
],
).paddingSymmetrical(16.w, 16.h),
)
],
).paddingSymmetrical(24.w, 16.h),
),
);
}
);
}

@ -819,6 +819,7 @@ class _AncillaryOrderPaymentPageState extends State<AncillaryOrderPaymentPage> {
applePayShaRequestPhrase: payfortViewModel.payfortProjectDetailsRespModel!.shaRequest,
currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED",
onFailed: (failureResult) async {
payfortViewModel.addApplePayPayfortResponse(failureResult.response);
log("failureResult: ${failureResult.message.toString()}");
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
@ -830,6 +831,7 @@ class _AncillaryOrderPaymentPageState extends State<AncillaryOrderPaymentPage> {
);
},
onSucceeded: (successResult) async {
payfortViewModel.addApplePayPayfortResponse(successResult);
LoaderBottomSheet.hideLoader();
log("successResult: ${successResult.responseMessage.toString()}");
selectedPaymentMethod = successResult.paymentOption ?? "VISA";

@ -17,10 +17,12 @@ class LocalAuthService {
final isAuthenticated = await localAuth.authenticate(
localizedReason: 'Please authenticate to proceed',
options: const AuthenticationOptions(
biometricOnly: true,
stickyAuth: true,
),
persistAcrossBackgrounding: false, // Replaces stickyAuth
biometricOnly: true,
// options: const AuthenticationOptions(
// biometricOnly: true,
// stickyAuth: true,
// ),
);
return isAuthenticated;

@ -82,7 +82,7 @@ class SecurityServiceImpl implements SecurityService {
onObfuscationIssues: () => _handleThreat('Obfuscation Issues', ThreatSeverity.warning),
onDebug: () => _handleThreat('Debug Mode', ThreatSeverity.critical),
onDeviceBinding: () => _handleThreat('Device Binding', ThreatSeverity.critical),
onDeviceID: () => _handleThreat('Device ID Mismatch', ThreatSeverity.critical),
onDeviceID: () => _handleThreat('Device ID Mismatch', ThreatSeverity.warning),
onHooks: () => _handleThreat('Hooks Detected', ThreatSeverity.critical),
onPasscode: () => _handleThreat('Passcode Not Set', ThreatSeverity.warning),
onPrivilegedAccess: () => _handleThreat('Privileged Access (Root/Jailbreak)', ThreatSeverity.critical),

@ -93,16 +93,12 @@ class _SplashScreenState extends State<SplashPage> {
if (isAppOpenedFromCall) {
navigateToTeleConsult();
} else {
if (Utils.havePrivilege(124)) {
Navigator.of(getIt.get<NavigationService>().navigatorKey.currentContext!).pushAndRemoveUntil(CustomPageRoute(page: AppClosedPage()), (r) => false);
if (await Utils.getBoolFromPrefs(CacheConst.firstLaunch)) {
// Navigator.of(context).pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: OnboardingScreen())));
Navigator.of(getIt.get<NavigationService>().navigatorKey.currentContext!).pushReplacement(FadePage(page: OnboardingScreen()));
} else {
if (await Utils.getBoolFromPrefs(CacheConst.firstLaunch)) {
// Navigator.of(context).pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: OnboardingScreen())));
Navigator.of(getIt.get<NavigationService>().navigatorKey.currentContext!).pushReplacement(FadePage(page: OnboardingScreen()));
} else {
// Navigator.of(context).pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: LandingNavigation())));
Navigator.of(getIt.get<NavigationService>().navigatorKey.currentContext!).pushReplacement(FadePage(page: LandingNavigation()));
}
// Navigator.of(context).pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: LandingNavigation())));
Navigator.of(getIt.get<NavigationService>().navigatorKey.currentContext!).pushReplacement(FadePage(page: LandingNavigation()));
}
}
}
@ -127,24 +123,24 @@ class _SplashScreenState extends State<SplashPage> {
// Set initial app context tags
try {
final appState = getIt.get<AppState>();
// Set device and app metadata
Clarity.setCustomTag('app_version', ApiConsts.appVersionID.toString());
Clarity.setCustomTag('device_type', appState.deviceTypeID ?? 'unknown');
Clarity.setCustomTag('platform', Platform.isIOS ? 'ios' : 'android');
// Set user context if authenticated
if (appState.isAuthenticated) {
final user = appState.getAuthenticatedUser();
if (user != null) {
// Set user ID for session tracking
Clarity.setCustomUserId(user.patientId.toString());
// Set custom tags for filtering sessions
Clarity.setCustomTag('user_type', user.patientType?.toString() ?? 'unknown');
Clarity.setCustomTag('user_segment', user.outSa == 0 ? 'in_sa' : 'out_sa');
Clarity.setCustomTag('auth_status', 'authenticated');
// Optional: Set other non-sensitive user properties
if (user.mobileNumber != null) {
// Mask phone number for privacy (show only last 4 digits)
@ -155,10 +151,9 @@ class _SplashScreenState extends State<SplashPage> {
} else {
Clarity.setCustomTag('auth_status', 'guest');
}
// Send initialization event
Clarity.sendCustomEvent('app_initialized');
} catch (e) {
debugPrint('Failed to set Clarity user context: $e');
}
@ -171,8 +166,7 @@ class _SplashScreenState extends State<SplashPage> {
// GetIt.instance<CacheService>().remove(key: CacheConst.isAppOpenedFromCall);
Utils.removeFromPrefs(CacheConst.isAppOpenedFromCall);
Navigator.of(GetIt.instance<NavigationService>().navigatorKey.currentContext!)
.pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: LandingNavigation())));
Navigator.of(GetIt.instance<NavigationService>().navigatorKey.currentContext!).pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: LandingNavigation())));
Navigator.pushReplacementNamed(
// context,
GetIt.instance<NavigationService>().navigatorKey.currentContext!,
@ -392,8 +386,6 @@ class _SplashScreenState extends State<SplashPage> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.whiteColor,
body: Lottie.asset(AppAnimations.loadingAnimation,
repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.fill)
.center);
body: Lottie.asset(AppAnimations.loadingAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.fill).center);
}
}

@ -117,10 +117,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.4.1"
version: "1.4.0"
chewie:
dependency: transitive
description:
@ -1105,6 +1105,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.12.0+301"
huawei_push:
dependency: "direct main"
description:
name: huawei_push
sha256: acc149482c03d0efe3ae50236b1a0aac9c0808cba07ad4eb41f06475b04c06f6
url: "https://pub.dev"
source: hosted
version: "6.15.0+300"
image:
dependency: transitive
description:
@ -1397,26 +1405,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.19"
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.13.0"
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.17.0"
mime:
dependency: transitive
description:
@ -2010,10 +2018,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev"
source: hosted
version: "0.7.11"
version: "0.7.7"
time:
dependency: transitive
description:
@ -2295,5 +2303,5 @@ packages:
source: hosted
version: "1.2.0"
sdks:
dart: ">=3.10.0-0 <4.0.0"
dart: ">=3.9.0 <4.0.0"
flutter: ">=3.35.0"

@ -2,8 +2,8 @@ name: hmg_patient_app_new
description: "New HMG Patient App"
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 0.0.49+50
#version: 0.0.17+1
#version: 4.6.046+1
version: 4.6.1004+40501004
environment:
sdk: ">=3.6.0 <4.0.0"
@ -17,17 +17,17 @@ dependencies:
cached_network_image: ^3.4.1
http: ^1.5.0
flutter_svg: ^2.2.0
shared_preferences: ^2.5.3
connectivity_plus: ^6.1.5
shared_preferences: ^2.5.5
connectivity_plus: ^7.3.1
auto_size_text: ^3.0.0
shimmer: ^3.0.0
sizer: ^3.1.3
easy_localization: ^3.0.8
fluttertoast: ^8.2.12
flutter_rating_bar: ^4.0.1
firebase_messaging: ^15.2.10
firebase_messaging: ^16.7.0
# firebase_messaging: any
firebase_core: any
firebase_core: ^4.15.0
# firebase_core: ^3.13.1
permission_handler: ^12.0.1
flutter_local_notifications: ^19.4.1
@ -45,7 +45,7 @@ dependencies:
flutter_ios_voip_kit_karmm: ^0.8.0
image_picker: ^1.2.0
file_picker: 10.3.8
local_auth: ^2.3.0
local_auth: ^3.0.2
share_plus: ^11.1.0
device_calendar_plus:
path: ./package/device_calendar_plus
@ -63,18 +63,17 @@ dependencies:
geolocator: ^14.0.2
dropdown_search: ^6.0.2
google_maps_flutter: ^2.13.1
# flutter_zoom_videosdk: 2.1.10
flutter_zoom_videosdk: ^2.5.10
flutter_zoom_videosdk: 2.1.10
dart_jsonwebtoken: ^3.2.0
dartz: ^0.10.1
equatable: ^2.0.7
google_api_availability: ^5.0.1
firebase_analytics: ^11.5.1
firebase_crashlytics: ^4.3.8
firebase_remote_config: ^5.5.0
firebase_analytics: ^12.6.0
firebase_crashlytics: ^5.4.0
firebase_remote_config: ^6.7.0
jiffy: ^6.4.3
# hijri_gregorian_calendar:
# path: /Users/aamir/StudioProjects/hijri_gregorian_calendar
# hijri_gregorian_calendar:
# path: /Users/aamir/StudioProjects/hijri_gregorian_calendar
sms_otp_auto_verify: ^2.2.0
web: any
flutter_staggered_animations: ^1.1.1
@ -91,7 +90,7 @@ dependencies:
path: package/flutter_swiper_view
flutter_callkit_incoming: 3.0.0
in_app_update: ^4.2.5
# device_preview: ^1.3.1
# device_preview: ^1.3.1
image_picker_android: ^0.8.13+16
image_picker_platform_interface: ^2.10.0
@ -102,13 +101,16 @@ dependencies:
intl: ^0.20.2
flutter_widget_from_html: ^0.17.1
huawei_map: ^6.12.0+301
huawei_push: ^6.15.0+300
flutter_image_compress: ^2.3.0
scrollable_positioned_list: ^0.3.8
in_app_review: ^2.0.11
flutter_paytabs_bridge: ^2.7.14
clarity_flutter: 1.9.0
flutter_amazonpaymentservices: ^0.0.13
clarity_flutter: ^1.10.0
# flutter_amazonpaymentservices: ^0.0.13
flutter_amazonpaymentservices:
path: ./package/flutter_amazonpaymentservices
screen_brightness: ^1.0.1
flutter_screenshot_blocker: ^1.0.4
cloudflare_turnstile: ^3.7.2

Loading…
Cancel
Save