Wd:design updated for the live activity

live_activities
tahaalam 4 days ago
parent cacc0264bc
commit 51fe8066a8

Binary file not shown.

@ -42,41 +42,30 @@ class CustomLiveActivityManager(context: Context) :
Log.d("updateRemoteViews", "current ticket is ${data["queueNo"] as? String ?: ""}")
Log.d("updateRemoteViews", "remoteViews is $remoteViews")
val (nextStepButtonBackground, textColor, containerBackground) = when (data["callType"] as? Int) {
0 -> Triple(R.drawable.grey_rounded_corner_widget, R.color.text_color, R.drawable.whitebg_yellow_border_rounded_corner_widget)
1 -> Triple(R.drawable.dark_red_rounded_corner_widget, R.color.colorWhite, R.drawable.whitebg_red_border_rounded_corner_widget)
2 -> Triple(R.drawable.green_rounded_corner_widget, R. color.colorWhite, R. drawable.whitebg_green_border_rounded_corner_widget)
else -> Triple(R. drawable.grey_rounded_corner_widget, R.color.text_color, R.drawable.whitebg_yellow_border_rounded_corner_widget)
val progress = when (data["callType"] as? Int) {
0 -> 33
1 -> 66
2 ->99
else -> 99
}
var (currentServingBackground, currentServingFontColor) = when (data["currentlyServingCallType"] as? Int) {
1->Pair(R.drawable.red_rounded_corner_widget, R.color.colorWhite)
else ->Pair(R.drawable.green_rounded_corner_widget, R.color.colorWhite)
}
remoteViews.setInt(R.id.nextStep, "setBackgroundResource", nextStepButtonBackground)
remoteViews.setInt(R.id.status, "setBackgroundResource", currentServingBackground)
remoteViews.setInt(R.id.container, "setBackgroundResource", containerBackground)
remoteViews.setTextColor(R.id.nextStep, ContextCompat.getColor(context, textColor))
remoteViews.setTextColor(R.id.status, ContextCompat.getColor(context, currentServingFontColor))
remoteViews.setTextViewText(R.id.countvalue, data["queueNo"] as? String ?: "")
remoteViews.setTextViewText(R.id.status, data["currentlyServingStatus"] as? String ?: "")
remoteViews.setTextViewText(R. id.currentlyserving, data["currentlyServingTitle"] as? String ?: "")
remoteViews.setTextViewText(R.id.nextStep, data["nextTicketStatus"] as? String ?: "")
remoteViews.setTextViewText(R.id.queue_number, data["queueNo"] as? String ?: "")
remoteViews.setTextViewText(R.id.currentServingStatus, data["currentlyServingStatus"] as? String ?: "")
remoteViews.setTextViewText(R. id.serving_number, data["currentlyServingToken"] as? String ?: "")
remoteViews.setTextViewText(R.id.status_text, data["nextTicketStatus"] as? String ?: "")
remoteViews.setTextViewText(R.id.queue_label, data["yourTicketHeader"] as? String ?: "")
remoteViews.setTextViewText(R.id.serving_label, data["currentlyServingTitle"] as? String ?: "")
}
private suspend fun updateCollapsedView(data: Map<String, Any>) {
Log.d("updateCollapsedView", "current ticket is ${data["queueNo"] as? String ?: ""}")
Log.d("updateCollapsedView", "remoteViews is $collapesView")
val containerBackground = when (data["callType"] as? Int) {
0 -> R.drawable.whitebg_yellow_border_rounded_corner_widget
1 -> R. drawable.whitebg_red_border_rounded_corner_widget
2 -> R.drawable. whitebg_green_border_rounded_corner_widget
else -> R.drawable.whitebg_yellow_border_rounded_corner_widget
}
collapesView.setInt(R.id.container, "setBackgroundResource", containerBackground)
collapesView.setTextViewText(R.id.countvalue_collapsed, data["queueNo"] as? String ?: "")
collapesView.setTextViewText(R.id.queue_number, data["queueNo"] as? String ?: "")
remoteViews.setTextViewText(R.id.queue_label, data["yourTicketHeader"] as? String ?: "")
}
override suspend fun buildNotification(

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:pathData="M8.333,31.667V36.667L31.667,36.667V31.667C31.667,25.223 26.444,20 20,20C13.557,20 8.333,25.223 8.333,31.667Z"
android:strokeAlpha="0.4"
android:fillColor="#9C9C9C"
android:fillAlpha="0.4"/>
<path
android:pathData="M6.667,2.084C5.976,2.084 5.417,2.644 5.417,3.334C5.417,4.024 5.976,4.584 6.667,4.584H7.083L7.083,8.334C7.083,13.481 10.094,17.925 14.449,20.001C10.094,22.077 7.083,26.521 7.083,31.667L7.083,35.417H6.667C5.976,35.417 5.417,35.977 5.417,36.667C5.417,37.358 5.976,37.917 6.667,37.917L33.333,37.917C34.023,37.917 34.583,37.358 34.583,36.667C34.583,35.977 34.023,35.417 33.333,35.417H32.917V31.667C32.917,26.521 29.906,22.077 25.55,20.001C29.906,17.925 32.917,13.481 32.917,8.334V4.584H33.333C34.023,4.584 34.583,4.024 34.583,3.334C34.583,2.644 34.023,2.084 33.333,2.084L6.667,2.084ZM30.417,4.584L9.583,4.584L9.583,8.334C9.583,14.087 14.247,18.751 20,18.751C25.753,18.751 30.417,14.087 30.417,8.334V4.584ZM30.417,35.417V31.667C30.417,25.914 25.753,21.251 20,21.251C14.247,21.251 9.583,25.914 9.583,31.667V35.417L30.417,35.417Z"
android:fillColor="#2E3039"
android:fillType="evenOdd"/>
</vector>

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M5.25,8.895C5.388,8.895 5.518,8.96 5.6,9.07L7,10.937L8.4,9.07C8.483,8.96 8.612,8.895 8.75,8.895C9.278,8.895 9.724,8.895 10.067,8.926C10.421,8.958 10.73,9.026 11.011,9.188C11.343,9.38 11.619,9.656 11.811,9.989C11.973,10.27 12.041,10.579 12.073,10.932C12.104,11.276 12.104,11.701 12.104,12.229V12.833C12.104,13.074 11.908,13.27 11.667,13.27H2.333C2.092,13.27 1.896,13.074 1.896,12.833V12.229C1.896,11.701 1.896,11.276 1.927,10.932C1.959,10.579 2.027,10.27 2.189,9.989C2.381,9.656 2.657,9.38 2.99,9.188C3.27,9.026 3.58,8.958 3.933,8.926C4.276,8.895 4.723,8.895 5.25,8.895Z"
android:fillColor="#18C273"/>
<path
android:pathData="M9.734,4.719L10.316,2.358C10.517,1.539 9.908,0.729 9.055,0.729H4.945C4.092,0.729 3.483,1.539 3.685,2.358L4.266,4.719V5.833C4.266,7.356 5.483,8.604 7,8.604C8.517,8.604 9.734,7.356 9.734,5.833V4.719ZM5.141,5.103H8.859V5.833C8.859,6.886 8.02,7.729 7,7.729C5.98,7.729 5.141,6.886 5.141,5.833V5.103ZM7,1.604C7.242,1.604 7.438,1.799 7.438,2.041V2.478H7.875C8.117,2.478 8.313,2.674 8.313,2.916C8.313,3.158 8.117,3.353 7.875,3.353H7.438V3.791C7.438,4.033 7.242,4.229 7,4.229C6.758,4.229 6.563,4.033 6.563,3.791V3.353H6.125C5.884,3.353 5.688,3.158 5.688,2.916C5.688,2.674 5.884,2.478 6.125,2.478H6.563V2.041C6.563,1.799 6.758,1.604 7,1.604Z"
android:fillColor="#18C273"
android:fillType="evenOdd"/>
</vector>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Background -->
<item
android:id="@android:id/background">
<shape android:shape="rectangle">
<solid android:color="#E8E8E8" />
<corners android:radius="3dp" />
</shape>
</item>
<!-- Progress -->
<item
android:id="@android:id/progress">
<clip>
<shape android:shape="rectangle">
<solid android:color="#18C273" />
<corners android:radius="3dp" />
</shape>
</clip>
</item>
</layer-list>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#00BFA5" />
<size
android:width="16dp"
android:height="16dp" />
<stroke
android:color="#FFFFFF"
android:width="2dp" />
</shape>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="24dp" />
</shape>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="8dp" />
</shape>

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="13"
android:viewportHeight="13">
<path
android:pathData="M6.5,6.5m-5.5,0a5.5,5.5 0,1 1,11 0a5.5,5.5 0,1 1,-11 0"
android:strokeWidth="2"
android:fillColor="#18C273"
android:strokeColor="#ffffff"/>
</vector>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#1A18C273" />
<corners android:radius="8dp" />
</shape>

@ -1,116 +1,176 @@
<?xml version="1.0" encoding="utf-8"?><!-- 1. Changed root to a RemoteViews-compatible layout like RelativeLayout -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/whitebg_red_border_rounded_corner_widget"
android:padding="@dimen/_12sdp">
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/nextStep_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView
android:id="@+id/countvalue"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="@id/nextStep_ll"
android:layout_alignParentStart="true"
android:paddingEnd="@dimen/_10sdp"
android:text="it is a status"
android:fontFamily="@font/poppins_medium"
android:textColor="@color/black_text"
android:gravity="top"
android:textSize="28sp"
android:textStyle="bold" />
android:layout_height="match_parent"
android:background="@drawable/queue_card_background"
android:orientation="vertical"
android:padding="24dp">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
>
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/hmg" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_weight=".7"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/queue_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="You queue number"
android:textColor="@color/queue_text_secondary"
android:textSize="14sp"
android:textStyle="normal" />
<TextView
android:id="@+id/currentlyserving_header"
<!-- Queue Number: OB-212 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/queue_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="OB-212"
android:textColor="@color/queue_text_primary"
android:textSize="32sp"
android:textStyle="bold" />
</RelativeLayout>
</LinearLayout>
<!-- Hourglass Icon -->
<ImageView
android:id="@+id/hourglass_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:scaleType="centerInside"
android:src="@drawable/icon" />
</LinearLayout>
<!-- Status Message in green box -->
<LinearLayout
android:id="@+id/status_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Currently Serving:"
android:textColor="@color/black_text"
android:layout_marginEnd="12dp"
android:layout_marginBottom="10dp"
android:textSize="14sp"
android:textStyle="bold"
android:fontFamily="@font/poppins_medium"
android:layout_marginTop="8dp"
android:background="@drawable/status_box_background"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingTop="8dp"
android:paddingEnd="12dp"
android:paddingBottom="8dp">
android:layout_below="@id/nextStep_ll"
android:layout_alignParentStart="true"
/>
<ImageView
android:id="@+id/status_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="@drawable/profession" />
<TextView
android:id="@+id/status_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="Please got to room no. 5 for vital signs"
android:textColor="@color/queue_status_green"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/currentlyserving_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/currentlyserving_header"
android:layout_alignParentStart="true"
android:orientation="horizontal"
>
<ProgressBar
android:id="@+id/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_marginTop="16dp"
android:max="100"
android:progress="33"
android:progressDrawable="@drawable/progress_bar_drawable" />
<!-- Bottom Section: Current Serving and Role -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="12dp"
android:gravity="bottom|center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/currentlyserving"
<!-- Current Serving -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="it is a status"
android:textColor="@color/black_text"
android:textStyle="bold"
android:gravity="center_vertical"
android:fontFamily="@font/poppins_medium"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
android:gravity="start|center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/serving_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Current Serving"
android:textColor="@color/queue_text_secondary"
android:textSize="14sp" />
<TextView
android:id="@+id/serving_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="3731"
android:textColor="@color/queue_text_primary"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<!-- Visiting Nurse Badge -->
<LinearLayout
android:id="@+id/role_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/status_box_background"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingTop="6dp"
android:paddingEnd="12dp"
android:paddingBottom="6dp">
<ImageView
android:id="@+id/role_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="@drawable/profession" />
<TextView
android:id="@+id/currentServingStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text="Visiting Nurse"
android:textColor="@color/queue_status_green"
android:textSize="10sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/red_rounded_corner_widget"
android:paddingStart="@dimen/_10sdp"
android:paddingTop="@dimen/_4sdp"
android:paddingEnd="@dimen/_10sdp"
android:paddingBottom="@dimen/_4sdp"
android:text="it is a status"
android:fontFamily="@font/poppins_medium"
android:layout_gravity="end"
android:textColor="@color/red_color_text" />
</LinearLayout>
<TextView
android:id="@+id/nextStep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/currentlyserving_ll"
android:layout_alignParentStart="true"
android:background="@drawable/red_rounded_corner_widget"
android:fontFamily="@font/poppins_medium"
android:gravity="bottom"
android:layout_marginTop="@dimen/_12sdp"
android:paddingStart="@dimen/_10sdp"
android:paddingTop="@dimen/_4sdp"
android:paddingEnd="@dimen/_10sdp"
android:paddingBottom="@dimen/_4sdp"
android:text="it is a status" />
</RelativeLayout>
</FrameLayout>

@ -1,32 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 1. Changed root to a RemoteViews-compatible layout like RelativeLayout -->
<RelativeLayout
android:id="@+id/container"
xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/_12sdp"
android:background="@drawable/whitebg_red_border_rounded_corner_widget">
<TextView
android:id="@+id/countvalue_collapsed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/img"
android:layout_alignBottom="@+id/img"
android:layout_alignParentStart="true"
android:text="it is a status"
android:gravity="center"
android:textColor="@color/black_text"
android:textSize="@dimen/_14ssp"
android:textStyle="bold" />
<ImageView
android:id="@+id/img"
android:layout_width="@dimen/_34sdp"
android:layout_height="@dimen/_34sdp"
android:src="@drawable/hmg"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
android:background="@drawable/queue_card_background_low_radius">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"
android:gravity="center"
>
<LinearLayout
android:layout_width="0dp"
android:layout_weight=".7"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/queue_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="You queue number"
android:textColor="@color/queue_text_secondary"
android:textSize="10sp"
android:textStyle="normal" />
<!-- Queue Number: OB-212 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/queue_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="OB-212"
android:textColor="@color/queue_text_primary"
android:textSize="22sp"
android:textStyle="bold" />
</RelativeLayout>
</LinearLayout>
<!-- Hourglass Icon -->
<ImageView
android:id="@+id/hourglass_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:scaleType="centerInside"
android:src="@drawable/icon" />
</LinearLayout>
</FrameLayout>

@ -6,4 +6,8 @@
<color name="inactive_color">#332E3039</color>
<color name="text_color">#A2A2A2</color>
<color name="colorWhite">#FFFF</color>
<color name="queue_text_secondary">#8F9AA3</color>
<color name="queue_text_primary">#2E3039</color>
<color name="queue_status_green">#18C273</color>
</resources>

@ -877,5 +877,9 @@
"walkin": "زيارة بدون موعد",
"laserClinic": "عيادة الليزر",
"continueString": "يكمل",
"covid_info": "تجري مستشفيات د. سليمان الحبيب فحص فيروس كورونا المستجد وتصدر شهادات السفر على مدار الساعة، طوال أيام الأسبوع، وبسرعة ودقة عالية. يمكن للراغبين في الاستفادة من هذه الخدمة زيارة أحد فروع مستشفيات د. سليمان الحبيب وإجراء فحص كورونا خلال بضع دقائق والحصول على النتائج خلال عدة ساعات خدمة فحص فيروس كورونا Covid 19 بتقنية PCR للكشف عن الفيروس وفقاً لأعلى المعايير العالمية وبأحدث أجهزة RT-PCR عالية الدقة (GeneXpert الأمريكي وغيره)، وهي طرق معتمدة من قبل هيئة الغذاء والدواء وكذلك من قبل المركز السعودي للوقاية من الأمراض المُعدية"
"covid_info": "تجري مستشفيات د. سليمان الحبيب فحص فيروس كورونا المستجد وتصدر شهادات السفر على مدار الساعة، طوال أيام الأسبوع، وبسرعة ودقة عالية. يمكن للراغبين في الاستفادة من هذه الخدمة زيارة أحد فروع مستشفيات د. سليمان الحبيب وإجراء فحص كورونا خلال بضع دقائق والحصول على النتائج خلال عدة ساعات خدمة فحص فيروس كورونا Covid 19 بتقنية PCR للكشف عن الفيروس وفقاً لأعلى المعايير العالمية وبأحدث أجهزة RT-PCR عالية الدقة (GeneXpert الأمريكي وغيره)، وهي طرق معتمدة من قبل هيئة الغذاء والدواء وكذلك من قبل المركز السعودي للوقاية من الأمراض المُعدية",
"callForVitalSign": "استدعاء لأخذ العلامات الحيوية",
"callForDoctor": "استدعاء الطبيب",
"yourQueueNumber": "رقمك في الدور",
"currentServing": "الدور الحالي"
}

@ -873,5 +873,9 @@
"walkin": "Walk In",
"continueString": "Continue",
"laserClinic": "Laser Clinic",
"covid_info" :"Dr. Sulaiman Al Habib hospitals are conducting a test for the emerging corona virus and issuing travel certificates 24/7 in a short time and with high accuracy. Those wishing to benefit from this service can visit one of Dr. Sulaiman Al Habib branches to conduct a corona test within few minutes, and obtain the result within several hours. Corona Virus Covid 19 testing service with PCR technology to detect the virus according to the highest international standards and with the latest high-precision RT-PCR devices (American GeneXpert and others), That is approved by the Food and Drug Authority as well as by the Saudi Center for Infectious Diseases Prevention."
"covid_info" :"Dr. Sulaiman Al Habib hospitals are conducting a test for the emerging corona virus and issuing travel certificates 24/7 in a short time and with high accuracy. Those wishing to benefit from this service can visit one of Dr. Sulaiman Al Habib branches to conduct a corona test within few minutes, and obtain the result within several hours. Corona Virus Covid 19 testing service with PCR technology to detect the virus according to the highest international standards and with the latest high-precision RT-PCR devices (American GeneXpert and others), That is approved by the Food and Drug Authority as well as by the Saudi Center for Infectious Diseases Prevention.",
"callForVitalSign": "Call for vital signs",
"callForDoctor": "Call for Doctor",
"yourQueueNumber": "Your Queue Number",
"currentServing" : "Current Serving"
}

@ -1,13 +1,7 @@
//
// AppWidgetLiveActivity.swift
// AppWidget
//
// Created by Cloud Solutions on 15/12/2025.
//
import ActivityKit
import WidgetKit
import SwiftUI
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
public typealias LiveDeliveryData = ContentState // don't forget to add this line, otherwise, live activity will not display it.
@ -112,304 +106,86 @@ struct NotificationWidgetView: View {
private let data: NotificationWidgetData
init(data: NotificationWidgetData) {
print("it is being loaded")
self.data = data
}
var body : some View{
// ZStack(){
body2
// .frame(width: .infinity, height: 400 )
// .padding(.top, 340)
// .cornerRadius(20)
// }.background(data.colorConfig.containerBorderColor)
// .cornerRadius(20)
}
var body2: some View {
VStack(alignment: .leading, spacing: 0) {
// Top section with current ticket and image
HStack(alignment: .top, spacing: 0) {
// Current ticket value
Text(data.currentTicket)
.font(.custom("Poppins-Medium", size: 28))
.fontWeight(.bold)
.foregroundColor(.black)
.padding(.trailing, 10)
.frame(maxWidth: .infinity, alignment: .leading)
var body: some View {
ZStack {
data.colorConfig.containerBorderColor // Background color
.edgesIgnoringSafeArea(.all) // Ensure it covers the entire screen
VStack(alignment: .leading, spacing: 0) {
// Top section with current ticket and image
HStack(alignment: .top, spacing: 0) {
// Current ticket value
Text(data.currentTicket)
.font(.custom("Poppins-Medium", size: 28))
.fontWeight(.bold)
.foregroundColor(.black)
.padding(.trailing, 10)
.frame(maxWidth: .infinity, alignment: .leading)
Image(data.imageName)
.resizable()
.scaledToFit()
.frame(width: 34, height: 34)
}
.padding(.top, 16)
.padding(.horizontal, 16)
// Currently Serving Header
Text(data.currentlyServingHeader)
.font(.custom("Poppins-Medium", size: 14))
.fontWeight(.bold)
.foregroundColor(.black)
.padding(.trailing, 12)
.padding(.bottom, 10)
Image(data.imageName)
.resizable()
.scaledToFit()
.frame(width: 34, height: 34)
}
.padding(.top, 16)
.padding(.horizontal, 16)
// Currently Serving section with status
HStack(alignment: .center, spacing: 0) {
// Currently serving text
Text(data.currentlyServing)
.font(.custom("Poppins-Medium", size: 16))
// Currently Serving Header
Text(data.currentlyServingHeader)
.font(.custom("Poppins-Medium", size: 14))
.fontWeight(.bold)
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.trailing, 12)
.padding(.bottom, 10)
.padding(.horizontal, 16)
// Currently Serving section with status
HStack(alignment: .center, spacing: 0) {
// Currently serving text
Text(data.currentlyServing)
.font(.custom("Poppins-Medium", size: 16))
.fontWeight(.bold)
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .leading)
// Status badge
Text(data.status)
.font(.custom("Poppins-Medium", size: 12))
.foregroundColor(data.colorConfig.nextStepTextColor)
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color.inactiveColor.opacity(0.2))
)
}
.padding(.horizontal, 16)
// Status badge
Text(data.status)
Spacer()
// Next Step badge
Text(data.nextStep)
.font(.custom("Poppins-Medium", size: 12))
.foregroundColor(data.colorConfig.nextStepTextColor)
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color.inactiveColor.opacity(0.2))
.fill(data.colorConfig.nextStepBackground)
)
.padding(.horizontal, 16)
.padding(.bottom, 16)
}
.padding(.horizontal, 16)
Spacer()
// Next Step badge
Text(data.nextStep)
.font(.custom("Poppins-Medium", size: 12))
.foregroundColor(data.colorConfig.nextStepTextColor)
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(data.colorConfig.nextStepBackground)
)
.padding(.horizontal, 16)
.padding(.bottom, 16)
}
.background(Color.black.opacity(0.01))
.cornerRadius(20)
// .border(width: 10, edges: [.top, .bottom], color: data.colorConfig.containerBorderColor)
// .border(width: 2, edges: [.leading, .trailing], color: data.colorConfig.containerBorderColor)
// .overlay(
// RoundedRectangle(cornerRadius: 20)
// .stroke(data.colorConfig.containerBorderColor, lineWidth: 20)
// )
}
}
extension View {
func border(width: CGFloat, edges: [Edge], color: Color) -> some View {
overlay(EdgeBorder(width: width, edges: edges).foregroundColor(color))
.background(Color.white) // Ensure content has a white background
.cornerRadius(20)
}
}
struct EdgeBorder: Shape {
var width: CGFloat
var edges: [Edge]
func path(in rect: CGRect) -> Path {
edges.map { edge -> Path in
switch edge {
case .top: return Path(.init(x: rect.minX, y: rect.minY, width: rect.width, height: width))
case .bottom: return Path(.init(x: rect.minX, y: rect.maxY - width, width: rect.width, height: width))
case .leading: return Path(.init(x: rect.minX, y: rect.minY, width: width, height: rect.height))
case .trailing: return Path(.init(x: rect.maxX - width, y: rect.minY, width: width, height: rect.height))
}
}.reduce(into: Path()) { $0.addPath($1) }
.padding() // Add padding to ensure it doesn't touch the edges
}
}
}
// MARK: - Main Widget View
//working widget but the border is not appearing
// struct NotificationWidgetView: View {
// private let data: NotificationWidgetData
//
// init(data: NotificationWidgetData) {
// self.data = data
// }
//
// var body: some View {
// VStack(alignment: .leading, spacing: 0) {
//
// VStack(alignment: .leading, spacing: 0) {
// // Top section with current ticket and image
// HStack(alignment: .top, spacing: 0) {
// // Current ticket value
// Text(data.currentTicket)
// .font(.custom("Poppins-Medium", size: 28))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 10)
//
// .frame(maxWidth: .infinity, alignment: .leading)
//
// Image(data.imageName)
// .resizable()
// .scaledToFit()
// .frame(width: 34, height: 34)
// }
//
// // Currently Serving Header
// Text(data.currentlyServingHeader)
// .font(.custom("Poppins-Medium", size: 14))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 12)
// .padding(.bottom, 10)
//
// // Currently Serving section with status
// HStack(alignment: .center, spacing: 0) {
// // Currently serving text
// Text(data.currentlyServing)
// .font(.custom("Poppins-Medium", size: 16))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .frame(maxWidth: .infinity, alignment: .leading)
//
// // Status badge
// Text(data.status)
// .font(.custom("Poppins-Medium", size: 12))
// .foregroundColor(data.colorConfig.nextStepTextColor)
// .padding(.horizontal, 12)
// .padding(.vertical, 8)
// .background(
// RoundedRectangle(cornerRadius: 8)
// .fill(Color.inactiveColor.opacity(0.2))
// )
// }
//
// // Next Step badge
// Text(data.nextStep)
// .font(.custom("Poppins-Medium", size: 12))
// .foregroundColor(data.colorConfig.nextStepTextColor)
// .padding(.horizontal, 12)
// .padding(.vertical, 8)
// .background(
// RoundedRectangle(cornerRadius: 8)
// .fill(data.colorConfig.nextStepBackground)
// )
//
// }
//
//
// }.padding()
// .background( RoundedRectangle(cornerRadius: 20)
//
// .fill(Color.white)
// )
// // .border(data.colorConfig.containerBorderColor, width: 2)
//
// .overlay(
// RoundedRectangle(cornerRadius: 20)
// .stroke(data.colorConfig.containerBorderColor, lineWidth: 1)
// // RoundedRectangle(cornerRadius: 12, style: .continuous)
// // .stroke(data.colorConfig.containerBorderColor, lineWidth: 5)
// )
//
// // .padding(12)
// }
// }
// MARK: - Main Widget View
// struct NotificationWidgetView: View {
// private let data: NotificationWidgetData
//
// init(data: NotificationWidgetData) {
// self.data = data
// }
//
// var body: some View {
// // Use a ZStack as the base to layer the background and content
// ZStack {
// // Layer 1: Glass effect background with border on all sides
// RoundedRectangle(cornerRadius: 12, style: .continuous)
// .strokeBorder(data.colorConfig.containerBorderColor, lineWidth: 3)
// .background(
// RoundedRectangle(cornerRadius: 12, style: .continuous)
//
// .background(
// RoundedRectangle(cornerRadius: 12, style: .continuous)
// .fill(Color.white)
// )
// )
// .shadow(color: Color.black.opacity(0.1), radius: 8, x: 0, y: 4)
//
//
// // Layer 2: Your content, padded from the edges
// VStack(alignment: .leading, spacing: 0) {
// // Top section with current ticket and image
// HStack(alignment: .top, spacing: 0) {
// Text(data.currentTicket)
// .font(.custom("Poppins-Medium", size: 28))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 10)
//
// Spacer() // Pushes the image to the trailing edge
//
// Image(systemName: data.imageName)
// .resizable()
// .scaledToFit()
// .frame(width: 24, height: 24)
// .foregroundColor(.gray)
// }
//
// // Currently Serving Header
// Text(data.currentlyServingHeader)
// .font(.custom("Poppins-Medium", size: 14))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.top, 4) // Adjusted padding
// .padding(.bottom, 10)
//
// // Currently Serving section with status
// HStack(alignment: .center, spacing: 0) {
// Text(data.currentlyServing)
// .font(.custom("Poppins-Medium", size: 16))
// .fontWeight(.bold)
// .foregroundColor(.black)
//
// Spacer() // Pushes status to the trailing edge
//
// Text(data.status)
// .font(.custom("Poppins-Medium", size: 12))
// .foregroundColor(data.colorConfig.nextStepTextColor)
// .padding(.horizontal, 12)
// .padding(.vertical, 8)
// .background(
// RoundedRectangle(cornerRadius: 8)
// .fill(Color.inactiveColor.opacity(0.2))
// )
// }
//
// // Next Step badge
// Text(data.nextStep)
// .font(.custom("Poppins-Medium", size: 12))
// .foregroundColor(data.colorConfig.nextStepTextColor)
// .padding(.horizontal, 12)
// .padding(.vertical, 8)
// .background(
// RoundedRectangle(cornerRadius: 8)
// .fill(data.colorConfig.nextStepBackground)
// )
// .padding(.top, 10)
//
// // **CRITICAL FIX**: Pushes all content to the top
// // and makes the VStack fill the available height.
// Spacer(minLength: 0)
// }
// .padding(15) // Apply padding to the content VStack instead
// }
// }
// }
// MARK: - Live Activity Widget
@ -418,13 +194,16 @@ struct AppWidgetLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
// Extract parameters from Flutter
let title = sharedDefault.string(forKey: context.attributes.prefixedKey("title")) ?? "test"
let contentText = sharedDefault.string(forKey: context.attributes.prefixedKey("contentText")) ?? "test"
let currentTicket = sharedDefault.string(forKey: context.attributes.prefixedKey("currentTicket")) ?? "test"
let status = sharedDefault.string(forKey: context.attributes.prefixedKey("status")) ?? "test"
let currentlyServing = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServing")) ?? "test"
let nextStep = sharedDefault.string(forKey: context.attributes.prefixedKey("nextStep")) ?? "test"
let nextStepBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("nextStepBackground"))
print("it is being loaded")
// print("the queno is \(context.attributes.prefixedKey("title")) ===== \(sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) )")
let title = sharedDefault.string(forKey: context.attributes.prefixedKey("title")) ?? "testes"
let contentText = sharedDefault.string(forKey: context.attributes.prefixedKey("contentText")) ?? "tested"
let currentTicket = sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) ?? "test1234"
let status = sharedDefault.string(forKey: context.attributes.prefixedKey("callType")) ?? "test3345"
let currentlyServing = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingTitle")) ?? "tes"
let nextStep = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingStatus")) ??
"test111"
let nextStepBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("currentlyServingCallType"))
// Get color configuration based on nextStepBackground
let colorConfig = WidgetColorConfig.config(for: nextStepBackground)
@ -432,26 +211,27 @@ struct AppWidgetLiveActivity: Widget {
// Create widget data
let widgetData = NotificationWidgetData(
currentTicket: currentTicket,
currentlyServingHeader: "Currently Serving:",
currentlyServingHeader: "Currently Servingsssssssss:",
currentlyServing: currentlyServing,
status: status,
nextStep: nextStep,
imageName:"hmg",
colorConfig: colorConfig
)
// Lock screen/banner UI
NotificationWidgetView(data: widgetData)
.activityBackgroundTint(Color.clear)
.activitySystemActionForegroundColor(Color.black)
NotificationWidgetView(data: widgetData)
.activityBackgroundTint(Color.clear)
.activitySystemActionForegroundColor(Color.black)
} dynamicIsland: { context in
let currentTicket = sharedDefault.string(forKey: context.attributes.prefixedKey("currentTicket")) ?? ""
let status = sharedDefault.string(forKey: context.attributes.prefixedKey("status")) ?? ""
let currentlyServing = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServing")) ?? ""
let nextStep = sharedDefault.string(forKey: context.attributes.prefixedKey("nextStep")) ?? ""
let nextStepBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("nextStepBackground"))
let title = sharedDefault.string(forKey: context.attributes.prefixedKey("title")) ?? "testes"
let contentText = sharedDefault.string(forKey: context.attributes.prefixedKey("contentText")) ?? "tested"
let currentTicket = sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) ?? "test1234"
let status = sharedDefault.string(forKey: context.attributes.prefixedKey("callType")) ?? "test3345"
let currentlyServing = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingTitle")) ?? "tes"
let nextStep = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingStatus")) ??
"test111"
let nextStepBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("currentlyServingCallType"))
let colorConfig = WidgetColorConfig.config(for: nextStepBackground)
@ -536,7 +316,7 @@ struct AppWidgetLiveActivity: Widget {
.frame(width: 4, height: 4)
.foregroundColor(colorConfig.containerBorderColor)
}.padding(2)
}
.contentMargins(.all, 20,for: .expanded)
}
@ -557,7 +337,7 @@ struct NotificationWidgetView_Previews: PreviewProvider {
NotificationWidgetView(
data: NotificationWidgetData(
currentTicket: "42",
currentlyServingHeader: "Currently Serving:",
currentlyServingHeader: "Currently Serving3:",
currentlyServing: "Customer #15",
status: "Pending",
nextStep: "Next: Prepare Order",
@ -566,12 +346,12 @@ struct NotificationWidgetView_Previews: PreviewProvider {
)
)
.previewDisplayName("Yellow Border (0)")
// Preview with nextStepBackground = 1 (Red border)
NotificationWidgetView(
data: NotificationWidgetData(
currentTicket: "89",
currentlyServingHeader: "Currently Serving:",
currentlyServingHeader: "Currently Serving2:",
currentlyServing: "Customer #67",
status: "Active",
nextStep: "Next: Quality Check",
@ -580,12 +360,12 @@ struct NotificationWidgetView_Previews: PreviewProvider {
)
)
.previewDisplayName("Red Border (1)")
// Preview with nextStepBackground = 2 (Green border)
NotificationWidgetView(
data: NotificationWidgetData(
currentTicket: "125",
currentlyServingHeader: "Currently Serving:",
currentlyServingHeader: "Currently Serving1:",
currentlyServing: "Customer #98",
status: "Completed",
nextStep: "Next: Ready for Pickup",
@ -599,3 +379,4 @@ struct NotificationWidgetView_Previews: PreviewProvider {
.previewLayout(.sizeThatFits)
}
}

@ -0,0 +1,17 @@
//
// AppWidgetLiveActivityBundle.swift
// AppWidgetLiveActivity
//
// Created by Cloud Solutions on 27/01/2026.
//
import WidgetKit
import SwiftUI
@main
struct AppWidgetLiveActivityBundle: WidgetBundle {
var body: some Widget {
AppWidgetLiveActivity()
}
}

@ -0,0 +1,575 @@
import ActivityKit
import WidgetKit
import SwiftUI
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
public typealias LiveDeliveryData = ContentState // don't forget to add this line, otherwise, live activity will not display it.
public struct ContentState: Codable, Hashable { }
var id = UUID()
}
let sharedDefault = UserDefaults(suiteName: "group.alhabib.patientApp")!
struct AppWidgetAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
// Dynamic stateful properties about your activity go here!
var emoji: String
}
// Fixed non-changing properties about your activity go here!
var name: String
}
extension Color {
static let redColorText = Color(hex: "#ED1C2B")
static let yellowColor = Color(hex: "#FFAF15")
static let successColor = Color(hex: "#18C273")
static let inactiveColor = Color(hex: "#ED1C2B")
static let textColor = Color(hex: "#A2A2A2")
static let colorWhite = Color(hex: "#FFFFFF")
// Helper initializer for hex colors
init(hex: String) {
let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int: UInt64 = 0
Scanner(string: hex).scanHexInt64(&int)
let a, r, g, b: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(a, r, g, b) = (255, 0, 0, 0)
}
self.init(
.sRGB,
red: Double(r) / 255,
green: Double(g) / 255,
blue: Double(b) / 255,
opacity: Double(a) / 255
)
}
}
// MARK: - Widget Configuration based on nextStepBackground
struct WidgetColorConfig {
let nextStepBackground: Color
let nextStepTextColor: Color
let containerBorderColor: Color
static func config(for value: Int) -> WidgetColorConfig {
switch value {
case 0:
return WidgetColorConfig(
nextStepBackground: .inactiveColor,
nextStepTextColor: .textColor,
containerBorderColor: .yellowColor
)
case 1:
return WidgetColorConfig(
nextStepBackground: .redColorText,
nextStepTextColor: .colorWhite,
containerBorderColor: .redColorText
)
case 2:
return WidgetColorConfig(
nextStepBackground: .successColor,
nextStepTextColor: .colorWhite,
containerBorderColor: .successColor
)
default:
return WidgetColorConfig(
nextStepBackground: .inactiveColor,
nextStepTextColor: .textColor,
containerBorderColor: .yellowColor
)
}
}
}
// MARK: - Widget Data Model
struct NotificationWidgetData {
let currentTicket: String
let currentlyServingHeader: String
let currentlyServing: String
let status: String
let nextStep: String
let imageName: String
let colorConfig: WidgetColorConfig
let progress: Double
let yourTicketHeaderText : String
}
struct NotificationWidgetView: View {
private let data: NotificationWidgetData
private let backgroundColor: Color
let animateProgress = false
init(data: NotificationWidgetData, backgroundColor: Color = .white) {
print("it is being loaded")
self.data = data
self.backgroundColor = backgroundColor
}
var body : some View{
ZStack {
// Dark background
Color(red: 0.15, green: 0.15, blue: 0.15)
.ignoresSafeArea()
// Main card
VStack(alignment: .leading, spacing: 0) {
// Header section
HStack(alignment: .top) {
HStack( alignment: .center,spacing: 4) {
Text(data.currentTicket)
.font(.system(size: 32, weight: .bold, design: .default))
.foregroundColor(Color(red: 0, green: 0.2, blue: 0.4))
Text(data.yourTicketHeaderText)
.font(.system(size: 14, weight: .regular))
.foregroundColor(Color(hex: "#8F9AA3"))
}
Spacer()
// Hourglass icon
Image("clock")
.frame(width: 24, height:24 )
.foregroundColor(Color(hex: "#2E3039"))
.padding(.top, 4)
}
.padding(.top,4)
.padding(.bottom, 4)
// Alert banner
HStack(spacing: 4) {
Image("profession")
Text(data.nextStep)
.font(.system(size: 10, weight: .semibold))
.foregroundColor(Color(hex:"#18C273"))
}
.padding(8)
.background(Color(hex:"#1A18C273"))
.cornerRadius(8)
.padding(.bottom, 10)
// Progress bar
VStack(alignment: .leading) {
ZStack(alignment: .leading) {
// Background track
Capsule()
.fill(Color(red: 0.9, green: 0.9, blue: 0.9))
.frame(height: 4)
// Progress fill
Capsule()
.fill(Color.green)
.frame(width: data.progress, height: 4)
.animation(
Animation.easeInOut(duration: 1.5)
.delay(0.3),
value: animateProgress
)
ZStack{
Circle()
.fill(Color.white)
.frame(width: 12, height: 12)
Circle()
.fill(Color.green)
.frame(width: 10, height: 10)
.animation(
Animation.easeInOut(duration: 1.5)
.delay(0.3),
value: animateProgress
)
}
.offset(x:data.progress)
}
}
.padding(.bottom, 10)
// Footer section
HStack {
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 4) {
Text(data.currentlyServingHeader)
.font(.system(size: 14, weight: .regular))
.foregroundColor(Color(hex:"#8F9AA3"))
Text(data.currentlyServing)
.font(.system(size: 18, weight: .bold))
.foregroundColor(Color(hex:"#2E3039"))
}
}
Spacer()
// Visiting Nurse badge
HStack(spacing: 8) {
Image("profession")
.font(.system(size: 10, weight: .semibold))
.foregroundColor(Color(hex: "#18C273"))
Text(data.status)
.font(.system(size: 10, weight: .semibold))
.foregroundColor(Color(hex: "#18C273"))
}
.padding(8)
.background(Color(hex:"#1A18C273"))
.cornerRadius(8)
}
.padding(.horizontal, 8)
.padding(.bottom, 8)
}
.padding(24)
.background(backgroundColor)
.cornerRadius(24)
}
}
// var body2 : some View {
// Text(data.currentTicket)
// .font(.custom("Poppins-Medium", size: 28))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 10)
// .frame(maxWidth: .infinity, alignment: .leading)
// }
//current one that todo will be handled
// var body2: some View {
// VStack(alignment: .leading, spacing: 0) {
// // Top section with current ticket and image
// HStack(alignment: .top, spacing: 0) {
// // Current ticket value
// Text(data.currentTicket)
// .font(.custom("Poppins-Medium", size: 28))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 10)
// .frame(maxWidth: .infinity, alignment: .leading)
//
// Image(data.imageName)
// .resizable()
// .scaledToFit()
// .frame(width: 34, height: 34)
// }
// .padding(.top, 16)
// .padding(.horizontal, 16)
//
// // Currently Serving Header
// Text(data.currentlyServingHeader)
// .font(.custom("Poppins-Medium", size: 14))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 12)
// .padding(.bottom, 10)
// .padding(.horizontal, 16)
//
// // Currently Serving section with status
// HStack(alignment: .center, spacing: 0) {
// // Currently serving text
// Text(data.currentlyServing)
// .font(.custom("Poppins-Medium", size: 16))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .frame(maxWidth: .infinity, alignment: .leading)
//
// // Status badge
// Text(data.status)
// .font(.custom("Poppins-Medium", size: 12))
// .foregroundColor(data.colorConfig.nextStepTextColor)
// .padding(.horizontal, 12)
// .padding(.vertical, 8)
// .background(
// RoundedRectangle(cornerRadius: 8)
// .fill(Color.inactiveColor.opacity(0.2))
// )
// }
// .padding(.horizontal, 16)
// Spacer()
// // Next Step badge
// Text(data.nextStep)
// .font(.custom("Poppins-Medium", size: 12))
// .foregroundColor(data.colorConfig.nextStepTextColor)
// .padding(.horizontal, 12)
// .padding(.vertical, 8)
// .background(
// RoundedRectangle(cornerRadius: 8)
// .fill(data.colorConfig.nextStepBackground)
// )
// .padding(.horizontal, 16)
// .padding(.bottom, 16)
// }
// .background(Color.black.opacity(0.01))
// .cornerRadius(20)
// .border(width: 10, edges: [.top, .bottom], color: data.colorConfig.containerBorderColor)
// .border(width: 2, edges: [.leading, .trailing], color: data.colorConfig.containerBorderColor)
// .overlay(
// RoundedRectangle(cornerRadius: 20)
// .stroke(data.colorConfig.containerBorderColor, lineWidth: 20)
// )
// }
}
// MARK: - Live Activity Widget
struct AppWidgetLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
// Extract parameters from Flutter
// print("the queno is \(context.attributes.prefixedKey("title")) ===== \(sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) )")
// let title = sharedDefault.string(forKey: context.attributes.prefixedKey("title")) ?? "testes"
// let contentText = sharedDefault.string(forKey: context.attributes.prefixedKey("contentText")) ?? "tested"
// let currentTicket = sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) ?? "test1234"
// let status = sharedDefault.string(forKey: context.attributes.prefixedKey("callType")) ?? "test3345"
// let currentlyServing = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingTitle")) ?? "tes"
// let nextStep = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingStatus")) ??
// "test111"
// let nextStepBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("currentlyServingCallType"))
// let title = sharedDefault.string(forKey: context.attributes.prefixedKey("title")) ?? "testes"
// let contentText = sharedDefault.string(forKey: context.attributes.prefixedKey("contentText")) ?? "tested"
let currentTicket = getValueFromSharedDefaults("queueNo")
let status = getValueFromSharedDefaults("currentlyServingStatus") ?? "test3345"
let currentlyServing = getValueFromSharedDefaults("currentlyServingToken")
let currentlyServingHeader = getValueFromSharedDefaults("currentlyServingTitle")
let yourTicketHeader = getValueFromSharedDefaults("yourTicketHeader")
let nextStep = getValueFromSharedDefaults("nextTicketStatus")
let nextStepBackground = Int(sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingCallType")) ?? "0") ?? 0
// Get color configuration based on nextStepBackground
let colorConfig = WidgetColorConfig.config(for: nextStepBackground)
// Create widget data
let widgetData = NotificationWidgetData(
currentTicket: currentTicket,
currentlyServingHeader: currentlyServingHeader,
currentlyServing: currentlyServing,
status: status,
nextStep: nextStep,
imageName:"hmg",
colorConfig: colorConfig,
progress: 33 * Double(nextStepBackground),
yourTicketHeaderText : yourTicketHeader,
)
//
// Lock screen/banner UI
NotificationWidgetView(data: widgetData)
// Text(widgetData.currentTicket)
// .font(.custom("Poppins-Medium", size: 28))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 10)
// .frame(maxWidth: .infinity, alignment: .leading)
} dynamicIsland: { context in
let currentTicket = getValueFromSharedDefaults("queueNo")
let status = getValueFromSharedDefaults("currentlyServingStatus") ?? "test3345"
let currentlyServing = getValueFromSharedDefaults("currentlyServingToken")
let nextStep = getValueFromSharedDefaults("nextTicketStatus")
let nextStepBackground = Int(sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingCallType")) ?? "0") ?? 0
let currentlyServingHeader = getValueFromSharedDefaults("currentlyServingTitle")
let yourTicketHeader = getValueFromSharedDefaults("yourTicketHeader")
let colorConfig = WidgetColorConfig.config(for: nextStepBackground)
let widgetData = NotificationWidgetData(
currentTicket: currentTicket,
currentlyServingHeader: currentlyServingHeader,
currentlyServing: currentlyServing,
status: status,
nextStep: nextStep,
imageName:"hmg",
colorConfig: colorConfig,
progress: 33 * Double(nextStepBackground),
yourTicketHeaderText: yourTicketHeader
)
return DynamicIsland {
//
// Lock screen/banner UI
// // Expanded UI
DynamicIslandExpandedRegion(.center) {
NotificationWidgetView(data: widgetData, backgroundColor: .black.opacity(0.4)).padding(-24)
}
// DynamicIslandExpandedRegion(.trailing) {
// Image("hmg")
// .resizable()
// .scaledToFit()
// .frame(width: 34, height: 34)
// .foregroundColor(.gray)
// }
//
// DynamicIslandExpandedRegion(.center) {
// VStack(spacing: 4) {
// Text("Currently Servings:")
// .font(.caption2)
// .foregroundColor(.secondary)
//
// Text(currentlyServing)
// .font(.caption)
// .fontWeight(.semibold)
// }
// }
//
// DynamicIslandExpandedRegion(.bottom) {
// HStack {
// Text(status)
// .font(.caption2)
// .padding(.horizontal, 8)
// .padding(.vertical, 4)
// .background(
// RoundedRectangle(cornerRadius: 6)
// .fill(colorConfig.nextStepBackground.opacity(0.2))
// )
//
// Spacer()
//
// Text(nextStep)
// .font(.caption2)
// .foregroundColor(colorConfig.nextStepTextColor)
// .padding(.horizontal, 8)
// .padding(.vertical, 4)
// .background(
// RoundedRectangle(cornerRadius: 6)
// .fill(colorConfig.nextStepBackground)
// )
// }
// .padding(.horizontal)
// }
} compactLeading: {
// Compact leading view
Text(currentTicket)
.font(.caption2)
.fontWeight(.bold)
} compactTrailing: {
// Compact trailing view
Image("hmg")
.resizable()
.scaledToFit()
.frame(width: 12, height: 12)
.foregroundColor(colorConfig.containerBorderColor).padding(4)
} minimal: {
// Minimal view
HStack{
Text(currentTicket)
.font(.caption2)
.fontWeight(.bold)
Spacer()
Image("hmg")
.resizable()
.scaledToFit()
.frame(width: 4, height: 4)
.foregroundColor(colorConfig.containerBorderColor)
}.padding(2)
}
}
}
}
extension LiveActivitiesAppAttributes {
func prefixedKey(_ key: String) -> String {
print("the id is \(id)")
return "\(id)_\(key)"
}
}
//struct NotificationWidgetView_Previews: PreviewProvider {
// static var previews: some View {
// Group {
// // Preview with nextStepBackground = 0 (Yellow border)
// NotificationWidgetView(
// data: NotificationWidgetData(
// currentTicket: "42",
// currentlyServingHeader: "Currently Serving3:",
// currentlyServing: "Customer #15",
// status: "Pending",
// nextStep: "Next: Prepare Order",
// imageName: "bell.fill",
// colorConfig: .config(for: 0)
// )
// )
// .previewDisplayName("Yellow Border (0)")
//
// // Preview with nextStepBackground = 1 (Red border)
// NotificationWidgetView(
// data: NotificationWidgetData(
// currentTicket: "89",
// currentlyServingHeader: "Currently Serving2:",
// currentlyServing: "Customer #67",
// status: "Active",
// nextStep: "Next: Quality Check",
// imageName: "bell.fill",
// colorConfig: .config(for: 1)
// )
// )
// .previewDisplayName("Red Border (1)")
//
// // Preview with nextStepBackground = 2 (Green border)
// NotificationWidgetView(
// data: NotificationWidgetData(
// currentTicket: "125",
// currentlyServingHeader: "Currently Serving1:",
// currentlyServing: "Customer #98",
// status: "Completed",
// nextStep: "Next: Ready for Pickup",
// imageName: "bell.fill",
// colorConfig: .config(for: 2)
// )
// )
// .previewDisplayName("Green Border (2)")
// }
// .padding()
// .previewLayout(.sizeThatFits)
// }
//}
func getValueFromSharedDefaults(_ containingString: String) -> String {
print("Function `getValueFromSharedDefaults` is being called")
let dictionary = sharedDefault.dictionaryRepresentation()
print("Contents of sharedDefault: \(dictionary)")
for (key, value) in dictionary {
print("Inspecting key: \(key), value: \(value)")
if key.contains(containingString) {
let components = key.split(separator: "_")
if let stringValue = value as? String {
return stringValue
} else {
return "no value"
}
}
}
return "no value"
}

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "icon.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,4 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.4" d="M8.3335 31.6667V36.6667L31.6668 36.6667V31.6667C31.6668 25.2233 26.4435 20 20.0002 20C13.5568 20 8.3335 25.2233 8.3335 31.6667Z" fill="#9C9C9C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.6665 2.08398C5.97615 2.08398 5.4165 2.64363 5.4165 3.33398C5.4165 4.02434 5.97615 4.58398 6.6665 4.58398H7.08317L7.08317 8.33398C7.08317 13.4808 10.0935 17.9246 14.4494 20.0007C10.0935 22.0767 7.08317 26.5205 7.08317 31.6673L7.08317 35.4173H6.6665C5.97615 35.4173 5.4165 35.977 5.4165 36.6673C5.4165 37.3577 5.97615 37.9173 6.6665 37.9173L33.3332 37.9173C34.0235 37.9173 34.5832 37.3577 34.5832 36.6673C34.5832 35.977 34.0235 35.4173 33.3332 35.4173H32.9165V31.6673C32.9165 26.5205 29.9062 22.0767 25.5502 20.0007C29.9062 17.9246 32.9165 13.4808 32.9165 8.33398V4.58398H33.3332C34.0235 4.58398 34.5832 4.02434 34.5832 3.33398C34.5832 2.64363 34.0235 2.08398 33.3332 2.08398L6.6665 2.08398ZM30.4165 4.58398L9.58317 4.58398L9.58317 8.33398C9.58317 14.087 14.2469 18.7507 19.9998 18.7507C25.7528 18.7507 30.4165 14.087 30.4165 8.33398V4.58398ZM30.4165 35.4173V31.6673C30.4165 25.9144 25.7528 21.2507 19.9998 21.2507C14.2469 21.2507 9.58317 25.9143 9.58317 31.6673V35.4173L30.4165 35.4173Z" fill="#2E3039"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "hmg.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "hmg 1.svg",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "hmg 2.svg",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="14" height="14" rx="3" fill="#ED1C2B"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="14" height="14" rx="3" fill="#ED1C2B"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="14" height="14" rx="3" fill="#ED1C2B"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "doctor-02.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,4 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.25016 8.89518C5.38787 8.89518 5.51754 8.96002 5.60016 9.07018L7.00016 10.9368L8.40016 9.07018C8.48279 8.96002 8.61246 8.89518 8.75016 8.89518C9.27763 8.89518 9.72393 8.89517 10.0671 8.92628C10.4208 8.95833 10.7298 9.02617 11.0106 9.18825C11.3431 9.38025 11.6193 9.65639 11.8113 9.98893C11.9733 10.2697 12.0412 10.5787 12.0732 10.9324C12.1043 11.2756 12.1043 11.701 12.1043 12.2285V12.8327C12.1043 13.0743 11.9085 13.2702 11.6668 13.2702H2.3335C2.09187 13.2702 1.896 13.0743 1.896 12.8327V12.2285C1.89599 11.701 1.89599 11.2756 1.92709 10.9324C1.95915 10.5787 2.02699 10.2697 2.18907 9.98893C2.38106 9.65639 2.6572 9.38025 2.98975 9.18825C3.27048 9.02617 3.57953 8.95833 3.93323 8.92628C4.2764 8.89517 4.72269 8.89518 5.25016 8.89518Z" fill="#18C273"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.73438 4.71896L10.3155 2.3578C10.5171 1.53855 9.90831 0.728516 9.05507 0.728516H4.94519C4.09195 0.728516 3.48316 1.53855 3.68478 2.3578L4.26579 4.71859V5.83268C4.26579 7.35644 5.48349 8.60352 7.00009 8.60352C8.51668 8.60352 9.73438 7.35644 9.73438 5.83268V4.71896ZM5.14079 5.10323H8.85938V5.83268C8.85938 6.88626 8.02046 7.72852 7.00009 7.72852C5.97971 7.72852 5.14079 6.88626 5.14079 5.83268V5.10323ZM7.00002 1.60352C7.24164 1.60352 7.43752 1.79939 7.43752 2.04102V2.47837H7.87516C8.11679 2.47837 8.31266 2.67425 8.31266 2.91587C8.31266 3.1575 8.11679 3.35337 7.87516 3.35337H7.43752V3.79102C7.43752 4.03264 7.24164 4.22852 7.00002 4.22852C6.7584 4.22852 6.56252 4.03264 6.56252 3.79102V3.35337H6.12516C5.88354 3.35337 5.68766 3.1575 5.68766 2.91587C5.68766 2.67425 5.88354 2.47837 6.12516 2.47837H6.56252V2.04102C6.56252 1.79939 6.7584 1.60352 7.00002 1.60352Z" fill="#18C273"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.alhabib.patientApp</string>
</array>
</dict>
</plist>

@ -17,11 +17,15 @@
61243B542EC5FA3700D46FA0 /* BuildFile in Sources */ = {isa = PBXBuildFile; };
61243B562EC5FA3700D46FA0 /* BuildFile in Sources */ = {isa = PBXBuildFile; };
61243B572EC5FA3700D46FA0 /* BuildFile in Sources */ = {isa = PBXBuildFile; };
614897042F28D996004105B3 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61E1DA312F28A72E00CBF473 /* WidgetKit.framework */; };
614897052F28D996004105B3 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61E1DA332F28A72E00CBF473 /* SwiftUI.framework */; };
614897122F28D99A004105B3 /* AppWidgetLiveActivityExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 614897032F28D996004105B3 /* AppWidgetLiveActivityExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
614897D22F29F952004105B3 /* LiveActivityHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614897D12F29F94A004105B3 /* LiveActivityHelper.swift */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
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 */; };
C5586BA7BD57391D3F91EF2B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8076571670911AB920E1FF99 /* Pods_Runner.framework */; };
FA9E781ABC7EBAA9AC2A559A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28E87B9D131B9D85858F792A /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -32,9 +36,27 @@
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
614897102F28D99A004105B3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 614897022F28D996004105B3;
remoteInfo = AppWidgetLiveActivityExtension;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
61E1DA462F28A73100CBF473 /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
614897122F28D99A004105B3 /* AppWidgetLiveActivityExtension.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -48,20 +70,25 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
049415E7A479589C7A439E26 /* 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>"; };
28E87B9D131B9D85858F792A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
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; };
34F2654CE6CEE8475402FCE4 /* 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>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; 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>"; };
614897032F28D996004105B3 /* AppWidgetLiveActivityExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = AppWidgetLiveActivityExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
614897902F29E233004105B3 /* AppWidgetLiveActivityExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AppWidgetLiveActivityExtension.entitlements; sourceTree = "<group>"; };
614897D12F29F94A004105B3 /* LiveActivityHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivityHelper.swift; sourceTree = "<group>"; };
61E1DA312F28A72E00CBF473 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
61E1DA332F28A72E00CBF473 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7595037DD52211B91157B0F3 /* 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>"; };
769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8076571670911AB920E1FF99 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8E12CEEB8E334EE22D5259D7 /* 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>"; };
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; };
@ -69,40 +96,49 @@
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>"; };
D6BB17A036DF7FCE75271203 /* 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>"; };
B50C2F2EABBC2DFA70F931F1 /* 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 PBXFileSystemSynchronizedBuildFileExceptionSet section */
6147DFA32EF2D46300A0F0AA /* Exceptions for "AppWidget" folder in "Runner" target */ = {
614897132F28D99B004105B3 /* Exceptions for "AppWidgetLiveActivity" folder in "AppWidgetLiveActivityExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
"Poppins-Medium.ttf",
Info.plist,
);
target = 97C146ED1CF9000F007C117D /* Runner */;
target = 614897022F28D996004105B3 /* AppWidgetLiveActivityExtension */;
};
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
61769DEA2EEFDD0F000EC14A /* AppWidget */ = {
614897062F28D996004105B3 /* AppWidgetLiveActivity */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
6147DFA32EF2D46300A0F0AA /* Exceptions for "AppWidget" folder in "Runner" target */,
614897132F28D99B004105B3 /* Exceptions for "AppWidgetLiveActivity" folder in "AppWidgetLiveActivityExtension" target */,
);
explicitFileTypes = {
};
explicitFolders = (
);
path = AppWidget;
path = AppWidgetLiveActivity;
sourceTree = "<group>";
};
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
614897002F28D996004105B3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
614897052F28D996004105B3 /* SwiftUI.framework in Frameworks */,
614897042F28D996004105B3 /* WidgetKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C5586BA7BD57391D3F91EF2B /* Pods_Runner.framework in Frameworks */,
FA9E781ABC7EBAA9AC2A559A /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -120,6 +156,7 @@
61243B412EC5FA3700D46FA0 /* Helper */ = {
isa = PBXGroup;
children = (
614897D12F29F94A004105B3 /* LiveActivityHelper.swift */,
);
path = Helper;
sourceTree = "<group>";
@ -131,12 +168,22 @@
path = Penguin;
sourceTree = "<group>";
};
71E5EACB6652FDA92D3045F5 /* Frameworks */ = {
isa = PBXGroup;
children = (
28E87B9D131B9D85858F792A /* Pods_Runner.framework */,
61E1DA312F28A72E00CBF473 /* WidgetKit.framework */,
61E1DA332F28A72E00CBF473 /* SwiftUI.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
79DD2093A1D9674C94359FC8 /* Pods */ = {
isa = PBXGroup;
children = (
8E12CEEB8E334EE22D5259D7 /* Pods-Runner.debug.xcconfig */,
7595037DD52211B91157B0F3 /* Pods-Runner.release.xcconfig */,
D6BB17A036DF7FCE75271203 /* Pods-Runner.profile.xcconfig */,
34F2654CE6CEE8475402FCE4 /* Pods-Runner.debug.xcconfig */,
049415E7A479589C7A439E26 /* Pods-Runner.release.xcconfig */,
B50C2F2EABBC2DFA70F931F1 /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@ -155,13 +202,14 @@
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
614897902F29E233004105B3 /* AppWidgetLiveActivityExtension.entitlements */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
61769DEA2EEFDD0F000EC14A /* AppWidget */,
614897062F28D996004105B3 /* AppWidgetLiveActivity */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
79DD2093A1D9674C94359FC8 /* Pods */,
DBBFD4F9B92DEEED70E55CB8 /* Frameworks */,
71E5EACB6652FDA92D3045F5 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -170,6 +218,7 @@
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
614897032F28D996004105B3 /* AppWidgetLiveActivityExtension.appex */,
);
name = Products;
sourceTree = "<group>";
@ -194,14 +243,6 @@
path = Runner;
sourceTree = "<group>";
};
DBBFD4F9B92DEEED70E55CB8 /* Frameworks */ = {
isa = PBXGroup;
children = (
8076571670911AB920E1FF99 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -222,23 +263,45 @@
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
614897022F28D996004105B3 /* AppWidgetLiveActivityExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 614897142F28D99B004105B3 /* Build configuration list for PBXNativeTarget "AppWidgetLiveActivityExtension" */;
buildPhases = (
614896FF2F28D996004105B3 /* Sources */,
614897002F28D996004105B3 /* Frameworks */,
614897012F28D996004105B3 /* Resources */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
614897062F28D996004105B3 /* AppWidgetLiveActivity */,
);
name = AppWidgetLiveActivityExtension;
productName = AppWidgetLiveActivityExtension;
productReference = 614897032F28D996004105B3 /* AppWidgetLiveActivityExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
BFED6CCFE59BB148875A533B /* [CP] Check Pods Manifest.lock */,
A6C952634C4302C01CA5C5E8 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
E6CDE64936F529AE76962FE8 /* [CP] Copy Pods Resources */,
61E1DA462F28A73100CBF473 /* Embed Foundation Extensions */,
D75CDA8F31A418BC8F9C299F /* [CP] Embed Pods Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
8372B02399CDF54531650AD4 /* [CP] Embed Pods Frameworks */,
81DE7C26F41956799E954FCE /* [CP] Copy Pods Resources */,
97C146EB1CF9000F007C117D /* Frameworks */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
614897112F28D99A004105B3 /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
@ -252,6 +315,7 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 1640;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
@ -259,6 +323,9 @@
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
614897022F28D996004105B3 = {
CreatedOnToolsVersion = 16.4;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
@ -280,6 +347,7 @@
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
614897022F28D996004105B3 /* AppWidgetLiveActivityExtension */,
);
};
/* End PBXProject section */
@ -292,6 +360,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
614897012F28D996004105B3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -323,75 +398,75 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
81DE7C26F41956799E954FCE /* [CP] Copy Pods Resources */ = {
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
8372B02399CDF54531650AD4 /* [CP] Embed Pods Frameworks */ = {
A6C952634C4302C01CA5C5E8 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
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-frameworks-${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-frameworks.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;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
D75CDA8F31A418BC8F9C299F /* [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;
};
BFED6CCFE59BB148875A533B /* [CP] Check Pods Manifest.lock */ = {
E6CDE64936F529AE76962FE8 /* [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 */
@ -405,6 +480,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
614896FF2F28D996004105B3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -414,6 +496,7 @@
61243B4C2EC5FA3700D46FA0 /* BuildFile in Sources */,
61243B502EC5FA3700D46FA0 /* BuildFile in Sources */,
61243B542EC5FA3700D46FA0 /* BuildFile in Sources */,
614897D22F29F952004105B3 /* LiveActivityHelper.swift in Sources */,
61243B562EC5FA3700D46FA0 /* BuildFile in Sources */,
61243B572EC5FA3700D46FA0 /* BuildFile in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
@ -428,6 +511,11 @@
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
614897112F28D99A004105B3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 614897022F28D996004105B3 /* AppWidgetLiveActivityExtension */;
targetProxy = 614897102F28D99A004105B3 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@ -577,6 +665,132 @@
};
name = Profile;
};
614897152F28D99B004105B3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = AppWidgetLiveActivityExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AppWidgetLiveActivity/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AppWidgetLiveActivity;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone.AppWidgetLiveActivity";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
614897162F28D99B004105B3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = AppWidgetLiveActivityExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AppWidgetLiveActivity/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AppWidgetLiveActivity;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone.AppWidgetLiveActivity";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
614897172F28D99B004105B3 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = AppWidgetLiveActivityExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AppWidgetLiveActivity/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AppWidgetLiveActivity;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone.AppWidgetLiveActivity";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -758,6 +972,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
614897142F28D99B004105B3 /* Build configuration list for PBXNativeTarget "AppWidgetLiveActivityExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
614897152F28D99B004105B3 /* Debug */,
614897162F28D99B004105B3 /* Release */,
614897172F28D99B004105B3 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (

@ -13,11 +13,13 @@ import GoogleMaps
FirebaseApp.configure()
initializePlatformChannels()
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
LiveActivityHelper().initialize(mainViewController)
// HMGPenguinInPlatformBridge.initialize(flutterViewController: mainViewController)
}

@ -0,0 +1,37 @@
//
// LiveActivityHelper.swift
// Runner
//
// Created by Cloud Solutions on 28/01/2026.
//
import Foundation
import FLAnimatedImage
class LiveActivityHelper{
private let channelName = "clear_data"
var flutterMethodChannelPenguinIn:FlutterMethodChannel? = nil
func initialize(_ controller :FlutterViewController){
openChannel(controller: controller)
}
private func openChannel(controller :FlutterViewController){
flutterMethodChannelPenguinIn = FlutterMethodChannel(name: channelName, binaryMessenger: controller.binaryMessenger)
flutterMethodChannelPenguinIn?.setMethodCallHandler { (methodCall, result) in
print("Called function \(methodCall.method)")
if methodCall.method == "clearUserDefaultData"{
let sharedDefaults: UserDefaults = UserDefaults(suiteName: "group.alhabib.patientApp")!
sharedDefaults.removePersistentDomain(forName: "group.alhabib.patientApp")
sharedDefaults.synchronize()
result(nil)
}
}
}
}

@ -110,6 +110,7 @@
<string>location</string>
<string>remote-notification</string>
<string>voip</string>
<string>processing</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>

@ -1,8 +1,8 @@
//
// AppIntent.swift
// liveapp
// live_notification
//
// Created by Cloud Solutions on 14/12/2025.
// Created by Cloud Solutions on 27/01/2026.
//
import WidgetKit

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,35 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "hmg.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "hmg 1.svg",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "hmg 2.svg",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="14" height="14" rx="3" fill="#ED1C2B"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="14" height="14" rx="3" fill="#ED1C2B"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="14" height="14" rx="3" fill="#ED1C2B"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
<path d="M2.54806 11.4469C2.54806 11.4469 2.98492 11.4437 3.29241 11.4437L5.6242 11.455C5.90252 11.455 6.13431 11.1634 6.14737 10.7422L6.15002 8.82227C6.15002 8.41291 6.3357 8.09262 6.6236 8.07432L7.33877 8.06869C7.62708 8.08618 7.825 8.4105 7.825 8.81725L7.82316 10.7474C7.83581 11.1685 8.03006 11.4433 8.30981 11.4433L11.4488 11.4518L11.4545 9.07923C11.4545 8.67107 11.2554 8.354 10.9648 8.3353L9.70382 8.32907C9.4249 8.32907 9.20555 8.03893 9.19372 7.6173L9.18882 6.97551C9.20269 6.55449 9.42326 6.26496 9.7028 6.26496L10.9707 6.26858C11.2588 6.25028 11.4465 5.91511 11.4465 5.50755L11.4496 2.5459C11.346 2.71309 11.2043 2.85421 11.0357 2.95807C10.8671 3.06193 10.6763 3.12568 10.4784 3.14426L8.34613 3.14245C8.06843 3.14245 7.83602 3.44083 7.82296 3.86185L7.82296 5.76371C7.8099 6.18393 7.59178 6.4813 7.31285 6.4813L6.66767 6.47647C6.38793 6.47647 6.1643 6.18875 6.15165 5.76974L6.15328 3.84698C6.14063 3.42575 5.91904 3.14326 5.63991 3.14326L2.54562 3.14466L2.54562 5.50997C2.54562 5.91853 2.73925 6.24565 3.02817 6.26455L4.29609 6.25933C4.58277 6.27782 4.78579 6.61481 4.78579 7.02115L4.78192 7.56865C4.78192 7.97701 4.58604 8.30373 4.29793 8.32223L3.02797 8.31921C2.73905 8.33932 2.54541 8.66102 2.54541 9.06938L2.54806 11.4469Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -2,12 +2,12 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSSupportsLiveActivities</key>
<true/>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
<key>NSSupportsLiveActivities</key>
<true/>
</dict>
</plist>

@ -0,0 +1,16 @@
//
// live_notificationBundle.swift
// live_notification
//
// Created by Cloud Solutions on 27/01/2026.
//
import WidgetKit
import SwiftUI
@main
struct live_notificationBundle: WidgetBundle {
var body: some Widget {
live_notificationLiveActivity()
}
}

@ -0,0 +1,410 @@
import ActivityKit
import WidgetKit
import SwiftUI
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
public typealias LiveDeliveryData = ContentState // don't forget to add this line, otherwise, live activity will not display it.
public struct ContentState: Codable, Hashable { }
var id = UUID()
}
let sharedDefault = UserDefaults(suiteName: "group.alhabib.patientApp")!
struct AppWidgetAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
// Dynamic stateful properties about your activity go here!
var emoji: String
}
// Fixed non-changing properties about your activity go here!
var name: String
}
extension Color {
static let redColorText = Color(hex: "#ED1C2B")
static let yellowColor = Color(hex: "#FFAF15")
static let successColor = Color(hex: "#18C273")
static let inactiveColor = Color(hex: "#ED1C2B")
static let textColor = Color(hex: "#A2A2A2")
static let colorWhite = Color(hex: "#FFFFFF")
// Helper initializer for hex colors
init(hex: String) {
let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int: UInt64 = 0
Scanner(string: hex).scanHexInt64(&int)
let a, r, g, b: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(a, r, g, b) = (255, 0, 0, 0)
}
self.init(
.sRGB,
red: Double(r) / 255,
green: Double(g) / 255,
blue: Double(b) / 255,
opacity: Double(a) / 255
)
}
}
// MARK: - Widget Configuration based on nextStepBackground
struct WidgetColorConfig {
let nextStepBackground: Color
let nextStepTextColor: Color
let containerBorderColor: Color
static func config(for value: Int) -> WidgetColorConfig {
switch value {
case 0:
return WidgetColorConfig(
nextStepBackground: .inactiveColor,
nextStepTextColor: .textColor,
containerBorderColor: .yellowColor
)
case 1:
return WidgetColorConfig(
nextStepBackground: .redColorText,
nextStepTextColor: .colorWhite,
containerBorderColor: .redColorText
)
case 2:
return WidgetColorConfig(
nextStepBackground: .successColor,
nextStepTextColor: .colorWhite,
containerBorderColor: .successColor
)
default:
return WidgetColorConfig(
nextStepBackground: .inactiveColor,
nextStepTextColor: .textColor,
containerBorderColor: .yellowColor
)
}
}
}
// MARK: - Widget Data Model
struct NotificationWidgetData {
let currentTicket: String
let currentlyServingHeader: String
let currentlyServing: String
let status: String
let nextStep: String
let imageName: String
let colorConfig: WidgetColorConfig
}
struct NotificationWidgetView: View {
private let data: NotificationWidgetData
init(data: NotificationWidgetData) {
print("it is being loaded")
self.data = data
}
var body : some View{
// ZStack(){
body2
// .frame(width: .infinity, height: 400 )
// .padding(.top, 340)
// .cornerRadius(20)
// }.background(data.colorConfig.containerBorderColor)
// .cornerRadius(20)
}
// var body2 : some View {
// Text(data.currentTicket)
// .font(.custom("Poppins-Medium", size: 28))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 10)
// .frame(maxWidth: .infinity, alignment: .leading)
// }
//current one that todo will be handled
var body2: some View {
VStack(alignment: .leading, spacing: 0) {
// Top section with current ticket and image
HStack(alignment: .top, spacing: 0) {
// Current ticket value
Text(data.currentTicket)
.font(.custom("Poppins-Medium", size: 28))
.fontWeight(.bold)
.foregroundColor(.black)
.padding(.trailing, 10)
.frame(maxWidth: .infinity, alignment: .leading)
Image(data.imageName)
.resizable()
.scaledToFit()
.frame(width: 34, height: 34)
}
.padding(.top, 16)
.padding(.horizontal, 16)
// Currently Serving Header
Text(data.currentlyServingHeader)
.font(.custom("Poppins-Medium", size: 14))
.fontWeight(.bold)
.foregroundColor(.black)
.padding(.trailing, 12)
.padding(.bottom, 10)
.padding(.horizontal, 16)
// Currently Serving section with status
HStack(alignment: .center, spacing: 0) {
// Currently serving text
Text(data.currentlyServing)
.font(.custom("Poppins-Medium", size: 16))
.fontWeight(.bold)
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .leading)
// Status badge
Text(data.status)
.font(.custom("Poppins-Medium", size: 12))
.foregroundColor(data.colorConfig.nextStepTextColor)
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color.inactiveColor.opacity(0.2))
)
}
.padding(.horizontal, 16)
Spacer()
// Next Step badge
Text(data.nextStep)
.font(.custom("Poppins-Medium", size: 12))
.foregroundColor(data.colorConfig.nextStepTextColor)
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(data.colorConfig.nextStepBackground)
)
.padding(.horizontal, 16)
.padding(.bottom, 16)
}
.background(Color.black.opacity(0.01))
.cornerRadius(20)
// .border(width: 10, edges: [.top, .bottom], color: data.colorConfig.containerBorderColor)
// .border(width: 2, edges: [.leading, .trailing], color: data.colorConfig.containerBorderColor)
// .overlay(
// RoundedRectangle(cornerRadius: 20)
// .stroke(data.colorConfig.containerBorderColor, lineWidth: 20)
// )
}
}
// MARK: - Live Activity Widget
struct live_notificationLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
// Extract parameters from Flut
// print("the queno is \(context.attributes.prefixedKey("title")) ===== \(sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) )")
let title = sharedDefault.string(forKey: context.attributes.prefixedKey("title")) ?? "testes"
let contentText = sharedDefault.string(forKey: context.attributes.prefixedKey("contentText")) ?? "tested"
let currentTicket = sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) ?? "test1234"
let status = sharedDefault.string(forKey: context.attributes.prefixedKey("callType")) ?? "test3345"
let currentlyServing = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingTitle")) ?? "tes"
let nextStep = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingStatus")) ??
"test111"
let nextStepBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("currentlyServingCallType"))
// Get color configuration based on nextStepBackground
let colorConfig = WidgetColorConfig.config(for: nextStepBackground)
// Create widget data
let widgetData = NotificationWidgetData(
currentTicket: currentTicket,
currentlyServingHeader: "Currently Servingsssssssss:",
currentlyServing: currentlyServing,
status: status,
nextStep: nextStep,
imageName:"hmg",
colorConfig: colorConfig
)
//
// Lock screen/banner UI
NotificationWidgetView(data: widgetData)
.activityBackgroundTint(Color.clear)
.activitySystemActionForegroundColor(Color.black)
// Text(widgetData.currentTicket)
// .font(.custom("Poppins-Medium", size: 28))
// .fontWeight(.bold)
// .foregroundColor(.black)
// .padding(.trailing, 10)
// .frame(maxWidth: .infinity, alignment: .leading)
} dynamicIsland: { context in
let title = sharedDefault.string(forKey: context.attributes.prefixedKey("title")) ?? "testes"
let contentText = sharedDefault.string(forKey: context.attributes.prefixedKey("contentText")) ?? "tested"
let currentTicket = sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) ?? "test1234"
let status = sharedDefault.string(forKey: context.attributes.prefixedKey("callType")) ?? "test3345"
let currentlyServing = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingTitle")) ?? "tes"
let nextStep = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingStatus")) ??
"test111"
let nextStepBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("currentlyServingCallType"))
let colorConfig = WidgetColorConfig.config(for: nextStepBackground)
return DynamicIsland {
// Expanded UI
DynamicIslandExpandedRegion(.leading) {
VStack(alignment: .leading) {
Text(currentTicket)
.font(.system(size: 24, weight: .bold))
.foregroundColor(.primary)
}
}
DynamicIslandExpandedRegion(.trailing) {
Image("hmg")
.resizable()
.scaledToFit()
.frame(width: 34, height: 34)
.foregroundColor(.gray)
}
DynamicIslandExpandedRegion(.center) {
VStack(spacing: 4) {
Text("Currently Servings:")
.font(.caption2)
.foregroundColor(.secondary)
Text(currentlyServing)
.font(.caption)
.fontWeight(.semibold)
}
}
DynamicIslandExpandedRegion(.bottom) {
HStack {
Text(status)
.font(.caption2)
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(
RoundedRectangle(cornerRadius: 6)
.fill(colorConfig.nextStepBackground.opacity(0.2))
)
Spacer()
Text(nextStep)
.font(.caption2)
.foregroundColor(colorConfig.nextStepTextColor)
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(
RoundedRectangle(cornerRadius: 6)
.fill(colorConfig.nextStepBackground)
)
}
.padding(.horizontal)
}
} compactLeading: {
// Compact leading view
Text(currentTicket)
.font(.caption2)
.fontWeight(.bold)
} compactTrailing: {
// Compact trailing view
Image("hmg")
.resizable()
.scaledToFit()
.frame(width: 12, height: 12)
.foregroundColor(colorConfig.containerBorderColor).padding(4)
} minimal: {
// Minimal view
HStack{
Text(currentTicket)
.font(.caption2)
.fontWeight(.bold)
Spacer()
Image("hmg")
.resizable()
.scaledToFit()
.frame(width: 4, height: 4)
.foregroundColor(colorConfig.containerBorderColor)
}.padding(2)
}
.contentMargins(.all, 20,for: .expanded)
}
}
}
extension LiveActivitiesAppAttributes {
func prefixedKey(_ key: String) -> String {
return "\(id)_\(key)"
}
}
// MARK: - Preview for Testing
struct NotificationWidgetView_Previews: PreviewProvider {
static var previews: some View {
Group {
// Preview with nextStepBackground = 0 (Yellow border)
NotificationWidgetView(
data: NotificationWidgetData(
currentTicket: "42",
currentlyServingHeader: "Currently Serving3:",
currentlyServing: "Customer #15",
status: "Pending",
nextStep: "Next: Prepare Order",
imageName: "bell.fill",
colorConfig: .config(for: 0)
)
)
.previewDisplayName("Yellow Border (0)")
// Preview with nextStepBackground = 1 (Red border)
NotificationWidgetView(
data: NotificationWidgetData(
currentTicket: "89",
currentlyServingHeader: "Currently Serving2:",
currentlyServing: "Customer #67",
status: "Active",
nextStep: "Next: Quality Check",
imageName: "bell.fill",
colorConfig: .config(for: 1)
)
)
.previewDisplayName("Red Border (1)")
// Preview with nextStepBackground = 2 (Green border)
NotificationWidgetView(
data: NotificationWidgetData(
currentTicket: "125",
currentlyServingHeader: "Currently Serving1:",
currentlyServing: "Customer #98",
status: "Completed",
nextStep: "Next: Ready for Pickup",
imageName: "bell.fill",
colorConfig: .config(for: 2)
)
)
.previewDisplayName("Green Border (2)")
}
.padding()
.previewLayout(.sizeThatFits)
}
}

@ -1,88 +0,0 @@
//
// liveapp.swift
// liveapp
//
// Created by Cloud Solutions on 14/12/2025.
//
import WidgetKit
import SwiftUI
struct Provider: AppIntentTimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), configuration: ConfigurationAppIntent())
}
func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
SimpleEntry(date: Date(), configuration: configuration)
}
func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, configuration: configuration)
entries.append(entry)
}
return Timeline(entries: entries, policy: .atEnd)
}
// func relevances() async -> WidgetRelevances<ConfigurationAppIntent> {
// // Generate a list containing the contexts this widget is relevant in.
// }
}
struct SimpleEntry: TimelineEntry {
let date: Date
let configuration: ConfigurationAppIntent
}
struct liveappEntryView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text("Time:")
Text(entry.date, style: .time)
Text("Favorite Emoji:")
Text(entry.configuration.favoriteEmoji)
}
}
}
struct liveapp: Widget {
let kind: String = "liveapp"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
liveappEntryView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
}
}
}
extension ConfigurationAppIntent {
fileprivate static var smiley: ConfigurationAppIntent {
let intent = ConfigurationAppIntent()
intent.favoriteEmoji = "😀"
return intent
}
fileprivate static var starEyes: ConfigurationAppIntent {
let intent = ConfigurationAppIntent()
intent.favoriteEmoji = "🤩"
return intent
}
}
#Preview(as: .systemSmall) {
liveapp()
} timeline: {
SimpleEntry(date: .now, configuration: .smiley)
SimpleEntry(date: .now, configuration: .starEyes)
}

@ -1,16 +0,0 @@
//
// liveappBundle.swift
// liveapp
//
// Created by Cloud Solutions on 14/12/2025.
//
import WidgetKit
import SwiftUI
@main
struct liveappBundle: WidgetBundle {
var body: some Widget {
FootballMatchApp()
}
}

@ -1,77 +0,0 @@
//
// liveappControl.swift
// liveapp
//
// Created by Cloud Solutions on 14/12/2025.
//
import AppIntents
import SwiftUI
import WidgetKit
struct liveappControl: ControlWidget {
static let kind: String = "com.HMG.HMG-Smartphone.liveapp"
var body: some ControlWidgetConfiguration {
AppIntentControlConfiguration(
kind: Self.kind,
provider: Provider()
) { value in
ControlWidgetToggle(
"Start Timer",
isOn: value.isRunning,
action: StartTimerIntent(value.name)
) { isRunning in
Label(isRunning ? "On" : "Off", systemImage: "timer")
}
}
.displayName("Timer")
.description("A an example control that runs a timer.")
}
}
extension liveappControl {
struct Value {
var isRunning: Bool
var name: String
}
struct Provider: AppIntentControlValueProvider {
func previewValue(configuration: TimerConfiguration) -> Value {
liveappControl.Value(isRunning: false, name: configuration.timerName)
}
func currentValue(configuration: TimerConfiguration) async throws -> Value {
let isRunning = true // Check if the timer is running
return liveappControl.Value(isRunning: isRunning, name: configuration.timerName)
}
}
}
struct TimerConfiguration: ControlConfigurationIntent {
static let title: LocalizedStringResource = "Timer Name Configuration"
@Parameter(title: "Timer Name", default: "Timer")
var timerName: String
}
struct StartTimerIntent: SetValueIntent {
static let title: LocalizedStringResource = "Start a timer"
@Parameter(title: "Timer Name")
var name: String
@Parameter(title: "Timer is running")
var value: Bool
init() {}
init(_ name: String) {
self.name = name
}
func perform() async throws -> some IntentResult {
// Start the timer
return .result()
}
}

@ -1,332 +0,0 @@
//
// liveappLiveActivity.swift
// liveapp
//
// Created by Cloud Solutions on 14/12/2025.
//
import ActivityKit
import WidgetKit
import SwiftUI
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
public typealias LiveDeliveryData = ContentState
public struct ContentState: Codable, Hashable { }
var id = UUID()
}
// Create shared default with custom group
let sharedDefault = UserDefaults(suiteName: "group.alhabib.patientApp")!
@available(iOSApplicationExtension 16.1, *)
struct FootballMatchApp: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
let matchName = sharedDefault.string(forKey: context.attributes.prefixedKey("matchName"))!
let ruleFile = sharedDefault.string(forKey: context.attributes.prefixedKey("ruleFile"))!
let teamAName = sharedDefault.string(forKey: context.attributes.prefixedKey("teamAName"))!
let teamAState = sharedDefault.string(forKey: context.attributes.prefixedKey("teamAState"))!
let teamAScore = sharedDefault.integer(forKey: context.attributes.prefixedKey("teamAScore"))
let teamALogo = sharedDefault.string(forKey: context.attributes.prefixedKey("teamALogo"))!
let teamBName = sharedDefault.string(forKey: context.attributes.prefixedKey("teamBName"))!
let teamBState = sharedDefault.string(forKey: context.attributes.prefixedKey("teamBState"))!
let teamBScore = sharedDefault.integer(forKey: context.attributes.prefixedKey("teamBScore"))
let teamBLogo = sharedDefault.string(forKey: context.attributes.prefixedKey("teamBLogo"))!
let rule = (try? String(contentsOfFile: ruleFile, encoding: .utf8)) ?? ""
let matchStartDate = Date(timeIntervalSince1970: sharedDefault.double(forKey: context.attributes.prefixedKey("matchStartDate")) / 1000)
let matchEndDate = Date(timeIntervalSince1970: sharedDefault.double(forKey: context.attributes.prefixedKey("matchEndDate")) / 1000)
let matchRemainingTime = matchStartDate...matchEndDate
ZStack {
LinearGradient(colors: [Color.black.opacity(0.5),Color.black.opacity(0.3)], startPoint: .topLeading, endPoint: .bottom)
HStack {
ZStack {
VStack(alignment: .center, spacing: 2.0) {
Spacer()
Text(teamAName)
.lineLimit(1)
.font(.subheadline)
.fontWeight(.bold)
.multilineTextAlignment(.center)
Text(teamAState)
.lineLimit(1)
.font(.footnote)
.fontWeight(.bold)
.multilineTextAlignment(.center)
}
.frame(width: 70, height: 120)
.padding(.bottom, 8)
.padding(.top, 8)
.background(.white.opacity(0.4), in: RoundedRectangle(cornerRadius: 16, style: .continuous))
ZStack {
if let uiImageTeamA = UIImage(contentsOfFile: teamALogo)
{
Image(uiImage: uiImageTeamA)
.resizable()
.frame(width: 80, height: 80)
.offset(y:-20)
}
}
}
VStack(alignment: .center, spacing: 6.0) {
HStack {
Text("\(teamAScore)")
.font(.title)
.fontWeight(.bold)
Text(":")
.font(.title)
.fontWeight(.bold)
.foregroundStyle(.primary)
Text("\(teamBScore)")
.font(.title)
.fontWeight(.bold)
}
.padding(.horizontal, 5.0)
.background(.white.opacity(0.4), in: RoundedRectangle(cornerRadius: 8, style: .continuous))
HStack(alignment: .center, spacing: 2.0) {
Text(timerInterval: matchRemainingTime, countsDown: true)
.multilineTextAlignment(.center)
.frame(width: 50)
.monospacedDigit()
.font(.footnote)
.foregroundStyle(.white)
}
VStack(alignment: .center, spacing: 1.0) {
Link(destination: URL(string: "la://my.app/stats")!) {
Text("See stats 📊")
}.padding(.vertical, 5).padding(.horizontal, 5)
Text(matchName)
.font(.footnote)
.foregroundStyle(.white)
.padding(.bottom, 5)
Text(rule)
.font(.footnote)
.foregroundStyle(.white.opacity(0.5))
}
}
.padding(.vertical, 6.0)
ZStack {
VStack(alignment: .center, spacing: 2.0) {
Spacer()
Text(teamBName)
.lineLimit(1)
.font(.subheadline)
.fontWeight(.bold)
.multilineTextAlignment(.center)
Text(teamBState)
.lineLimit(1)
.font(.footnote)
.fontWeight(.bold)
.multilineTextAlignment(.center)
}
.frame(width: 70, height: 120)
.padding(.bottom, 8)
.padding(.top, 8)
.background(.white.opacity(0.4), in: RoundedRectangle(cornerRadius: 16, style: .continuous))
ZStack {
if let uiImageTeamB = UIImage(contentsOfFile: teamBLogo)
{
Image(uiImage: uiImageTeamB)
.resizable()
.frame(width: 80, height: 80)
.offset(y:-20)
}
}
}
}
.padding(.horizontal, 2.0)
}.frame(height: 160)
} dynamicIsland: { context in
let matchName = sharedDefault.string(forKey: context.attributes.prefixedKey("matchName"))!
let teamAName = sharedDefault.string(forKey: context.attributes.prefixedKey("teamAName"))!
let teamAState = sharedDefault.string(forKey: context.attributes.prefixedKey("teamAState"))!
let teamAScore = sharedDefault.integer(forKey: context.attributes.prefixedKey("teamAScore"))
let teamALogo = sharedDefault.string(forKey: context.attributes.prefixedKey("teamALogo"))!
let teamBName = sharedDefault.string(forKey: context.attributes.prefixedKey("teamBName"))!
let teamBState = sharedDefault.string(forKey: context.attributes.prefixedKey("teamBState"))!
let teamBScore = sharedDefault.integer(forKey: context.attributes.prefixedKey("teamBScore"))
let teamBLogo = sharedDefault.string(forKey: context.attributes.prefixedKey("teamBLogo"))!
let matchStartDate = Date(timeIntervalSince1970: sharedDefault.double(forKey: context.attributes.prefixedKey("matchStartDate")) / 1000)
let matchEndDate = Date(timeIntervalSince1970: sharedDefault.double(forKey: context.attributes.prefixedKey("matchEndDate")) / 1000)
let matchRemainingTime = matchStartDate...matchEndDate
return DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
VStack(alignment: .center, spacing: 2.0) {
if let uiImageTeamA = UIImage(contentsOfFile: teamALogo)
{
Image(uiImage: uiImageTeamA)
.resizable()
.frame(width: 80, height: 80)
.offset(y:0)
}
Spacer()
Text(teamAName)
.lineLimit(1)
.font(.subheadline)
.fontWeight(.bold)
.multilineTextAlignment(.center)
Text(teamAState)
.lineLimit(1)
.font(.footnote)
.fontWeight(.bold)
.multilineTextAlignment(.center)
}
.frame(width: 70, height: 120)
.padding(.bottom, 8)
.padding(.top, 8)
}
DynamicIslandExpandedRegion(.trailing) {
VStack(alignment: .center, spacing: 2.0) {
if let uiImageTeamB = UIImage(contentsOfFile: teamBLogo)
{
Image(uiImage: uiImageTeamB)
.resizable()
.frame(width: 80, height: 80)
.offset(y:0)
}
Spacer()
Text(teamBName)
.lineLimit(1)
.font(.subheadline)
.fontWeight(.bold)
.multilineTextAlignment(.center)
Text(teamBState)
.lineLimit(1)
.font(.footnote)
.fontWeight(.bold)
.multilineTextAlignment(.center)
}
.frame(width: 70, height: 120)
.padding(.bottom, 8)
.padding(.top, 8)
}
DynamicIslandExpandedRegion(.center) {
VStack(alignment: .center, spacing: 6.0) {
HStack {
Text("\(teamAScore)")
.font(.title)
.fontWeight(.bold)
Text(":")
.font(.title)
.fontWeight(.bold)
.foregroundStyle(.primary)
Text("\(teamBScore)")
.font(.title)
.fontWeight(.bold)
}
.padding(.horizontal, 5.0)
.background(.thinMaterial, in: RoundedRectangle(cornerRadius: 8, style: .continuous))
HStack(alignment: .center, spacing: 2.0) {
Text(timerInterval: matchRemainingTime, countsDown: true)
.multilineTextAlignment(.center)
.frame(width: 50)
.monospacedDigit()
.font(.footnote)
.foregroundStyle(.white)
}
VStack(alignment: .center, spacing: 1.0) {
Link(destination: URL(string: "la://my.app/stats")!) {
Text("See stats 📊")
}.padding(.vertical, 5).padding(.horizontal, 5)
Text(matchName)
.font(.footnote)
.foregroundStyle(.white)
}
}
.padding(.vertical, 6.0)
}
} compactLeading: {
HStack {
if let uiImageTeamA = UIImage(contentsOfFile: teamALogo)
{
Image(uiImage: uiImageTeamA)
.resizable()
.frame(width: 26, height: 26)
}
Text("\(teamAScore)")
.font(.title)
.fontWeight(.bold)
}
} compactTrailing: {
HStack {
Text("\(teamBScore)")
.font(.title)
.fontWeight(.bold)
if let uiImageTeamB = UIImage(contentsOfFile: teamBLogo)
{
Image(uiImage: uiImageTeamB)
.resizable()
.frame(width: 26, height: 26)
}
}
} minimal: {
ZStack {
if let uiImageTeamA = UIImage(contentsOfFile: teamALogo)
{
Image(uiImage: uiImageTeamA)
.resizable()
.frame(width: 26, height: 26)
.offset(x:-6)
}
if let uiImageTeamB = UIImage(contentsOfFile: teamBLogo)
{
Image(uiImage: uiImageTeamB)
.resizable()
.frame(width: 26, height: 26)
.offset(x:6)
}
}
}
}
}
}
extension LiveActivitiesAppAttributes {
func prefixedKey(_ key: String) -> String {
return "\(id)_\(key)"
}
}

@ -79,4 +79,6 @@ class CacheConst {
static const String zoomRoomID = 'zoom-room-id';
static String isAppOpenedFromCall = "is_app_opened_from_call";
static const String patientQueueNoForLiveActivity = "QUEUENO_FOR_ACTIVITYID";
}

@ -2,12 +2,16 @@ class PatientQueue {
final String? queueNo;
final String? currentlyServingStatus;
final String? currentlyServingToken;
final String? yourTicketHeader;
final String? currentlyServingTitle;
final String? nextTicketStatus;
final int? currentlyServingCallType;
final int? callType;// background will be same as of the [Utils.getCardButtonColor]
const PatientQueue({ this.queueNo, this.currentlyServingStatus, this.nextTicketStatus, this.callType, this.currentlyServingTitle,this.currentlyServingCallType, });
const PatientQueue({this.yourTicketHeader,this.currentlyServingTitle, this.queueNo, this.currentlyServingStatus, this.nextTicketStatus, this.callType, this.currentlyServingToken,this
.currentlyServingCallType,
});
/// Converts this PatientQueue object to a map.
/// This is used for passing data to the native side for Live Activities.
@ -17,8 +21,10 @@ class PatientQueue {
'currentlyServingStatus': currentlyServingStatus,
'nextTicketStatus': nextTicketStatus,
'callType': callType,
'currentlyServingTitle': currentlyServingTitle,
'currentlyServingToken': currentlyServingToken,
'currentlyServingCallType': currentlyServingCallType,
'yourTicketHeader':yourTicketHeader,
'currentlyServingTitle':currentlyServingTitle,
};
}
}

@ -0,0 +1,14 @@
import 'package:flutter/services.dart';
class LiveActivityHelperChannel {
static const MethodChannel _channel = MethodChannel('clear_data');
static Future<void> removeData() async {
try {
await _channel.invokeMethod('clearUserDefaultData');
} on PlatformException catch (e) {
print("Failed to removeData: '${e.message}'.");
}
}
}

@ -4,6 +4,7 @@ import 'dart:io';
import 'dart:ui';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart' as fir;
import 'package:firebase_messaging/firebase_messaging.dart';
@ -19,10 +20,14 @@ import 'package:flutter_ios_voip_kit_karmm/call_state_type.dart';
import 'package:flutter_ios_voip_kit_karmm/flutter_ios_voip_kit.dart';
import 'package:hmg_patient_app_new/core/common_models/patient_queue.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/live_activty_helper_channel.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_queue_details_response_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:live_activities/live_activities.dart' show LiveActivities;
import 'package:permission_handler/permission_handler.dart';
import 'package:uuid/uuid.dart';
@ -44,74 +49,110 @@ Future<dynamic> backgroundMessageHandler(dynamic message) async {
}
if (message.data['isLiveActivity'] == true || message.data['isLiveActivity'] == "true") {
try {
print('Before WidgetsFlutterBinding');
// Initialize Firebase
await Firebase.initializeApp();
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
await Future.delayed(Duration(seconds: 2));
print('Before addLiveNotification');
addLiveNotification(message, isBackgroundMessage: true);
print('After addLiveNotification');
} catch (e, stackTrace) {
print('Error: $e');
print('Stack trace: $stackTrace');
}
}
}
addLiveNotification(dynamic message, {bool isBackgroundMessage = false}) async{
print("live activity called");
// final methodChannel = const MethodChannel('live_activities');
// methodChannel.invokeMethod('init', {
// 'appGroupId': "",
// 'urlScheme': "",
// });
// print("After addLiveNotification local init run");
var liveActivity = LiveActivities();
// addLiveNotification(dynamic message, {bool isBackgroundMessage = false}) async{
// print("live activity called");
// var liveActivity = LiveActivities();
//
//
// var activityId = await Utils.getStringFromPrefs( message.data['queueNo'] ??"");
//
// var buttonText = Utils.getCardButtonText(int.parse(message.data['callType']??"1"), message.data['roomNo']);
// PatientQueue _patientQueue = PatientQueue(
// queueNo: message.data['queueNo'] ?? "IME-1",
// currentlyServingStatus: (message.data['servingCallType'] ?? 0) == "1" ? "Call for vital signs".needTranslation : "Call for Doctor".needTranslation,
// currentlyServingTitle: message.data['servingQueueNo'] ?? "IME-3",
// nextTicketStatus: buttonText,
// callType: int.parse(message.data['callType']??"1"),
// currentlyServingCallType: int.parse(message.data['servingCallType']??"1"));
// if((activityId??"") != (message.data['queueNo']??"")){
// liveActivity.endActivity(activityId);
// activityId = "";
// }
// print("the activity id is $activityId");
//
// if( activityId == ""){
// String? id = await liveActivity.createActivity(
// DateTime.now().millisecondsSinceEpoch.toString(),
// _patientQueue.toMap(),
// );
// print("the activity id created is $id");
// await Utils.saveStringFromPrefs(message.data['queueNo'] ??"", message.data['queueNo']??"");
// print("the activity id saved is ${await Utils.getStringFromPrefs(message.data['queueNo'] ??"")}");
// print("the activity is created");
// return;
// }
//
// await liveActivity.updateActivity(
// activityId,
// _patientQueue.toMap(),
// );
//
// print("the activity is is created or updated");
//
// }
addLiveNotification(dynamic data, {bool isBackgroundMessage = false}) async{
var liveActivity = LiveActivities();
var activityId = await Utils.getStringFromPrefs( message.data['queueNo'] ??"");
liveActivity.init(appGroupId: "group.alhabib.patientApp");
if(Platform.isIOS){
LiveActivityHelperChannel.removeData();
}
var queueNoForWhichActivityIdCreated = await Utils.getStringFromPrefs( CacheConst.patientQueueNoForLiveActivity);
var activityId = await Utils.getStringFromPrefs( data.data['queueNo'] ??"");
var buttonText = Utils.getCardButtonText(int.parse(message.data['callType']??"1"), message.data['roomNo']);
var buttonText = Utils.getCardButtonText(int.parse(data.data['callType']??"1"), data.data['roomNo']);
PatientQueue _patientQueue = PatientQueue(
queueNo: message.data['queueNo'] ?? "IME-1",
currentlyServingStatus: (message.data['servingCallType'] ?? 0) == "1" ? "Call for vital signs".needTranslation : "Call for Doctor".needTranslation,
currentlyServingTitle: message.data['servingQueueNo'] ?? "IME-3",
queueNo: data.data['queueNo'] ?? "IME-1",
currentlyServingStatus: (data.data['servingCallType'] ?? 0) == "1" ?LocaleKeys.callForVitalSign.tr() : LocaleKeys.callForDoctor.tr() ,
currentlyServingToken: data.data['servingQueueNo'] ?? "IME-3",
nextTicketStatus: buttonText,
callType: int.parse(message.data['callType']??"1"),
currentlyServingCallType: int.parse(message.data['servingCallType']??"1"));
if((activityId??"") != (message.data['queueNo']??"")){
callType: int.parse(data.data['callType']??"1"),
currentlyServingCallType: int.parse(data.data['servingCallType']??"1"),
yourTicketHeader: LocaleKeys.yourQueueNumber.tr(),
currentlyServingTitle: LocaleKeys.currentServing.tr()
);
if((queueNoForWhichActivityIdCreated??"") != (_patientQueue.queueNo??"")){
liveActivity.endActivity(activityId);
activityId = "";
}
print("the activity id is $activityId");
if( activityId == ""){
String? id = await liveActivity.createActivity(
String? id = await liveActivity.createActivity(
DateTime.now().millisecondsSinceEpoch.toString(),
_patientQueue.toMap(),
);
print("the activity id created is $id");
await Utils.saveStringFromPrefs(message.data['queueNo'] ??"", message.data['queueNo']??"");
print("the activity id saved is ${await Utils.getStringFromPrefs(message.data['queueNo'] ??"")}");
print("the activity is created");
await Utils.saveStringFromPrefs(_patientQueue.queueNo ??"", id??"");
await Utils.saveStringFromPrefs(CacheConst.patientQueueNoForLiveActivity ??"", _patientQueue.queueNo??"");
return;
}
await liveActivity.updateActivity(
if(Platform.isIOS) {
await liveActivity.createOrUpdateActivity(
activityId,
_patientQueue.toMap(),
);
print("the activity is is created or updated");
_patientQueue.toMap(),
);
}else{
await liveActivity.updateActivity(
activityId,
_patientQueue.toMap(),
);
}
}
callPage(String sessionID, String token) async {}
_incomingCall(Map<String, dynamic> data) async {
print('the value of the _incomingCall remote message is $data');
// LandingPage.incomingCallData = IncomingCallData.fromJson(data);
// var dataItem = await AppSharedPreferences().getObject('call_data');
@ -219,7 +260,6 @@ Future<void> openCallPage(BuildContext context) async {
// );
// }
} catch (err) {
print(err);
// await PlatformExceptionAlertDialog(
// exception: Exception(err),
// ).show(context);
@ -284,7 +324,6 @@ class PushNotificationHandler {
// late HmsApiAvailability hmsApiAvailability;
final voIPKit = FlutterIOSVoIPKit.instance;
late Timer timeOutTimer;
bool isTalking = false;
@ -333,10 +372,8 @@ class PushNotificationHandler {
final PermissionStatus status = await Permission.notification.request();
if (status.isGranted) {
// Notification permissions granted
print("Notification permissions granted");
} else if (status.isDenied) {
// Notification permissions denied
print("Notification permissions not granted");
} else if (status.isPermanentlyDenied) {
// // Notification permissions permanently denied, open app settings
@ -344,19 +381,16 @@ class PushNotificationHandler {
}
if (Platform.isIOS) {
voIPKit.getVoIPToken().then((value) {
print("🎈 APNS VOIP KIT TOKEN: $value");
Utils.saveStringFromPrefs(CacheConst.voipToken, value ?? "");
// AppSharedPreferences().setString(APNS_TOKEN, value!);
});
voIPKit.onDidUpdatePushToken = (String token) {
print('🎈 example: onDidUpdatePushToken: $token');
};
voIPKit.onDidReceiveIncomingPush = (
Map<String, dynamic> payload,
) async {
print('🎈 example: onDidReceiveIncomingPush $payload');
// _timeOut();
};
@ -365,7 +399,6 @@ class PushNotificationHandler {
String callerId,
) async {
try {
print('🎈 example: onDidRejectIncomingCall $uuid - $callerId');
timeOutTimer.cancel();
} catch (err) {}
};
@ -374,7 +407,6 @@ class PushNotificationHandler {
String uuid,
String callerId,
) async {
print('🎈 example: onDidAcceptIncomingCall $uuid - $callerId');
await voIPKit.acceptIncomingCall(callerState: CallStateType.calling);
await voIPKit.callConnected();
await Future.delayed(Duration(seconds: 2)).then((val) async {
@ -394,6 +426,7 @@ class PushNotificationHandler {
// timeOutTimer.cancel();
};
}
try {
final fcmToken = await FirebaseMessaging.instance.getToken().catchError((err) {
print(err);
@ -458,7 +491,6 @@ class PushNotificationHandler {
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
print("Firebase onMessageOpenedApp!!!");
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
newMessage(message);
@ -472,7 +504,6 @@ class PushNotificationHandler {
print("Push Notification getToken: ${token!}");
onToken(token!);
}).catchError((err) {
print(err);
});
FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
@ -492,7 +523,6 @@ class PushNotificationHandler {
}
newMessage(RemoteMessage remoteMessage) async {
print("Remote Message 1: ${remoteMessage.data}");
if (remoteMessage.data.isEmpty) {
return;
}
@ -541,7 +571,6 @@ class PushNotificationHandler {
}
onToken(String token) async {
print("Push Notification Token: $token");
await Utils.saveStringFromPrefs(CacheConst.pushToken, token);
}
@ -563,8 +592,6 @@ class PushNotificationHandler {
// Permission.audio,
// Permission.microphone,
].request();
print("=-=-=-=-=-=-=-=-=-=-");
print(statuses[Permission.notification]);
}
} catch (_) {
debugPrint(_.toString());

@ -876,5 +876,9 @@ abstract class LocaleKeys {
static const laserClinic = 'laserClinic';
static const continueString = 'continueString';
static const covid_info = 'covid_info';
static const callForVitalSign = 'callForVitalSign';
static const callForDoctor = 'callForDoctor';
static const yourQueueNumber = 'yourQueueNumber';
static const currentServing = 'currentServing';
}

@ -643,7 +643,7 @@ class _LandingPageState extends State<LandingPage> {
}),
SizedBox(height: 16.h),
Container(
height: 250.h,
height: 121.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
child: Column(
children: [

@ -1,10 +1,13 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/utils/live_activty_helper_channel.dart';
import 'package:hmg_patient_app_new/core/utils/push_notification_handler.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/emergency_services/emergency_services_view_model.dart';
import 'package:hmg_patient_app_new/features/hospital/hospital_selection_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/my_doctors_page.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/emergency_services_page.dart';
@ -12,17 +15,13 @@ import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.d
import 'package:hmg_patient_app_new/presentation/lab/lab_orders_page.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/patient_sickleaves_list_page.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:live_activities/live_activities.dart' show LiveActivities;
import 'package:live_activities/live_activities.dart';
import 'package:provider/provider.dart';
import '../../../core/common_models/patient_queue.dart' show PatientQueue;
import '../../../core/dependencies.dart';
import '../../../core/common_models/patient_queue.dart';
import '../../../core/utils/utils.dart';
import '../../../theme/colors.dart';
import '../../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart';
import '../../radiology/radiology_orders_page.dart' show RadiologyOrdersPage;
class SmallServiceCard extends StatelessWidget {
@ -69,29 +68,14 @@ class SmallServiceCard extends StatelessWidget {
),
),
),
).onPress(() async {
).onPress(() {
switch (serviceName) {
case "lab_results":
{
LiveActivities().init(appGroupId: "group.alhabib.patientApp");
PatientQueue _patientQueue = PatientQueue(
queueNo: "IME-1",
currentlyServingStatus: "Call for vital signs".needTranslation ,
currentlyServingTitle:"IME-3",
nextTicketStatus: "dsds",
callType: 1,
currentlyServingCallType: 1);
var activity = await LiveActivities().createActivity(
DateTime.now().millisecondsSinceEpoch.toString(),
_patientQueue.toMap(),
);
}
// Navigator.of(context).push(
// CustomPageRoute(
// page: LabOrdersPage(),
// ),
// );
Navigator.of(context).push(
CustomPageRoute(
page: LabOrdersPage(),
),
);
break;
case "radiology_results":
Navigator.of(context).push(
@ -131,30 +115,15 @@ class SmallServiceCard extends StatelessWidget {
);
break;
case "emergency":
// context.read<EmergencyServicesViewModel>().flushData();
// context.read<EmergencyServicesViewModel>().getTransportationOrders(showLoader: false,);
// context.read<EmergencyServicesViewModel>().getRRTOrders(showLoader: false,);
// Navigator.of(context).push(
// CustomPageRoute(
// page: EmergencyServicesPage(),
// settings: const RouteSettings(name: '/EmergencyServicesPage'),
// ),
// );
{
LiveActivities().init(appGroupId: "group.alhabib.patientApp");
PatientQueue _patientQueue = PatientQueue(
queueNo: "IME-1",
currentlyServingStatus: "Call for vital signs".needTranslation ,
currentlyServingTitle:"IME-3",
nextTicketStatus: "dsds",
callType: 1,
currentlyServingCallType: 1);
var activity = await LiveActivities().createActivity(
DateTime.now().millisecondsSinceEpoch.toString(),
_patientQueue.toMap(),
context.read<EmergencyServicesViewModel>().flushData();
context.read<EmergencyServicesViewModel>().getTransportationOrders(showLoader: false,);
context.read<EmergencyServicesViewModel>().getRRTOrders(showLoader: false,);
Navigator.of(context).push(
CustomPageRoute(
page: EmergencyServicesPage(),
settings: const RouteSettings(name: '/EmergencyServicesPage'),
),
);
}
break;
default:
// Handle unknown service
@ -162,41 +131,4 @@ class SmallServiceCard extends StatelessWidget {
}
});
}
void openIndoorNavigationBottomSheet(BuildContext context) {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.selectHospital.tr(),
context,
child: ChangeNotifierProvider(
create: (context) => HospitalSelectionBottomSheetViewModel(getIt()),
child: Consumer<HospitalSelectionBottomSheetViewModel>(
builder: (_, vm, __) => HospitalBottomSheetBody(
searchText: vm.searchController,
displayList: vm.displayList,
onFacilityClicked: (value) {
vm.setSelectedFacility(value);
vm.getDisplayList();
},
onHospitalClicked: (hospital) {
Navigator.pop(context);
vm.openPenguin(hospital);
},
onHospitalSearch: (value) {
vm.searchHospitals(value ?? "");
},
selectedFacility: vm.selectedFacility,
hmcCount: vm.hmcCount,
hmgCount: vm.hmgCount,
),
),
),
isFullScreen: false,
isCloseButtonVisible: true,
hasBottomPadding: false,
backgroundColor: AppColors.bottomSheetBgColor,
callBackFunc: () {
context.read<EmergencyServicesViewModel>().clearSearchText();
},
);
}
}

Loading…
Cancel
Save