diff --git a/android/app/key.properties b/android/app/key.properties
new file mode 100644
index 00000000..5f99fd60
--- /dev/null
+++ b/android/app/key.properties
@@ -0,0 +1,4 @@
+storePassword=HmGsa123
+keyPassword=HmGsa123
+keyAlias=hmg
+storeFile=key
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 70a68707..fc13a9f2 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -31,6 +31,9 @@
+
@@ -64,6 +67,7 @@
+
@@ -128,7 +132,6 @@
) {
+ Log.d("updateRemoteViews", "current ticket is ${data["queueNo"] as? String ?: ""}")
+ Log.d("updateRemoteViews", "remoteViews is $remoteViews")
+ val progress = when (data["callType"] as? Int) {
+ 0 -> 33
+ 1 -> 66
+ 2 ->99
+ else -> 99}
+
+ 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)
+ }
+
+
+
+ remoteViews.setInt(R.id.status_container, "setBackgroundResource", nextStepButtonBackground)
+ remoteViews.setInt(R.id.role_badge, "setBackgroundResource", nextStepButtonBackground)
+// remoteViews.setInt(R.id.container, "setBackgroundResource", containerBackground)
+ remoteViews.setTextColor(R.id.status_text, ContextCompat.getColor(context, textColor))
+ remoteViews.setTextColor(R.id.currentServingStatus, ContextCompat.getColor(context, textColor))
+ remoteViews.setProgressBar(R.id.progress_bar,1, progress, true)
+
+ remoteViews.setProgressTintList(
+ R.id.progress_bar,
+ "setProgressTintList",
+ ColorStateList.valueOf(nextStepButtonBackground) // your desired color
+ );
+
+ 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 ?: "")
+
+ // Hide serving_layout if currentlyServingToken is empty
+ val currentlyServingToken = data["currentlyServingToken"] as? String ?: ""
+ if (currentlyServingToken.isEmpty()) {
+ remoteViews.setViewVisibility(R.id.serving_layout, android.view.View.GONE)
+ } else {
+ remoteViews.setViewVisibility(R.id.serving_layout, android.view.View.VISIBLE)
+ }
+
+
+ }
+
+ private suspend fun updateCollapsedView(data: Map) {
+ Log.d("updateCollapsedView", "current ticket is ${data["queueNo"] as? String ?: ""}")
+ Log.d("updateCollapsedView", "remoteViews is $collapesView")
+
+ collapesView.setTextViewText(R.id.queue_number, data["queueNo"] as? String ?: "")
+ remoteViews.setTextViewText(R.id.queue_label, data["yourTicketHeader"] as? String ?: "")
+ }
+
+ override suspend fun buildNotification(
+ notification: Notification.Builder,
+ event: String,
+ data: Map
+ ): Notification {
+// val notificationManager =
+// context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+// if (notificationManager != null) {
+// notificationManager.cancelAll();
+// }
+
+ collapesView.apply {
+ updateCollapsedView(data)
+ }
+ remoteViews.apply {
+ updateRemoteViews(data)
+ }
+ Log.d("buildNotification", "Building notification for event: $event with data: $data")
+ Log.d("buildNotification", "Building notification for collapesView: $collapesView with remoteViews: $remoteViews")
+
+ return notification
+ .setSmallIcon(R.drawable.hmg)
+ .setContentTitle(data["title"] as? String ?: "Patient Queue")
+ .setContentIntent(pendingIntent)
+ .setContentText(data["content"] as? String ?: "Patient Queues")
+ .setStyle(Notification.DecoratedCustomViewStyle())
+ .setCustomContentView(collapesView)
+ .setCustomBigContentView(remoteViews)
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setCategory(Notification.CATEGORY_EVENT)
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setOngoing(true)
+
+ .build()
+ }
+}
diff --git a/android/app/src/main/res/drawable/dark_red_rounded_corner_widget.xml b/android/app/src/main/res/drawable/dark_red_rounded_corner_widget.xml
new file mode 100644
index 00000000..7f6098a6
--- /dev/null
+++ b/android/app/src/main/res/drawable/dark_red_rounded_corner_widget.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/green_rounded_corner_widget.xml b/android/app/src/main/res/drawable/green_rounded_corner_widget.xml
new file mode 100644
index 00000000..79e7f569
--- /dev/null
+++ b/android/app/src/main/res/drawable/green_rounded_corner_widget.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/grey_rounded_corner_widget.xml b/android/app/src/main/res/drawable/grey_rounded_corner_widget.xml
new file mode 100644
index 00000000..eda87791
--- /dev/null
+++ b/android/app/src/main/res/drawable/grey_rounded_corner_widget.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/hmc.xml b/android/app/src/main/res/drawable/hmc.xml
new file mode 100644
index 00000000..5dffd390
--- /dev/null
+++ b/android/app/src/main/res/drawable/hmc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/hmg.xml b/android/app/src/main/res/drawable/hmg.xml
new file mode 100644
index 00000000..ba3a4b2f
--- /dev/null
+++ b/android/app/src/main/res/drawable/hmg.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/ic_notification.png b/android/app/src/main/res/drawable/ic_notification.png
new file mode 100644
index 00000000..e4a08151
Binary files /dev/null and b/android/app/src/main/res/drawable/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable/icon.xml b/android/app/src/main/res/drawable/icon.xml
new file mode 100644
index 00000000..68ce3c25
--- /dev/null
+++ b/android/app/src/main/res/drawable/icon.xml
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/android/app/src/main/res/drawable/profession.xml b/android/app/src/main/res/drawable/profession.xml
new file mode 100644
index 00000000..7282bc0f
--- /dev/null
+++ b/android/app/src/main/res/drawable/profession.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/android/app/src/main/res/drawable/progress_bar_drawable.xml b/android/app/src/main/res/drawable/progress_bar_drawable.xml
new file mode 100644
index 00000000..9d08e71d
--- /dev/null
+++ b/android/app/src/main/res/drawable/progress_bar_drawable.xml
@@ -0,0 +1,21 @@
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/progress_thumb.xml b/android/app/src/main/res/drawable/progress_thumb.xml
new file mode 100644
index 00000000..4c5e39fc
--- /dev/null
+++ b/android/app/src/main/res/drawable/progress_thumb.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/queue_card_background.xml b/android/app/src/main/res/drawable/queue_card_background.xml
new file mode 100644
index 00000000..da4d7207
--- /dev/null
+++ b/android/app/src/main/res/drawable/queue_card_background.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/queue_card_background_low_radius.xml b/android/app/src/main/res/drawable/queue_card_background_low_radius.xml
new file mode 100644
index 00000000..0d59d1b6
--- /dev/null
+++ b/android/app/src/main/res/drawable/queue_card_background_low_radius.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/red_rounded_corner_widget.xml b/android/app/src/main/res/drawable/red_rounded_corner_widget.xml
new file mode 100644
index 00000000..5e1395a0
--- /dev/null
+++ b/android/app/src/main/res/drawable/red_rounded_corner_widget.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/seekbar_thumb_image.xml b/android/app/src/main/res/drawable/seekbar_thumb_image.xml
new file mode 100644
index 00000000..ba9b8c72
--- /dev/null
+++ b/android/app/src/main/res/drawable/seekbar_thumb_image.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/android/app/src/main/res/drawable/status_box_background.xml b/android/app/src/main/res/drawable/status_box_background.xml
new file mode 100644
index 00000000..148bcef6
--- /dev/null
+++ b/android/app/src/main/res/drawable/status_box_background.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/whitebg_green_border_rounded_corner_widget.xml b/android/app/src/main/res/drawable/whitebg_green_border_rounded_corner_widget.xml
new file mode 100644
index 00000000..d75af999
--- /dev/null
+++ b/android/app/src/main/res/drawable/whitebg_green_border_rounded_corner_widget.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/whitebg_red_border_rounded_corner_widget.xml b/android/app/src/main/res/drawable/whitebg_red_border_rounded_corner_widget.xml
new file mode 100644
index 00000000..246c9613
--- /dev/null
+++ b/android/app/src/main/res/drawable/whitebg_red_border_rounded_corner_widget.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/whitebg_yellow_border_rounded_corner_widget.xml b/android/app/src/main/res/drawable/whitebg_yellow_border_rounded_corner_widget.xml
new file mode 100644
index 00000000..92e81441
--- /dev/null
+++ b/android/app/src/main/res/drawable/whitebg_yellow_border_rounded_corner_widget.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/font/poppins_medium.ttf b/android/app/src/main/res/font/poppins_medium.ttf
new file mode 100644
index 00000000..e90e87ed
Binary files /dev/null and b/android/app/src/main/res/font/poppins_medium.ttf differ
diff --git a/android/app/src/main/res/layout/live_activity.xml b/android/app/src/main/res/layout/live_activity.xml
new file mode 100644
index 00000000..06b51931
--- /dev/null
+++ b/android/app/src/main/res/layout/live_activity.xml
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/layout/live_activity_collapsed.xml b/android/app/src/main/res/layout/live_activity_collapsed.xml
new file mode 100644
index 00000000..096f542c
--- /dev/null
+++ b/android/app/src/main/res/layout/live_activity_collapsed.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..44004699
--- /dev/null
+++ b/android/app/src/main/res/values/colors.xml
@@ -0,0 +1,13 @@
+
+
+ #ED1C2B
+ #FFAF15
+ #18C273
+ #332E3039
+ #A2A2A2
+ #FFFF
+ #8F9AA3
+ #2E3039
+ #18C273
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index 2d103337..4a6602a0 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -20,4 +20,5 @@
Geofence requests happened too frequently.
pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ
+
diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..13372aef
Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/android/gradlew b/android/gradlew
new file mode 100755
index 00000000..9d82f789
--- /dev/null
+++ b/android/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/android/gradlew.bat b/android/gradlew.bat
new file mode 100644
index 00000000..8a0b282a
--- /dev/null
+++ b/android/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/android/key.properties b/android/key.properties
new file mode 100644
index 00000000..5f99fd60
--- /dev/null
+++ b/android/key.properties
@@ -0,0 +1,4 @@
+storePassword=HmGsa123
+keyPassword=HmGsa123
+keyAlias=hmg
+storeFile=key
\ No newline at end of file
diff --git a/android/local.properties b/android/local.properties
new file mode 100644
index 00000000..6316c058
--- /dev/null
+++ b/android/local.properties
@@ -0,0 +1,5 @@
+flutter.buildMode=debug
+flutter.sdk=/Users/cloud/sdk/flutter
+flutter.versionCode=38
+flutter.versionName=0.0.39
+sdk.dir=/Users/cloud/Library/Android/sdk
\ No newline at end of file
diff --git a/assets/files/rule.txt b/assets/files/rule.txt
new file mode 100644
index 00000000..49c1cb46
--- /dev/null
+++ b/assets/files/rule.txt
@@ -0,0 +1 @@
+this is a match
\ No newline at end of file
diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json
index d0321ace..d5c45e3c 100644
--- a/assets/langs/ar-SA.json
+++ b/assets/langs/ar-SA.json
@@ -1966,5 +1966,12 @@
"weeklyShift": "الفترات الأسبوعية",
"dayOff": "إجازة",
"notAvailable": "غير متاح",
- "hide": "إخفاء"
+ "hide": "إخفاء",
+ "yesPleaseINeedHelp": "نعم، من فضلك أريد المساعدة",
+ "noThanksIKnowTheClinic": "لا شكراً، أعرف العيادة",
+ "unableToSendOTP": "تعذر إرسال رمز التحقق لمرة واحدة",
+ "callForVitalSign": "استدعاء لأخذ العلامات الحيوية",
+ "callForDoctor": "استدعاء الطبيب",
+ "yourQueueNumber": "رقمك في الدور",
+ "currentServing": "الدور الحالي"
}
diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json
index ae344b01..e3916d21 100644
--- a/assets/langs/en-US.json
+++ b/assets/langs/en-US.json
@@ -1956,7 +1956,14 @@
"weeklyShift": "Weekly Shift",
"dayOff": "Off",
"notAvailable": "Not Available",
- "hide": "Hide"
+ "hide": "Hide",
+ "yesPleaseINeedHelp": "Yes, Please I need help",
+ "noThanksIKnowTheClinic": "No, Thanks. I Know the clinic",
+ "unableToSendOTP": "Unable to send Verification OTP",
+ "callForVitalSign": "Call for vital signs",
+ "callForDoctor": "Call for Doctor",
+ "yourQueueNumber": "Your Queue Number",
+ "currentServing" : "Current Serving"
}
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
index 1dc6cf76..391a902b 100644
--- a/ios/Flutter/AppFrameworkInfo.plist
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -20,7 +20,5 @@
????
CFBundleVersion
1.0
- MinimumOSVersion
- 13.0
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
new file mode 100644
index 00000000..b858ea36
--- /dev/null
+++ b/ios/Podfile.lock
@@ -0,0 +1,677 @@
+PODS:
+ - amazon_payfort (1.1.4):
+ - Flutter
+ - PayFortSDK
+ - audio_session (0.0.1):
+ - Flutter
+ - barcode_scan2 (0.0.1):
+ - Flutter
+ - SwiftProtobuf (~> 1.33)
+ - clarity_flutter (1.0.0):
+ - Flutter
+ - connectivity_plus (0.0.1):
+ - Flutter
+ - CryptoSwift (1.8.4)
+ - device_calendar (0.0.1):
+ - Flutter
+ - device_calendar_plus_ios (0.0.1):
+ - Flutter
+ - device_info_plus (0.0.1):
+ - Flutter
+ - DKImagePickerController/Core (4.3.9):
+ - DKImagePickerController/ImageDataManager
+ - DKImagePickerController/Resource
+ - DKImagePickerController/ImageDataManager (4.3.9)
+ - DKImagePickerController/PhotoGallery (4.3.9):
+ - DKImagePickerController/Core
+ - DKPhotoGallery
+ - DKImagePickerController/Resource (4.3.9)
+ - DKPhotoGallery (0.0.19):
+ - DKPhotoGallery/Core (= 0.0.19)
+ - DKPhotoGallery/Model (= 0.0.19)
+ - DKPhotoGallery/Preview (= 0.0.19)
+ - DKPhotoGallery/Resource (= 0.0.19)
+ - SDWebImage
+ - SwiftyGif
+ - DKPhotoGallery/Core (0.0.19):
+ - DKPhotoGallery/Model
+ - DKPhotoGallery/Preview
+ - SDWebImage
+ - SwiftyGif
+ - DKPhotoGallery/Model (0.0.19):
+ - SDWebImage
+ - SwiftyGif
+ - DKPhotoGallery/Preview (0.0.19):
+ - DKPhotoGallery/Model
+ - DKPhotoGallery/Resource
+ - SDWebImage
+ - SwiftyGif
+ - DKPhotoGallery/Resource (0.0.19):
+ - SDWebImage
+ - SwiftyGif
+ - file_picker (0.0.1):
+ - DKImagePickerController/PhotoGallery
+ - Flutter
+ - Firebase/Analytics (11.15.0):
+ - Firebase/Core
+ - Firebase/Core (11.15.0):
+ - Firebase/CoreOnly
+ - FirebaseAnalytics (~> 11.15.0)
+ - Firebase/CoreOnly (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - Firebase/Crashlytics (11.15.0):
+ - Firebase/CoreOnly
+ - FirebaseCrashlytics (~> 11.15.0)
+ - Firebase/Messaging (11.15.0):
+ - Firebase/CoreOnly
+ - FirebaseMessaging (~> 11.15.0)
+ - firebase_analytics (11.6.0):
+ - Firebase/Analytics (= 11.15.0)
+ - firebase_core
+ - Flutter
+ - firebase_core (3.15.2):
+ - Firebase/CoreOnly (= 11.15.0)
+ - Flutter
+ - firebase_crashlytics (4.3.10):
+ - Firebase/Crashlytics (= 11.15.0)
+ - firebase_core
+ - Flutter
+ - firebase_messaging (15.2.10):
+ - Firebase/Messaging (= 11.15.0)
+ - firebase_core
+ - Flutter
+ - FirebaseAnalytics (11.15.0):
+ - FirebaseAnalytics/Default (= 11.15.0)
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseInstallations (~> 11.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.1)
+ - GoogleUtilities/MethodSwizzler (~> 8.1)
+ - GoogleUtilities/Network (~> 8.1)
+ - "GoogleUtilities/NSData+zlib (~> 8.1)"
+ - nanopb (~> 3.30910.0)
+ - FirebaseAnalytics/Default (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseInstallations (~> 11.0)
+ - GoogleAppMeasurement/Default (= 11.15.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.1)
+ - GoogleUtilities/MethodSwizzler (~> 8.1)
+ - GoogleUtilities/Network (~> 8.1)
+ - "GoogleUtilities/NSData+zlib (~> 8.1)"
+ - nanopb (~> 3.30910.0)
+ - FirebaseCore (11.15.0):
+ - FirebaseCoreInternal (~> 11.15.0)
+ - GoogleUtilities/Environment (~> 8.1)
+ - GoogleUtilities/Logger (~> 8.1)
+ - FirebaseCoreExtension (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseCoreInternal (11.15.0):
+ - "GoogleUtilities/NSData+zlib (~> 8.1)"
+ - FirebaseCrashlytics (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseInstallations (~> 11.0)
+ - FirebaseRemoteConfigInterop (~> 11.0)
+ - FirebaseSessions (~> 11.0)
+ - GoogleDataTransport (~> 10.0)
+ - GoogleUtilities/Environment (~> 8.1)
+ - nanopb (~> 3.30910.0)
+ - PromisesObjC (~> 2.4)
+ - FirebaseInstallations (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - GoogleUtilities/Environment (~> 8.1)
+ - GoogleUtilities/UserDefaults (~> 8.1)
+ - PromisesObjC (~> 2.4)
+ - FirebaseMessaging (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseInstallations (~> 11.0)
+ - GoogleDataTransport (~> 10.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.1)
+ - GoogleUtilities/Environment (~> 8.1)
+ - GoogleUtilities/Reachability (~> 8.1)
+ - GoogleUtilities/UserDefaults (~> 8.1)
+ - nanopb (~> 3.30910.0)
+ - FirebaseRemoteConfigInterop (11.15.0)
+ - FirebaseSessions (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseCoreExtension (~> 11.15.0)
+ - FirebaseInstallations (~> 11.0)
+ - GoogleDataTransport (~> 10.0)
+ - GoogleUtilities/Environment (~> 8.1)
+ - GoogleUtilities/UserDefaults (~> 8.1)
+ - nanopb (~> 3.30910.0)
+ - PromisesSwift (~> 2.1)
+ - FLAnimatedImage (1.0.17)
+ - Flutter (1.0.0)
+ - flutter_amazonpaymentservices (0.0.1):
+ - Flutter
+ - PayFortSDK
+ - flutter_app_group_directory (0.0.1):
+ - Flutter
+ - flutter_callkit_incoming (0.0.1):
+ - CryptoSwift
+ - Flutter
+ - flutter_image_compress_common (1.0.0):
+ - Flutter
+ - Mantle
+ - SDWebImage
+ - SDWebImageWebPCoder
+ - flutter_inappwebview_ios (0.0.1):
+ - Flutter
+ - flutter_inappwebview_ios/Core (= 0.0.1)
+ - OrderedSet (~> 6.0.3)
+ - flutter_inappwebview_ios/Core (0.0.1):
+ - Flutter
+ - OrderedSet (~> 6.0.3)
+ - flutter_ios_voip_kit_karmm (0.8.0):
+ - Flutter
+ - flutter_local_notifications (0.0.1):
+ - Flutter
+ - flutter_nfc_kit (3.6.0):
+ - Flutter
+ - flutter_paytabs_bridge (2.7.12):
+ - Flutter
+ - PayTabsSDK (= 6.6.54)
+ - flutter_screenshot_blocker (0.0.1):
+ - Flutter
+ - flutter_zoom_videosdk (0.0.1):
+ - Flutter
+ - ZoomVideoSDK/CptShare (= 2.4.0)
+ - ZoomVideoSDK/Whiteboard (= 2.4.0)
+ - ZoomVideoSDK/zm_annoter_dynamic (= 2.4.0)
+ - ZoomVideoSDK/zoomcml (= 2.4.0)
+ - ZoomVideoSDK/ZoomTask (= 2.4.0)
+ - ZoomVideoSDK/ZoomVideoSDK (= 2.4.0)
+ - fluttertoast (0.0.2):
+ - Flutter
+ - geolocator_apple (1.2.0):
+ - Flutter
+ - FlutterMacOS
+ - Google-Maps-iOS-Utils (5.0.0):
+ - GoogleMaps (~> 8.0)
+ - google_maps_flutter_ios (0.0.1):
+ - Flutter
+ - Google-Maps-iOS-Utils (< 7.0, >= 5.0)
+ - GoogleMaps (< 11.0, >= 8.4)
+ - GoogleAdsOnDeviceConversion (2.1.0):
+ - GoogleUtilities/Logger (~> 8.1)
+ - GoogleUtilities/Network (~> 8.1)
+ - nanopb (~> 3.30910.0)
+ - GoogleAppMeasurement/Core (11.15.0):
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.1)
+ - GoogleUtilities/MethodSwizzler (~> 8.1)
+ - GoogleUtilities/Network (~> 8.1)
+ - "GoogleUtilities/NSData+zlib (~> 8.1)"
+ - nanopb (~> 3.30910.0)
+ - GoogleAppMeasurement/Default (11.15.0):
+ - GoogleAdsOnDeviceConversion (= 2.1.0)
+ - GoogleAppMeasurement/Core (= 11.15.0)
+ - GoogleAppMeasurement/IdentitySupport (= 11.15.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.1)
+ - GoogleUtilities/MethodSwizzler (~> 8.1)
+ - GoogleUtilities/Network (~> 8.1)
+ - "GoogleUtilities/NSData+zlib (~> 8.1)"
+ - nanopb (~> 3.30910.0)
+ - GoogleAppMeasurement/IdentitySupport (11.15.0):
+ - GoogleAppMeasurement/Core (= 11.15.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.1)
+ - GoogleUtilities/MethodSwizzler (~> 8.1)
+ - GoogleUtilities/Network (~> 8.1)
+ - "GoogleUtilities/NSData+zlib (~> 8.1)"
+ - nanopb (~> 3.30910.0)
+ - GoogleDataTransport (10.1.0):
+ - nanopb (~> 3.30910.0)
+ - PromisesObjC (~> 2.4)
+ - GoogleMaps (8.4.0):
+ - GoogleMaps/Maps (= 8.4.0)
+ - GoogleMaps/Base (8.4.0)
+ - GoogleMaps/Maps (8.4.0):
+ - GoogleMaps/Base
+ - GoogleUtilities/AppDelegateSwizzler (8.1.0):
+ - GoogleUtilities/Environment
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Network
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Environment (8.1.0):
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Logger (8.1.0):
+ - GoogleUtilities/Environment
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/MethodSwizzler (8.1.0):
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Network (8.1.0):
+ - GoogleUtilities/Logger
+ - "GoogleUtilities/NSData+zlib"
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Reachability
+ - "GoogleUtilities/NSData+zlib (8.1.0)":
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Privacy (8.1.0)
+ - GoogleUtilities/Reachability (8.1.0):
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/UserDefaults (8.1.0):
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Privacy
+ - health (13.1.4):
+ - Flutter
+ - image_picker_ios (0.0.1):
+ - Flutter
+ - in_app_review (2.0.0):
+ - Flutter
+ - just_audio (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - libwebp (1.5.0):
+ - libwebp/demux (= 1.5.0)
+ - libwebp/mux (= 1.5.0)
+ - libwebp/sharpyuv (= 1.5.0)
+ - libwebp/webp (= 1.5.0)
+ - libwebp/demux (1.5.0):
+ - libwebp/webp
+ - libwebp/mux (1.5.0):
+ - libwebp/demux
+ - libwebp/sharpyuv (1.5.0)
+ - libwebp/webp (1.5.0):
+ - libwebp/sharpyuv
+ - live_activities (0.0.1):
+ - Flutter
+ - local_auth_darwin (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - location (0.0.1):
+ - Flutter
+ - manage_calendar_events (0.0.1):
+ - Flutter
+ - Mantle (2.2.0):
+ - Mantle/extobjc (= 2.2.0)
+ - Mantle/extobjc (2.2.0)
+ - map_launcher (0.0.1):
+ - Flutter
+ - MapboxCommon (23.11.0)
+ - MapboxCoreMaps (10.19.1):
+ - MapboxCommon (~> 23.11)
+ - MapboxCoreNavigation (2.19.0):
+ - MapboxDirections (~> 2.14)
+ - MapboxNavigationNative (< 207.0.0, >= 206.0.1)
+ - MapboxDirections (2.14.2):
+ - Polyline (~> 5.0)
+ - Turf (~> 2.8.0)
+ - MapboxMaps (10.19.0):
+ - MapboxCommon (= 23.11.0)
+ - MapboxCoreMaps (= 10.19.1)
+ - MapboxMobileEvents (= 2.0.0)
+ - Turf (= 2.8.0)
+ - MapboxMobileEvents (2.0.0)
+ - MapboxNavigation (2.19.0):
+ - MapboxCoreNavigation (= 2.19.0)
+ - MapboxMaps (~> 10.18)
+ - MapboxSpeech (~> 2.0)
+ - Solar-dev (~> 3.0)
+ - MapboxNavigationNative (206.2.2):
+ - MapboxCommon (~> 23.10)
+ - MapboxSpeech (2.1.1)
+ - nanopb (3.30910.0):
+ - nanopb/decode (= 3.30910.0)
+ - nanopb/encode (= 3.30910.0)
+ - nanopb/decode (3.30910.0)
+ - nanopb/encode (3.30910.0)
+ - network_info_plus (0.0.1):
+ - Flutter
+ - open_filex (0.0.2):
+ - Flutter
+ - OrderedSet (6.0.3)
+ - package_info_plus (0.4.5):
+ - Flutter
+ - path_provider_foundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - PayFortSDK (3.2.1)
+ - PayTabsSDK (6.6.54)
+ - permission_handler_apple (9.3.0):
+ - Flutter
+ - Polyline (5.1.0)
+ - PromisesObjC (2.4.0)
+ - PromisesSwift (2.4.0):
+ - PromisesObjC (= 2.4.0)
+ - screen_brightness_ios (0.1.0):
+ - Flutter
+ - SDWebImage (5.21.2):
+ - SDWebImage/Core (= 5.21.2)
+ - SDWebImage/Core (5.21.2)
+ - SDWebImageWebPCoder (0.15.0):
+ - libwebp (~> 1.0)
+ - SDWebImage/Core (~> 5.17)
+ - share_plus (0.0.1):
+ - Flutter
+ - shared_preferences_foundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - Solar-dev (3.0.1)
+ - sqflite_darwin (0.0.4):
+ - Flutter
+ - FlutterMacOS
+ - SwiftProtobuf (1.38.1)
+ - SwiftyGif (5.4.5)
+ - Turf (2.8.0)
+ - url_launcher_ios (0.0.1):
+ - Flutter
+ - video_player_avfoundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - wakelock_plus (0.0.1):
+ - Flutter
+ - webview_flutter_wkwebview (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - ZoomVideoSDK/CptShare (2.4.0)
+ - ZoomVideoSDK/Whiteboard (2.4.0)
+ - ZoomVideoSDK/zm_annoter_dynamic (2.4.0)
+ - ZoomVideoSDK/zoomcml (2.4.0)
+ - ZoomVideoSDK/ZoomTask (2.4.0)
+ - ZoomVideoSDK/ZoomVideoSDK (2.4.0)
+
+DEPENDENCIES:
+ - amazon_payfort (from `.symlinks/plugins/amazon_payfort/ios`)
+ - audio_session (from `.symlinks/plugins/audio_session/ios`)
+ - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
+ - clarity_flutter (from `.symlinks/plugins/clarity_flutter/ios`)
+ - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
+ - device_calendar (from `.symlinks/plugins/device_calendar/ios`)
+ - device_calendar_plus_ios (from `.symlinks/plugins/device_calendar_plus_ios/ios`)
+ - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
+ - file_picker (from `.symlinks/plugins/file_picker/ios`)
+ - firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
+ - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
+ - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
+ - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
+ - FLAnimatedImage
+ - Flutter (from `Flutter`)
+ - flutter_amazonpaymentservices (from `.symlinks/plugins/flutter_amazonpaymentservices/ios`)
+ - flutter_app_group_directory (from `.symlinks/plugins/flutter_app_group_directory/ios`)
+ - flutter_callkit_incoming (from `.symlinks/plugins/flutter_callkit_incoming/ios`)
+ - flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`)
+ - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
+ - flutter_ios_voip_kit_karmm (from `.symlinks/plugins/flutter_ios_voip_kit_karmm/ios`)
+ - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
+ - flutter_nfc_kit (from `.symlinks/plugins/flutter_nfc_kit/ios`)
+ - flutter_paytabs_bridge (from `.symlinks/plugins/flutter_paytabs_bridge/ios`)
+ - flutter_screenshot_blocker (from `.symlinks/plugins/flutter_screenshot_blocker/ios`)
+ - flutter_zoom_videosdk (from `.symlinks/plugins/flutter_zoom_videosdk/ios`)
+ - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
+ - geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`)
+ - google_maps_flutter_ios (from `.symlinks/plugins/google_maps_flutter_ios/ios`)
+ - health (from `.symlinks/plugins/health/ios`)
+ - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
+ - in_app_review (from `.symlinks/plugins/in_app_review/ios`)
+ - just_audio (from `.symlinks/plugins/just_audio/darwin`)
+ - live_activities (from `.symlinks/plugins/live_activities/ios`)
+ - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
+ - location (from `.symlinks/plugins/location/ios`)
+ - manage_calendar_events (from `.symlinks/plugins/manage_calendar_events/ios`)
+ - map_launcher (from `.symlinks/plugins/map_launcher/ios`)
+ - MapboxMaps (= 10.19.0)
+ - MapboxNavigation (= 2.19.0)
+ - network_info_plus (from `.symlinks/plugins/network_info_plus/ios`)
+ - open_filex (from `.symlinks/plugins/open_filex/ios`)
+ - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
+ - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
+ - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
+ - screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
+ - share_plus (from `.symlinks/plugins/share_plus/ios`)
+ - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
+ - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
+ - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
+ - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
+ - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
+ - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
+
+SPEC REPOS:
+ trunk:
+ - CryptoSwift
+ - DKImagePickerController
+ - DKPhotoGallery
+ - Firebase
+ - FirebaseAnalytics
+ - FirebaseCore
+ - FirebaseCoreExtension
+ - FirebaseCoreInternal
+ - FirebaseCrashlytics
+ - FirebaseInstallations
+ - FirebaseMessaging
+ - FirebaseRemoteConfigInterop
+ - FirebaseSessions
+ - FLAnimatedImage
+ - Google-Maps-iOS-Utils
+ - GoogleAdsOnDeviceConversion
+ - GoogleAppMeasurement
+ - GoogleDataTransport
+ - GoogleMaps
+ - GoogleUtilities
+ - libwebp
+ - Mantle
+ - MapboxCommon
+ - MapboxCoreMaps
+ - MapboxCoreNavigation
+ - MapboxDirections
+ - MapboxMaps
+ - MapboxMobileEvents
+ - MapboxNavigation
+ - MapboxNavigationNative
+ - MapboxSpeech
+ - nanopb
+ - OrderedSet
+ - PayFortSDK
+ - PayTabsSDK
+ - Polyline
+ - PromisesObjC
+ - PromisesSwift
+ - SDWebImage
+ - SDWebImageWebPCoder
+ - Solar-dev
+ - SwiftProtobuf
+ - SwiftyGif
+ - Turf
+ - ZoomVideoSDK
+
+EXTERNAL SOURCES:
+ amazon_payfort:
+ :path: ".symlinks/plugins/amazon_payfort/ios"
+ audio_session:
+ :path: ".symlinks/plugins/audio_session/ios"
+ barcode_scan2:
+ :path: ".symlinks/plugins/barcode_scan2/ios"
+ clarity_flutter:
+ :path: ".symlinks/plugins/clarity_flutter/ios"
+ connectivity_plus:
+ :path: ".symlinks/plugins/connectivity_plus/ios"
+ device_calendar:
+ :path: ".symlinks/plugins/device_calendar/ios"
+ device_calendar_plus_ios:
+ :path: ".symlinks/plugins/device_calendar_plus_ios/ios"
+ device_info_plus:
+ :path: ".symlinks/plugins/device_info_plus/ios"
+ file_picker:
+ :path: ".symlinks/plugins/file_picker/ios"
+ firebase_analytics:
+ :path: ".symlinks/plugins/firebase_analytics/ios"
+ firebase_core:
+ :path: ".symlinks/plugins/firebase_core/ios"
+ firebase_crashlytics:
+ :path: ".symlinks/plugins/firebase_crashlytics/ios"
+ firebase_messaging:
+ :path: ".symlinks/plugins/firebase_messaging/ios"
+ Flutter:
+ :path: Flutter
+ flutter_amazonpaymentservices:
+ :path: ".symlinks/plugins/flutter_amazonpaymentservices/ios"
+ flutter_app_group_directory:
+ :path: ".symlinks/plugins/flutter_app_group_directory/ios"
+ flutter_callkit_incoming:
+ :path: ".symlinks/plugins/flutter_callkit_incoming/ios"
+ flutter_image_compress_common:
+ :path: ".symlinks/plugins/flutter_image_compress_common/ios"
+ flutter_inappwebview_ios:
+ :path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
+ flutter_ios_voip_kit_karmm:
+ :path: ".symlinks/plugins/flutter_ios_voip_kit_karmm/ios"
+ flutter_local_notifications:
+ :path: ".symlinks/plugins/flutter_local_notifications/ios"
+ flutter_nfc_kit:
+ :path: ".symlinks/plugins/flutter_nfc_kit/ios"
+ flutter_paytabs_bridge:
+ :path: ".symlinks/plugins/flutter_paytabs_bridge/ios"
+ flutter_screenshot_blocker:
+ :path: ".symlinks/plugins/flutter_screenshot_blocker/ios"
+ flutter_zoom_videosdk:
+ :path: ".symlinks/plugins/flutter_zoom_videosdk/ios"
+ fluttertoast:
+ :path: ".symlinks/plugins/fluttertoast/ios"
+ geolocator_apple:
+ :path: ".symlinks/plugins/geolocator_apple/darwin"
+ google_maps_flutter_ios:
+ :path: ".symlinks/plugins/google_maps_flutter_ios/ios"
+ health:
+ :path: ".symlinks/plugins/health/ios"
+ image_picker_ios:
+ :path: ".symlinks/plugins/image_picker_ios/ios"
+ in_app_review:
+ :path: ".symlinks/plugins/in_app_review/ios"
+ just_audio:
+ :path: ".symlinks/plugins/just_audio/darwin"
+ live_activities:
+ :path: ".symlinks/plugins/live_activities/ios"
+ local_auth_darwin:
+ :path: ".symlinks/plugins/local_auth_darwin/darwin"
+ location:
+ :path: ".symlinks/plugins/location/ios"
+ manage_calendar_events:
+ :path: ".symlinks/plugins/manage_calendar_events/ios"
+ map_launcher:
+ :path: ".symlinks/plugins/map_launcher/ios"
+ network_info_plus:
+ :path: ".symlinks/plugins/network_info_plus/ios"
+ open_filex:
+ :path: ".symlinks/plugins/open_filex/ios"
+ package_info_plus:
+ :path: ".symlinks/plugins/package_info_plus/ios"
+ path_provider_foundation:
+ :path: ".symlinks/plugins/path_provider_foundation/darwin"
+ permission_handler_apple:
+ :path: ".symlinks/plugins/permission_handler_apple/ios"
+ screen_brightness_ios:
+ :path: ".symlinks/plugins/screen_brightness_ios/ios"
+ share_plus:
+ :path: ".symlinks/plugins/share_plus/ios"
+ shared_preferences_foundation:
+ :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
+ sqflite_darwin:
+ :path: ".symlinks/plugins/sqflite_darwin/darwin"
+ url_launcher_ios:
+ :path: ".symlinks/plugins/url_launcher_ios/ios"
+ video_player_avfoundation:
+ :path: ".symlinks/plugins/video_player_avfoundation/darwin"
+ wakelock_plus:
+ :path: ".symlinks/plugins/wakelock_plus/ios"
+ webview_flutter_wkwebview:
+ :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
+
+SPEC CHECKSUMS:
+ amazon_payfort: 4ad7a3413acc1c4c4022117a80d18fee23c572d3
+ audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0
+ barcode_scan2: 4e4b850b112f4e29017833e4715f36161f987966
+ clarity_flutter: d665e4a61c0000a28e7829668a4e287cc1b657bd
+ connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
+ CryptoSwift: e64e11850ede528a02a0f3e768cec8e9d92ecb90
+ device_calendar: b55b2c5406cfba45c95a59f9059156daee1f74ed
+ device_calendar_plus_ios: 2c04ad7643c6e697438216e33693b84e8ca45ded
+ device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
+ DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
+ DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
+ file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
+ Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
+ firebase_analytics: 0e25ca1d4001ccedd40b4e5b74c0ec34e18f6425
+ firebase_core: 995454a784ff288be5689b796deb9e9fa3601818
+ firebase_crashlytics: 30dcd6dfd2fe895c0848af46722a4227346c19aa
+ firebase_messaging: f4a41dd102ac18b840eba3f39d67e77922d3f707
+ FirebaseAnalytics: 6433dfd311ba78084fc93bdfc145e8cb75740eae
+ FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
+ FirebaseCoreExtension: edbd30474b5ccf04e5f001470bdf6ea616af2435
+ FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
+ FirebaseCrashlytics: e09d0bc19aa54a51e45b8039c836ef73f32c039a
+ FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
+ FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09
+ FirebaseRemoteConfigInterop: 1c6135e8a094cc6368949f5faeeca7ee8948b8aa
+ FirebaseSessions: b9a92c1c51bbb81e78fc3142cda6d925d700f8e7
+ FLAnimatedImage: bbf914596368867157cc71b38a8ec834b3eeb32b
+ Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
+ flutter_amazonpaymentservices: 30d57c19319b81de776345023e4f0697c7d94866
+ flutter_app_group_directory: 55b5362007d1c0cb45dc1dd1e94f67d615f45a6b
+ flutter_callkit_incoming: cb8138af67cda6dd981f7101a5d709003af21502
+ flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
+ flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
+ flutter_ios_voip_kit_karmm: 371663476722afb631d5a13a39dee74c56c1abd0
+ flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb
+ flutter_nfc_kit: e1b71583eafd2c9650bc86844a7f2d185fb414f6
+ flutter_paytabs_bridge: 193d7ae44a86bf5a9b618fc839433e721e04012d
+ flutter_screenshot_blocker: 87493b3202126286ddce134a2703fdfc1f9267ea
+ flutter_zoom_videosdk: d0c2be11c6e3bfdae9ace300f878943036cf909c
+ fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
+ geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
+ Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
+ google_maps_flutter_ios: 3213e1e5f5588b6134935cb8fc59acb4e6d88377
+ GoogleAdsOnDeviceConversion: 2be6297a4f048459e0ae17fad9bfd2844e10cf64
+ GoogleAppMeasurement: 700dce7541804bec33db590a5c496b663fbe2539
+ GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
+ GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
+ GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
+ health: 32d2fbc7f26f9a2388d1a514ce168adbfa5bda65
+ image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
+ in_app_review: 7dd1ea365263f834b8464673f9df72c80c17c937
+ just_audio: 4e391f57b79cad2b0674030a00453ca5ce817eed
+ libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
+ live_activities: 4dfa736d0736e1c77866a2f9c056a76513cc9e7b
+ local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb
+ location: 155caecf9da4f280ab5fe4a55f94ceccfab838f8
+ manage_calendar_events: fe1541069431af035ced925ebd9def8b4b271254
+ Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
+ map_launcher: 8051ad5783913cafce93f2414c6858f2904fd8df
+ MapboxCommon: 119f3759f7dc9457f0695848108ab323eb643cb4
+ MapboxCoreMaps: ca17f67baced23f8c952166ac6314c35bad3f66c
+ MapboxCoreNavigation: 3be9990fae3ed732a101001746d0e3b4234ec023
+ MapboxDirections: d4fe7d43cff82aa0c15955d1b4563a5a01e2d4de
+ MapboxMaps: b7f29ec7c33f7dc6d2947c1148edce6db81db9a7
+ MapboxMobileEvents: d044b9edbe0ec7df60f6c2c9634fe9a7f449266b
+ MapboxNavigation: da9cf3d773ed5b0fa0fb388fccdaa117ee681f31
+ MapboxNavigationNative: 629e359f3d2590acd1ebbacaaf99e1a80ee57e42
+ MapboxSpeech: cd25ef99c3a3d2e0da72620ff558276ea5991a77
+ nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
+ network_info_plus: cf61925ab5205dce05a4f0895989afdb6aade5fc
+ open_filex: 432f3cd11432da3e39f47fcc0df2b1603854eff1
+ OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
+ package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
+ path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
+ PayFortSDK: 233eabe9a45601fdbeac67fa6e5aae46ed8faf82
+ PayTabsSDK: 51d21d0174679d08ee816583266aa5f557ebf5ed
+ permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
+ Polyline: 2a1f29f87f8d9b7de868940f4f76deb8c678a5b1
+ PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
+ PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
+ screen_brightness_ios: 28c5fbdb40634de44f86025d84470158ad4df48c
+ SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
+ SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377
+ share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
+ shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
+ Solar-dev: 4612dc9878b9fed2667d23b327f1d4e54e16e8d0
+ sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
+ SwiftProtobuf: 409d3aaec90e51b1705b1dd8065b56893450e77c
+ SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
+ Turf: aa2ede4298009639d10db36aba1a7ebaad072a5e
+ url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
+ video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a
+ wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
+ webview_flutter_wkwebview: 8ebf4fded22593026f7dbff1fbff31ea98573c8d
+ ZoomVideoSDK: c3ac797074847382d9b539044d77f5971d6b62cd
+
+PODFILE CHECKSUM: b2fdde559476ac2931f2a7ceec6cf5a78743c72b
+
+COCOAPODS: 1.16.2
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index fdc3bdfa..d4f26a7e 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -8,24 +8,16 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
- 1587365701FF0D2AAAFED0D8 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
478CFA942E638C8E0064F3D7 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */; };
- 61243B492EC5FA3700D46FA0 /* PenguinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */; };
- 61243B4C2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */; };
- 61243B502EC5FA3700D46FA0 /* PenguinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B452EC5FA3700D46FA0 /* PenguinView.swift */; };
- 61243B542EC5FA3700D46FA0 /* PenguinPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B442EC5FA3700D46FA0 /* PenguinPlugin.swift */; };
- 61243B562EC5FA3700D46FA0 /* PenguinNavigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */; };
- 61243B572EC5FA3700D46FA0 /* PenguinViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B462EC5FA3700D46FA0 /* PenguinViewFactory.swift */; };
+ 58A16A1D1E63FA0AF61318A5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE7076AA781403E32077FCBF /* Pods_Runner.framework */; };
+ 61AE8DCB3010AA4700DB059A /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61D6D9F1300F522E002E5487 /* WidgetKit.framework */; };
+ 61AE8DCC3010AA4700DB059A /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61D6D9F3300F522E002E5487 /* SwiftUI.framework */; };
+ 61AE8DD93010AA4A00DB059A /* live_notificationExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 61AE8DCA3010AA4700DB059A /* live_notificationExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ 61D6DAB9300F718A002E5487 /* LiveActivityHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D6DAB8300F718A002E5487 /* LiveActivityHelper.swift */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
76AA18AE2F3B2A4D00DC8DFC /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */; };
- 76B1D2512F91BF8000DBBD1B /* Penguin.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D24E2F91BF8000DBBD1B /* Penguin.xcframework */; };
- 76B1D2522F91BF8000DBBD1B /* Penguin.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D24E2F91BF8000DBBD1B /* Penguin.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- 76B1D2532F91BF8000DBBD1B /* PenguinINRenderer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D24F2F91BF8000DBBD1B /* PenguinINRenderer.xcframework */; };
- 76B1D2542F91BF8000DBBD1B /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D24F2F91BF8000DBBD1B /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- 76B1D2552F91BF8000DBBD1B /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D2502F91BF8000DBBD1B /* PenNavUI.xcframework */; };
- 76B1D2562F91BF8000DBBD1B /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 76B1D2502F91BF8000DBBD1B /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
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 */; };
@@ -39,18 +31,33 @@
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
+ 61AE8DD73010AA4A00DB059A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 97C146E61CF9000F007C117D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 61AE8DC93010AA4700DB059A;
+ remoteInfo = live_notificationExtension;
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
+ 61D6DA07300F5240002E5487 /* Embed Foundation Extensions */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 13;
+ files = (
+ 61AE8DD93010AA4A00DB059A /* live_notificationExtension.appex in Embed Foundation Extensions */,
+ );
+ name = "Embed Foundation Extensions";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
765A5A922F35CD8B0003FF7D /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
- 76B1D2542F91BF8000DBBD1B /* PenguinINRenderer.xcframework in Embed Frameworks */,
- 76B1D2522F91BF8000DBBD1B /* Penguin.xcframework in Embed Frameworks */,
- 76B1D2562F91BF8000DBBD1B /* PenNavUI.xcframework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -58,30 +65,26 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
- 05E1B2A0E6844572ADA81174 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 237D1205ED89EAB6C90BC64D /* 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 = ""; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
- 3EAE1F31D8D0AA94CA6C11EB /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; };
478CFA952E6E20A60064F3D7 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; };
- 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = ""; };
- 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = ""; };
- 61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = ""; };
- 61243B442EC5FA3700D46FA0 /* PenguinPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinPlugin.swift; sourceTree = ""; };
- 61243B452EC5FA3700D46FA0 /* PenguinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinView.swift; sourceTree = ""; };
- 61243B462EC5FA3700D46FA0 /* PenguinViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinViewFactory.swift; sourceTree = ""; };
+ 612BC91D3011009600FF6F5B /* live_notificationExtensionDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = live_notificationExtensionDebug.entitlements; sourceTree = ""; };
+ 61AE8DCA3010AA4700DB059A /* live_notificationExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = live_notificationExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
+ 61D6D9F1300F522E002E5487 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
+ 61D6D9F3300F522E002E5487 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
+ 61D6DAB8300F718A002E5487 /* LiveActivityHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveActivityHelper.swift; path = Helper/LiveActivityHelper.swift; sourceTree = ""; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = ""; };
76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ring_30Sec.caf; sourceTree = ""; };
- 76B1D24E2F91BF8000DBBD1B /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = ""; };
- 76B1D24F2F91BF8000DBBD1B /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenguinINRenderer.xcframework; path = Frameworks/PenguinINRenderer.xcframework; sourceTree = ""; };
- 76B1D2502F91BF8000DBBD1B /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
- 7BEF44ABFEF585D64D3F266C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
+ 80AB360F7825C2FB720CB86E /* 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 = ""; };
+ 93CFB47A4DD7AA77469CFEC2 /* 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 = ""; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -89,18 +92,49 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ CE7076AA781403E32077FCBF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
+/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
+ 61AE8DDA3010AA4A00DB059A /* Exceptions for "live_notification" folder in "live_notificationExtension" target */ = {
+ isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
+ membershipExceptions = (
+ Info.plist,
+ );
+ target = 61AE8DC93010AA4700DB059A /* live_notificationExtension */;
+ };
+/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
+
+/* Begin PBXFileSystemSynchronizedRootGroup section */
+ 61AE8DCD3010AA4700DB059A /* live_notification */ = {
+ isa = PBXFileSystemSynchronizedRootGroup;
+ exceptions = (
+ 61AE8DDA3010AA4A00DB059A /* Exceptions for "live_notification" folder in "live_notificationExtension" target */,
+ );
+ explicitFileTypes = {
+ };
+ explicitFolders = (
+ );
+ path = live_notification;
+ sourceTree = "";
+ };
+/* End PBXFileSystemSynchronizedRootGroup section */
+
/* Begin PBXFrameworksBuildPhase section */
+ 61AE8DC73010AA4700DB059A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 61AE8DCC3010AA4700DB059A /* SwiftUI.framework in Frameworks */,
+ 61AE8DCB3010AA4700DB059A /* WidgetKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 76B1D2512F91BF8000DBBD1B /* Penguin.xcframework in Frameworks */,
- 76B1D2552F91BF8000DBBD1B /* PenNavUI.xcframework in Frameworks */,
- 76B1D2532F91BF8000DBBD1B /* PenguinINRenderer.xcframework in Frameworks */,
- DE1EF78253E64BE86845D2CC /* Pods_Runner.framework in Frameworks */,
+ 58A16A1D1E63FA0AF61318A5 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -115,33 +149,12 @@
path = RunnerTests;
sourceTree = "";
};
- 61243B412EC5FA3700D46FA0 /* Helper */ = {
- isa = PBXGroup;
- children = (
- 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */,
- );
- path = Helper;
- sourceTree = "";
- };
- 61243B472EC5FA3700D46FA0 /* Penguin */ = {
- isa = PBXGroup;
- children = (
- 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */,
- 61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */,
- 61243B442EC5FA3700D46FA0 /* PenguinPlugin.swift */,
- 61243B452EC5FA3700D46FA0 /* PenguinView.swift */,
- 61243B462EC5FA3700D46FA0 /* PenguinViewFactory.swift */,
- );
- path = Penguin;
- sourceTree = "";
- };
766D8CB22EC60BE600D05E07 /* Frameworks */ = {
isa = PBXGroup;
children = (
- 76B1D24E2F91BF8000DBBD1B /* Penguin.xcframework */,
- 76B1D24F2F91BF8000DBBD1B /* PenguinINRenderer.xcframework */,
- 76B1D2502F91BF8000DBBD1B /* PenNavUI.xcframework */,
- A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */,
+ 61D6D9F1300F522E002E5487 /* WidgetKit.framework */,
+ 61D6D9F3300F522E002E5487 /* SwiftUI.framework */,
+ CE7076AA781403E32077FCBF /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "";
@@ -149,9 +162,9 @@
79DD2093A1D9674C94359FC8 /* Pods */ = {
isa = PBXGroup;
children = (
- 3EAE1F31D8D0AA94CA6C11EB /* Pods-Runner.debug.xcconfig */,
- 05E1B2A0E6844572ADA81174 /* Pods-Runner.release.xcconfig */,
- 7BEF44ABFEF585D64D3F266C /* Pods-Runner.profile.xcconfig */,
+ 237D1205ED89EAB6C90BC64D /* Pods-Runner.debug.xcconfig */,
+ 93CFB47A4DD7AA77469CFEC2 /* Pods-Runner.release.xcconfig */,
+ 80AB360F7825C2FB720CB86E /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -170,8 +183,10 @@
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
+ 612BC91D3011009600FF6F5B /* live_notificationExtensionDebug.entitlements */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
+ 61AE8DCD3010AA4700DB059A /* live_notification */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
79DD2093A1D9674C94359FC8 /* Pods */,
@@ -184,6 +199,7 @@
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
+ 61AE8DCA3010AA4700DB059A /* live_notificationExtension.appex */,
);
name = Products;
sourceTree = "";
@@ -191,9 +207,8 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
+ 61D6DAB8300F718A002E5487 /* LiveActivityHelper.swift */,
76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */,
- 61243B412EC5FA3700D46FA0 /* Helper */,
- 61243B472EC5FA3700D46FA0 /* Penguin */,
769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */,
478CFA952E6E20A60064F3D7 /* Runner.entitlements */,
478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */,
@@ -229,23 +244,45 @@
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
+ 61AE8DC93010AA4700DB059A /* live_notificationExtension */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 61AE8DDB3010AA4A00DB059A /* Build configuration list for PBXNativeTarget "live_notificationExtension" */;
+ buildPhases = (
+ 61AE8DC63010AA4700DB059A /* Sources */,
+ 61AE8DC73010AA4700DB059A /* Frameworks */,
+ 61AE8DC83010AA4700DB059A /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ fileSystemSynchronizedGroups = (
+ 61AE8DCD3010AA4700DB059A /* live_notification */,
+ );
+ name = live_notificationExtension;
+ productName = live_notificationExtension;
+ productReference = 61AE8DCA3010AA4700DB059A /* live_notificationExtension.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
- EA10FC42B68E41E75A052FAA /* [CP] Check Pods Manifest.lock */,
+ 8DED67C11B08C38D4CA4B516 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
+ 61D6DA07300F5240002E5487 /* Embed Foundation Extensions */,
97C146EC1CF9000F007C117D /* Resources */,
765A5A922F35CD8B0003FF7D /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
- 5D78F615DF2D966539B34DE2 /* [CP] Embed Pods Frameworks */,
- 4AA9AE39AD56A64A1F16E548 /* [CP] Copy Pods Resources */,
+ 64913143522DD2E7A5709D09 /* [CP] Embed Pods Frameworks */,
+ 57400ED2A0499CE460F108E2 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
+ 61AE8DD83010AA4A00DB059A /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
@@ -259,6 +296,7 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
+ LastSwiftUpdateCheck = 2640;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
@@ -266,6 +304,9 @@
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
+ 61AE8DC93010AA4700DB059A = {
+ CreatedOnToolsVersion = 26.4.1;
+ };
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
@@ -287,6 +328,7 @@
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
+ 61AE8DC93010AA4700DB059A /* live_notificationExtension */,
);
};
/* End PBXProject section */
@@ -299,6 +341,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 61AE8DC83010AA4700DB059A /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -329,9 +378,9 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
};
- 4AA9AE39AD56A64A1F16E548 /* [CP] Copy Pods Resources */ = {
+ 57400ED2A0499CE460F108E2 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -348,7 +397,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 5D78F615DF2D966539B34DE2 /* [CP] Embed Pods Frameworks */ = {
+ 64913143522DD2E7A5709D09 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -365,42 +414,42 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- 9740EEB61CF901F6004384FC /* Run Script */ = {
+ 8DED67C11B08C38D4CA4B516 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
- alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
+ inputFileListPaths = (
+ );
inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
);
- name = "Run Script";
outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ 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;
};
- EA10FC42B68E41E75A052FAA /* [CP] Check Pods Manifest.lock */ = {
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
);
+ name = "Run Script";
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
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";
- showEnvVarsInLog = 0;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
@@ -413,18 +462,20 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 61AE8DC63010AA4700DB059A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
- 61243B492EC5FA3700D46FA0 /* PenguinModel.swift in Sources */,
- 61243B4C2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift in Sources */,
- 61243B502EC5FA3700D46FA0 /* PenguinView.swift in Sources */,
- 61243B542EC5FA3700D46FA0 /* PenguinPlugin.swift in Sources */,
- 61243B562EC5FA3700D46FA0 /* PenguinNavigator.swift in Sources */,
- 61243B572EC5FA3700D46FA0 /* PenguinViewFactory.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ 61D6DAB9300F718A002E5487 /* LiveActivityHelper.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -436,6 +487,11 @@
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
+ 61AE8DD83010AA4A00DB059A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 61AE8DC93010AA4700DB059A /* live_notificationExtension */;
+ targetProxy = 61AE8DD73010AA4A00DB059A /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -586,6 +642,136 @@
};
name = Profile;
};
+ 61AE8DDC3010AA4A00DB059A /* 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 = live_notificationExtensionDebug.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 = live_notification/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = live_notification;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ IPHONEOS_DEPLOYMENT_TARGET = 26.4;
+ 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.cloudsolutions.HMGPatientApp.live-notification";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 61AE8DDD3010AA4A00DB059A /* 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_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 = live_notification/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = live_notification;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ IPHONEOS_DEPLOYMENT_TARGET = 26.4;
+ 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.cloudsolutions.HMGPatientApp.live-notification";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 61AE8DDE3010AA4A00DB059A /* 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_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 = live_notification/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = live_notification;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ IPHONEOS_DEPLOYMENT_TARGET = 26.4;
+ 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.cloudsolutions.HMGPatientApp.live-notification";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Profile;
+ };
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -703,7 +889,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
+ CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
@@ -769,6 +955,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
+ 61AE8DDB3010AA4A00DB059A /* Build configuration list for PBXNativeTarget "live_notificationExtension" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 61AE8DDC3010AA4A00DB059A /* Debug */,
+ 61AE8DDD3010AA4A00DB059A /* Release */,
+ 61AE8DDE3010AA4A00DB059A /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index dc11bbed..a1a793d9 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -13,11 +13,14 @@ 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
HMGPenguinInPlatformBridge.initialize(flutterViewController: mainViewController)
+ LiveActivityHelper().initialize(mainViewController)
}
}
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){
diff --git a/ios/Runner/Helper/LiveActivityHelper.swift b/ios/Runner/Helper/LiveActivityHelper.swift
new file mode 100644
index 00000000..4ebde7fd
--- /dev/null
+++ b/ios/Runner/Helper/LiveActivityHelper.swift
@@ -0,0 +1,37 @@
+//
+// LiveActivityHelper.swift
+// Runner
+//
+// Created by Cloud Solutions on 28/01/2026.
+//
+
+import Foundation
+
+
+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)
+ }
+
+ }
+ }
+
+}
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 5b3b2681..7cb5fbec 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -95,8 +95,14 @@
This app requires calendar access to set reminders for Virtual & Normal Appointments.
NSSpeechRecognitionUsageDescription
This app requires speech recognition access to access voice command features.
+ NSSupportsLiveActivities
+
NSUserActivityTypes
+ UIAppFonts
+
+ Poppins-Medium.ttf
+
UIApplicationSupportsIndirectInputEvents
UIBackgroundModes
@@ -105,6 +111,7 @@
fetch
remote-notification
voip
+ processing
UILaunchStoryboardName
LaunchScreen
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
index 2c37e774..2b950d14 100644
--- a/ios/Runner/Runner.entitlements
+++ b/ios/Runner/Runner.entitlements
@@ -21,5 +21,9 @@
TAG
+ com.apple.security.application-groups
+
+ group.alhabib.patientApp
+
diff --git a/ios/Runner/RunnerDebug.entitlements b/ios/Runner/RunnerDebug.entitlements
index 319178a4..2b950d14 100644
--- a/ios/Runner/RunnerDebug.entitlements
+++ b/ios/Runner/RunnerDebug.entitlements
@@ -4,6 +4,14 @@
aps-environment
development
+ com.apple.developer.healthkit
+
+ com.apple.developer.healthkit.access
+
+ health-records
+
+ com.apple.developer.healthkit.background-delivery
+
com.apple.developer.in-app-payments
merchant.com.hmgwebservices
@@ -13,5 +21,9 @@
TAG
+ com.apple.security.application-groups
+
+ group.alhabib.patientApp
+
diff --git a/ios/live_notification/Assets.xcassets/AccentColor.colorset/Contents.json b/ios/live_notification/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 00000000..eb878970
--- /dev/null
+++ b/ios/live_notification/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ios/live_notification/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/live_notification/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000..23058801
--- /dev/null
+++ b/ios/live_notification/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -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
+ }
+}
diff --git a/ios/live_notification/Assets.xcassets/Contents.json b/ios/live_notification/Assets.xcassets/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/ios/live_notification/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ios/live_notification/Assets.xcassets/WidgetBackground.colorset/Contents.json b/ios/live_notification/Assets.xcassets/WidgetBackground.colorset/Contents.json
new file mode 100644
index 00000000..eb878970
--- /dev/null
+++ b/ios/live_notification/Assets.xcassets/WidgetBackground.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ios/live_notification/Assets.xcassets/hmg.imageset/Contents.json b/ios/live_notification/Assets.xcassets/hmg.imageset/Contents.json
new file mode 100644
index 00000000..ed588f89
--- /dev/null
+++ b/ios/live_notification/Assets.xcassets/hmg.imageset/Contents.json
@@ -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
+ }
+}
diff --git a/ios/live_notification/Assets.xcassets/hmg.imageset/hmg 1.svg b/ios/live_notification/Assets.xcassets/hmg.imageset/hmg 1.svg
new file mode 100644
index 00000000..ccaed0c3
--- /dev/null
+++ b/ios/live_notification/Assets.xcassets/hmg.imageset/hmg 1.svg
@@ -0,0 +1,5 @@
+
diff --git a/ios/live_notification/Assets.xcassets/hmg.imageset/hmg 2.svg b/ios/live_notification/Assets.xcassets/hmg.imageset/hmg 2.svg
new file mode 100644
index 00000000..ccaed0c3
--- /dev/null
+++ b/ios/live_notification/Assets.xcassets/hmg.imageset/hmg 2.svg
@@ -0,0 +1,5 @@
+
diff --git a/ios/live_notification/Assets.xcassets/hmg.imageset/hmg.svg b/ios/live_notification/Assets.xcassets/hmg.imageset/hmg.svg
new file mode 100644
index 00000000..ccaed0c3
--- /dev/null
+++ b/ios/live_notification/Assets.xcassets/hmg.imageset/hmg.svg
@@ -0,0 +1,5 @@
+
diff --git a/ios/live_notification/Info.plist b/ios/live_notification/Info.plist
new file mode 100644
index 00000000..0f118fb7
--- /dev/null
+++ b/ios/live_notification/Info.plist
@@ -0,0 +1,11 @@
+
+
+
+
+ NSExtension
+
+ NSExtensionPointIdentifier
+ com.apple.widgetkit-extension
+
+
+
diff --git a/ios/live_notification/live_notificationBundle.swift b/ios/live_notification/live_notificationBundle.swift
new file mode 100644
index 00000000..51dfc678
--- /dev/null
+++ b/ios/live_notification/live_notificationBundle.swift
@@ -0,0 +1,16 @@
+//
+// live_notificationBundle.swift
+// live_notification
+//
+// Created by Cloud Solutions on 22/07/2026.
+//
+
+import WidgetKit
+import SwiftUI
+
+@main
+struct live_notificationBundle: WidgetBundle {
+ var body: some Widget {
+ live_notificationLiveActivity()
+ }
+}
diff --git a/ios/live_notification/live_notificationLiveActivity.swift b/ios/live_notification/live_notificationLiveActivity.swift
new file mode 100644
index 00000000..37f8cf07
--- /dev/null
+++ b/ios/live_notification/live_notificationLiveActivity.swift
@@ -0,0 +1,583 @@
+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: "#FFA2A2A2")
+ 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: .colorWhite,
+ 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 currentlyServingStatus: 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("hmg")
+ .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(data.colorConfig.nextStepTextColor)
+
+ }
+ .padding(8)
+ .background(data.colorConfig.nextStepBackground)
+ .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(data.colorConfig.nextStepBackground)
+// .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
+ if !data.currentlyServing.isEmpty {
+ 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.currentlyServingStatus)
+ .font(.system(size: 10, weight: .semibold))
+ .foregroundColor(data.colorConfig.nextStepTextColor)
+ }
+ .padding(8)
+ .background(data.colorConfig.nextStepBackground)
+ .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 currentlyServingStatus
+// 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)
+//
+// // currentlyServingStatus badge
+// Text(data.currentlyServingStatus)
+// .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 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 currentlyServingStatus = 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("currentlyServingcurrentlyServingStatus")) ??
+// "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 currentlyServingStatus = 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
+ let callType = sharedDefault.integer(forKey: context.attributes.prefixedKey("callType")) ?? 0
+
+
+
+
+ // Get color configuration based on nextStepBackground
+ let colorConfig = WidgetColorConfig.config(for: callType)
+
+ // Create widget data
+ let widgetData = NotificationWidgetData(
+ currentTicket: currentTicket,
+ currentlyServingHeader: currentlyServingHeader,
+ currentlyServing: currentlyServing,
+ currentlyServingStatus: currentlyServingStatus,
+ nextStep: nextStep,
+ imageName:"hmg",
+ colorConfig: colorConfig,
+ progress: 33 * Double(callType),
+ 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 currentlyServingStatus = 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 callType = sharedDefault.integer(forKey: context.attributes.prefixedKey("callType")) ?? 0
+
+
+
+ let colorConfig = WidgetColorConfig.config(for: callType)
+ let widgetData = NotificationWidgetData(
+ currentTicket: currentTicket,
+ currentlyServingHeader: currentlyServingHeader,
+ currentlyServing: currentlyServing,
+ currentlyServingStatus: currentlyServingStatus,
+ nextStep: nextStep,
+ imageName:"hmg",
+ colorConfig: colorConfig,
+ progress: 33 * Double(callType),
+ 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(currentlyServingStatus)
+// .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",
+// currentlyServingStatus: "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",
+// currentlyServingStatus: "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",
+// currentlyServingStatus: "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 ""
+ }
+ }
+ }
+ return ""
+}
diff --git a/ios/live_notificationExtensionDebug.entitlements b/ios/live_notificationExtensionDebug.entitlements
new file mode 100644
index 00000000..a1ca053c
--- /dev/null
+++ b/ios/live_notificationExtensionDebug.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.application-groups
+
+ group.alhabib.patientApp
+
+
+
diff --git a/ios/live_notifications/AppIntent.swift b/ios/live_notifications/AppIntent.swift
new file mode 100644
index 00000000..cca69d59
--- /dev/null
+++ b/ios/live_notifications/AppIntent.swift
@@ -0,0 +1,18 @@
+//
+// AppIntent.swift
+// live_notifications
+//
+// Created by Haroon Amjad on 20/07/2026.
+//
+
+import WidgetKit
+import AppIntents
+
+struct ConfigurationAppIntent: WidgetConfigurationIntent {
+ static var title: LocalizedStringResource { "Configuration" }
+ static var description: IntentDescription { "This is an example widget." }
+
+ // An example configurable parameter.
+ @Parameter(title: "Favorite Emoji", default: "😃")
+ var favoriteEmoji: String
+}
diff --git a/ios/live_notifications/Assets.xcassets/AccentColor.colorset/Contents.json b/ios/live_notifications/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 00000000..eb878970
--- /dev/null
+++ b/ios/live_notifications/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ios/live_notifications/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/live_notifications/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000..23058801
--- /dev/null
+++ b/ios/live_notifications/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -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
+ }
+}
diff --git a/ios/live_notifications/Assets.xcassets/Contents.json b/ios/live_notifications/Assets.xcassets/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/ios/live_notifications/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ios/live_notifications/Assets.xcassets/WidgetBackground.colorset/Contents.json b/ios/live_notifications/Assets.xcassets/WidgetBackground.colorset/Contents.json
new file mode 100644
index 00000000..eb878970
--- /dev/null
+++ b/ios/live_notifications/Assets.xcassets/WidgetBackground.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ios/live_notifications/Assets.xcassets/hmg.imageset/Contents.json b/ios/live_notifications/Assets.xcassets/hmg.imageset/Contents.json
new file mode 100644
index 00000000..ed588f89
--- /dev/null
+++ b/ios/live_notifications/Assets.xcassets/hmg.imageset/Contents.json
@@ -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
+ }
+}
diff --git a/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg 1.svg b/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg 1.svg
new file mode 100644
index 00000000..ccaed0c3
--- /dev/null
+++ b/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg 1.svg
@@ -0,0 +1,5 @@
+
diff --git a/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg 2.svg b/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg 2.svg
new file mode 100644
index 00000000..ccaed0c3
--- /dev/null
+++ b/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg 2.svg
@@ -0,0 +1,5 @@
+
diff --git a/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg.svg b/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg.svg
new file mode 100644
index 00000000..ccaed0c3
--- /dev/null
+++ b/ios/live_notifications/Assets.xcassets/hmg.imageset/hmg.svg
@@ -0,0 +1,5 @@
+
diff --git a/ios/live_notifications/Info.plist b/ios/live_notifications/Info.plist
new file mode 100644
index 00000000..0f118fb7
--- /dev/null
+++ b/ios/live_notifications/Info.plist
@@ -0,0 +1,11 @@
+
+
+
+
+ NSExtension
+
+ NSExtensionPointIdentifier
+ com.apple.widgetkit-extension
+
+
+
diff --git a/ios/live_notifications/live_notification.swift b/ios/live_notifications/live_notification.swift
new file mode 100644
index 00000000..9eec9203
--- /dev/null
+++ b/ios/live_notifications/live_notification.swift
@@ -0,0 +1,84 @@
+//
+// live_notifications.swift
+// live_notifications
+//
+// Created by Cloud Solutions on 21/07/2026.
+//
+
+import WidgetKit
+import SwiftUI
+
+struct Provider: TimelineProvider {
+ func placeholder(in context: Context) -> SimpleEntry {
+ SimpleEntry(date: Date(), emoji: "😀")
+ }
+
+ func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
+ let entry = SimpleEntry(date: Date(), emoji: "😀")
+ completion(entry)
+ }
+
+ func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) {
+ 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, emoji: "😀")
+ entries.append(entry)
+ }
+
+ let timeline = Timeline(entries: entries, policy: .atEnd)
+ completion(timeline)
+ }
+
+// func relevances() async -> WidgetRelevances {
+// // Generate a list containing the contexts this widget is relevant in.
+// }
+}
+
+struct SimpleEntry: TimelineEntry {
+ let date: Date
+ let emoji: String
+}
+
+struct live_notificationEntryView : View {
+ var entry: Provider.Entry
+
+ var body: some View {
+ VStack {
+ Text("Time:")
+ Text(entry.date, style: .time)
+
+ Text("Emoji:")
+ Text(entry.emoji)
+ }
+ }
+}
+
+struct live_notification: Widget {
+ let kind: String = "live_notifications"
+
+ var body: some WidgetConfiguration {
+ StaticConfiguration(kind: kind, provider: Provider()) { entry in
+ if #available(iOS 17.0, *) {
+ live_notificationEntryView(entry: entry)
+ .containerBackground(.fill.tertiary, for: .widget)
+ } else {
+ live_notificationEntryView(entry: entry)
+ .padding()
+ .background()
+ }
+ }
+ .configurationDisplayName("My Widget")
+ .description("This is an example widget.")
+ }
+}
+
+#Preview(as: .systemSmall) {
+ live_notification()
+} timeline: {
+ SimpleEntry(date: .now, emoji: "😀")
+ SimpleEntry(date: .now, emoji: "🤩")
+}
diff --git a/ios/live_notifications/live_notificationBundle.swift b/ios/live_notifications/live_notificationBundle.swift
new file mode 100644
index 00000000..2a55111c
--- /dev/null
+++ b/ios/live_notifications/live_notificationBundle.swift
@@ -0,0 +1,16 @@
+//
+// live_notificationBundle.swift
+// live_notifications
+//
+// Created by Haroon Amjad on 20/07/2026.
+//
+
+import WidgetKit
+import SwiftUI
+
+@main
+struct live_notificationBundle: WidgetBundle {
+ var body: some Widget {
+ live_notificationLiveActivity()
+ }
+}
diff --git a/ios/live_notifications/live_notificationLiveActivity.swift b/ios/live_notifications/live_notificationLiveActivity.swift
new file mode 100644
index 00000000..ec976f41
--- /dev/null
+++ b/ios/live_notifications/live_notificationLiveActivity.swift
@@ -0,0 +1,420 @@
+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 currentServingStatusBackground
+struct WidgetColorConfig {
+ let currentServingStatusBackground: Color
+ let currentServingStatusTextColor: Color
+ let containerBorderColor: Color
+
+ static func config(for value: Int) -> WidgetColorConfig {
+ switch value {
+ case 0:
+ return WidgetColorConfig(
+ currentServingStatusBackground: .inactiveColor,
+ currentServingStatusTextColor: .textColor,
+ containerBorderColor: .yellowColor
+ )
+ case 1:
+ return WidgetColorConfig(
+ currentServingStatusBackground: .redColorText,
+ currentServingStatusTextColor: .colorWhite,
+ containerBorderColor: .redColorText
+ )
+ case 2:
+ return WidgetColorConfig(
+ currentServingStatusBackground: .successColor,
+ currentServingStatusTextColor: .colorWhite,
+ containerBorderColor: .successColor
+ )
+ default:
+ return WidgetColorConfig(
+ currentServingStatusBackground: .inactiveColor,
+ currentServingStatusTextColor: .textColor,
+ containerBorderColor: .yellowColor
+ )
+ }
+ }
+}
+
+// MARK: - Widget Data Model
+struct NotificationWidgetData {
+ let queueNo: String
+ let yourTicketHeader: String
+ let currentlyServing: String
+ let status: Int
+ let currentServingStatus: String
+ let imageName: String
+ let nextTicketStatus: 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.queueNo)
+ // .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.yourTicketHeader)
+ .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.queueNo)
+ .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.currentServingStatus)
+ .font(.custom("Poppins-Medium", size: 12))
+ .foregroundColor(data.colorConfig.currentServingStatusTextColor)
+ .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.currentServingStatus)
+ .font(.custom("Poppins-Medium", size: 12))
+ .foregroundColor(data.colorConfig.currentServingStatusTextColor)
+ .padding(.horizontal, 12)
+ .padding(.vertical, 8)
+ .background(
+ RoundedRectangle(cornerRadius: 8)
+ .fill(data.colorConfig.currentServingStatusBackground)
+ )
+ .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")) ?? ""
+ let yourTicketHeader = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingHeader")) ?? ""
+ let nextTicketStatus = sharedDefault.string(forKey: context.attributes.prefixedKey("nextTicketStatus")) ?? ""
+
+ let queueNo = sharedDefault.string(forKey: context.attributes.prefixedKey("queueNo")) ?? ""
+ let currentlyServingToken = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingToken")) ?? ""
+ let currentlyServing = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingTitle")) ?? ""
+ let currentServingStatus = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingStatus")) ??
+ ""
+ let currentServingStatusBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("currentlyServingCallType"))
+
+ let status = sharedDefault.integer(forKey: context.attributes.prefixedKey("callType")) ?? 0
+
+
+ // Get color configuration based on currentServingStatusBackground
+ let colorConfig = WidgetColorConfig.config(for: status)
+
+ // Create widget data
+ let widgetData = NotificationWidgetData(
+ queueNo: queueNo,
+ yourTicketHeader: yourTicketHeader,
+ currentlyServing: currentlyServing,
+ status: status,
+ currentServingStatus: currentServingStatus,
+ imageName:"hmg",
+ nextTicketStatus:nextTicketStatus,
+ colorConfig: colorConfig
+ )
+//
+ // Lock screen/banner UI
+ NotificationWidgetView(data: widgetData)
+ .activityBackgroundTint(Color.clear)
+ .activitySystemActionForegroundColor(Color.black)
+
+ // Text(widgetData.queueNo)
+ // .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 queueNo = 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 currentServingStatus = sharedDefault.string(forKey: context.attributes.prefixedKey("currentlyServingStatus")) ??
+ "test111"
+ let currentServingStatusBackground = sharedDefault.integer(forKey: context.attributes.prefixedKey("currentlyServingCallType"))
+
+
+ let colorConfig = WidgetColorConfig.config(for: currentServingStatusBackground)
+
+ return DynamicIsland {
+ // Expanded UI
+ DynamicIslandExpandedRegion(.leading) {
+ VStack(alignment: .leading) {
+ Text(queueNo)
+ .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.currentServingStatusBackground.opacity(0.2))
+ )
+
+ Spacer()
+
+ Text(currentServingStatus)
+ .font(.caption2)
+ .foregroundColor(colorConfig.currentServingStatusTextColor)
+ .padding(.horizontal, 8)
+ .padding(.vertical, 4)
+ .background(
+ RoundedRectangle(cornerRadius: 6)
+ .fill(colorConfig.currentServingStatusBackground)
+ )
+ }
+ .padding(.horizontal)
+ }
+
+ } compactLeading: {
+ // Compact leading view
+ Text(queueNo)
+ .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(queueNo)
+ .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 {
+ print("the id to get the element is \(id)")
+ return "\(id)_\(key)"
+ }
+}
+// MARK: - Preview for Testing
+struct NotificationWidgetView_Previews: PreviewProvider {
+ static var previews: some View {
+ Group {
+ // Preview with currentServingStatusBackground = 0 (Yellow border)
+ NotificationWidgetView(
+ data: NotificationWidgetData(
+ queueNo: "42",
+ yourTicketHeader: "Currently Serving3:",
+ currentlyServing: "Customer #15",
+ status: 0,
+ currentServingStatus: "Next: Prepare Order",
+ imageName: "bell.fill",
+ nextTicketStatus: "bell.fill",
+ colorConfig: .config(for: 0)
+ )
+ )
+ .previewDisplayName("Yellow Border (0)")
+
+ // Preview with currentServingStatusBackground = 1 (Red border)
+ NotificationWidgetView(
+ data: NotificationWidgetData(
+ queueNo: "89",
+ yourTicketHeader: "Currently Serving2:",
+ currentlyServing: "Customer #67",
+ status: 1,
+ currentServingStatus: "Next: Quality Check",
+ imageName: "bell.fill",
+ nextTicketStatus: "bell.fill",
+ colorConfig: .config(for: 1)
+ )
+ )
+ .previewDisplayName("Red Border (1)")
+
+ // Preview with currentServingStatusBackground = 2 (Green border)
+ NotificationWidgetView(
+ data: NotificationWidgetData(
+ queueNo: "125",
+ yourTicketHeader: "Currently Serving1:",
+ currentlyServing: "Customer #98",
+ status: 1,
+ currentServingStatus: "Next: Ready for Pickup",
+ imageName: "bell.fill",
+ nextTicketStatus: "bell.fill",
+ colorConfig: .config(for: 2)
+ )
+ )
+ .previewDisplayName("Green Border (2)")
+ }
+ .padding()
+ .previewLayout(.sizeThatFits)
+ }
+}
diff --git a/ios/liveappExtension.entitlements b/ios/liveappExtension.entitlements
new file mode 100644
index 00000000..a1ca053c
--- /dev/null
+++ b/ios/liveappExtension.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.application-groups
+
+ group.alhabib.patientApp
+
+
+
diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart
index a27b727e..4b3d2e0c 100644
--- a/lib/core/app_state.dart
+++ b/lib/core/app_state.dart
@@ -47,6 +47,7 @@ class AppState {
AuthenticatedUser? _authenticatedChildUser;
bool isPaytabsEnabled = false;
+ bool isLiveActivityEnabled = true;
bool isPayfortHostedPageEnabled = true;
void setIsPaytabsEnabled(bool value) {
diff --git a/lib/core/cache_consts.dart b/lib/core/cache_consts.dart
index 758676b2..e10f0679 100644
--- a/lib/core/cache_consts.dart
+++ b/lib/core/cache_consts.dart
@@ -81,5 +81,7 @@ class CacheConst {
static const String zoomRoomID = 'zoom-room-id';
static const String callTypeID = 'call-type-id';
static String isAppOpenedFromCall = "is_app_opened_from_call";
+
+ static const String patientQueueNoForLiveActivity = "QUEUENO_FOR_ACTIVITYID";
static const String organSelectorTutorialShown = 'organ_selector_tutorial_shown';
}
diff --git a/lib/core/common_models/patient_queue.dart b/lib/core/common_models/patient_queue.dart
new file mode 100644
index 00000000..82b3d3dd
--- /dev/null
+++ b/lib/core/common_models/patient_queue.dart
@@ -0,0 +1,30 @@
+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.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.
+ Map toMap() {
+ return {
+ 'queueNo': queueNo,
+ 'currentlyServingStatus': currentlyServingStatus,
+ 'nextTicketStatus': nextTicketStatus,
+ 'callType': callType,
+ 'currentlyServingToken': currentlyServingToken,
+ 'currentlyServingCallType': currentlyServingCallType,
+ 'yourTicketHeader':yourTicketHeader,
+ 'currentlyServingTitle':currentlyServingTitle,
+ };
+ }
+}
\ No newline at end of file
diff --git a/lib/core/firebase_message.dart b/lib/core/firebase_message.dart
new file mode 100644
index 00000000..0a236613
--- /dev/null
+++ b/lib/core/firebase_message.dart
@@ -0,0 +1,38 @@
+
+
+// Background message handler (must be top-level function)
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
+
+@pragma('vm:entry-point')
+Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
+ await Firebase.initializeApp();
+ print('Handling background message: ${message.messageId}');
+}
+
+class NotificationService {
+ final FirebaseMessaging _fcm = FirebaseMessaging.instance;
+
+
+ Future initialize() async {
+
+ String? token = await _fcm. getToken();
+ print('FCM Token: $token');
+
+ // Set up background handler
+ FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
+
+ // Foreground message handler
+ FirebaseMessaging.onMessage.listen(_handleForegroundMessage);
+
+ }
+
+ // Foreground message handler
+ void _handleForegroundMessage(RemoteMessage message) {
+ print('Foreground notification: ${message.notification?.title}');
+
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/lib/core/utils/calender_utils_new.dart b/lib/core/utils/calender_utils_new.dart
index f733f82e..702f23ce 100644
--- a/lib/core/utils/calender_utils_new.dart
+++ b/lib/core/utils/calender_utils_new.dart
@@ -93,13 +93,13 @@ class CalenderUtilsNew {
// String eventId = await getEventIdIfEventExist(title!.split("#").last);
// if (eventId.isEmpty) {
eventResult = await DeviceCalendar.instance.createEvent(
- calendarId: writableCalendars!.id,
- title: title,
- description: description,
- startDate: scheduleDateTime!,
- endDate: scheduleDateTime!.add(Duration(minutes: 30)),
-
- reminderMinutes: reminderMinutes, // TODO : NEED TO CONFIRM THIS FROM TAHA
+ calendarId: writableCalendars!.id,
+ title: title,
+ description: description,
+ startDate: scheduleDateTime!,
+ endDate: scheduleDateTime!.add(Duration(minutes: 30)),
+ reminderMinutes: reminderMinutes
+ // TODO : NEED TO CONFIRM THIS FROM TAHA
);
return eventResult.isNotEmpty;
// }
diff --git a/lib/core/utils/live_activty_helper_channel.dart b/lib/core/utils/live_activty_helper_channel.dart
new file mode 100644
index 00000000..e59f30e2
--- /dev/null
+++ b/lib/core/utils/live_activty_helper_channel.dart
@@ -0,0 +1,14 @@
+import 'package:flutter/services.dart';
+
+class LiveActivityHelperChannel {
+ static const MethodChannel _channel = MethodChannel('clear_data');
+
+ static Future removeData() async {
+ try {
+ await _channel.invokeMethod('clearUserDefaultData');
+ } on PlatformException catch (e) {
+ print("Failed to removeData: '${e.message}'.");
+ }
+ }
+
+}
diff --git a/lib/core/utils/push_notification_handler.dart b/lib/core/utils/push_notification_handler.dart
index 89f6969a..3b09b1cb 100644
--- a/lib/core/utils/push_notification_handler.dart
+++ b/lib/core/utils/push_notification_handler.dart
@@ -1,13 +1,16 @@
import 'dart:async';
import 'dart:developer';
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';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
import 'package:flutter_callkit_incoming/entities/android_params.dart';
import 'package:flutter_callkit_incoming/entities/call_kit_params.dart';
import 'package:flutter_callkit_incoming/entities/ios_params.dart';
@@ -15,12 +18,21 @@ import 'package:flutter_callkit_incoming/entities/notification_params.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
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/api/api_client.dart';
import 'package:hmg_patient_app_new/core/api_consts.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/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.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:hmg_patient_app_new/features/notifications/models/resp_models/notification_response_model.dart';
import 'package:hmg_patient_app_new/presentation/notifications/notification_details_page.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
@@ -40,14 +52,118 @@ Future backgroundMessageHandler(dynamic message) async {
log("Firebase backgroundMessageHandler!!!");
await Firebase.initializeApp();
fir.RemoteMessage message_;
+ if(message.data == null ){
+ return;
+ }
- if (message.data != null && (message.data['is_call'] == 'true' || message.data['is_call'] == true)) {
+ if (message.data['is_call'] == 'true' || message.data['is_call'] == true) {
// showCallkitIncoming(message);
_incomingCall(message.data);
return;
}
+ if (message.data['isLiveActivity'] == true || message.data['isLiveActivity'] == "true") {
+ try {
+ // Initialize Firebase
+ await Firebase.initializeApp();
+ WidgetsFlutterBinding.ensureInitialized();
+ DartPluginRegistrant.ensureInitialized();
+ await Future.delayed(Duration(seconds: 2));
+ Utils.addLiveNotification(message, isBackgroundMessage: true);
+ } catch (e, stackTrace) {
+ }
+ }
}
+// 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();
+//
+// 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(data.data['callType']??"1"), data.data['roomNo']);
+// PatientQueue _patientQueue = PatientQueue(
+// 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(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 = "";
+// }
+//
+// if( activityId == ""){
+// String? id = await liveActivity.createActivity(
+// DateTime.now().millisecondsSinceEpoch.toString(),
+// _patientQueue.toMap(),
+// );
+// await Utils.saveStringFromPrefs(_patientQueue.queueNo ??"", id??"");
+// await Utils.saveStringFromPrefs(CacheConst.patientQueueNoForLiveActivity ??"", _patientQueue.queueNo??"");
+// return;
+// }
+// if(Platform.isIOS) {
+// await liveActivity.createOrUpdateActivity(
+// activityId,
+// _patientQueue.toMap(),
+// );
+// }else{
+// await liveActivity.updateActivity(
+// activityId,
+// _patientQueue.toMap(),
+// );
+// }
+// }
+
callPage(String sessionID, String token) async {}
_incomingCall(Map data) async {
@@ -309,7 +425,6 @@ class PushNotificationHandler {
// late HmsApiAvailability hmsApiAvailability;
final voIPKit = FlutterIOSVoIPKit.instance;
-
late Timer timeOutTimer;
bool isTalking = false;
@@ -355,166 +470,172 @@ class PushNotificationHandler {
init(BuildContext context) async {
this.context = context;
+ final PermissionStatus status = await Permission.notification.request();
+ if (status.isGranted) {
+ // Notification permissions granted
+ } else if (status.isDenied) {
+ // Notification permissions denied
- await requestPermissions();
+ await requestPermissions();
- if (Platform.isIOS) {
- voIPKit.getVoIPToken().then((value) {
- log("🎈 APNS VOIP KIT TOKEN: $value");
- Utils.saveStringFromPrefs(CacheConst.voipToken, value ?? "");
- // AppSharedPreferences().setString(APNS_TOKEN, value!);
- });
-
- voIPKit.onDidUpdatePushToken = (String token) {
- log('🎈 example: onDidUpdatePushToken: $token');
- };
-
- voIPKit.onDidReceiveIncomingPush = (
- Map payload,
- ) async {
- log('🎈 example: onDidReceiveIncomingPush $payload');
- // _timeOut();
- };
-
- voIPKit.onDidRejectIncomingCall = (
- String uuid,
- String callerId,
- ) async {
- try {
- log('🎈 example: onDidRejectIncomingCall $uuid - $callerId');
- timeOutTimer.cancel();
- // Cleanup on reject with API call
- if (_currentCallId != null) {
- await _endCallAndCleanup(_currentCallId!, isDeclined: true);
- }
- } catch (err) {
- log(err.toString());
- }
- };
-
- voIPKit.onDidAcceptIncomingCall = (
- String uuid,
- String callerId,
- ) async {
- log('🎈 example: onDidAcceptIncomingCall $uuid - $callerId');
- await voIPKit.acceptIncomingCall(callerState: CallStateType.calling);
- await voIPKit.callConnected();
-
- // Cleanup on accept - cancel timer and reset flags
- _callTimeoutTimer?.cancel();
- _callTimeoutTimer = null;
- _isCallInProgress = false;
- _currentCallId = null;
- await Future.delayed(Duration(seconds: 2)).then((val) async {
- await voIPKit.endCall();
+ if (Platform.isIOS) {
+ voIPKit.getVoIPToken().then((value) {
+ log("🎈 APNS VOIP KIT TOKEN: $value");
+ Utils.saveStringFromPrefs(CacheConst.voipToken, value ?? "");
+ // AppSharedPreferences().setString(APNS_TOKEN, value!);
});
- // Navigator.pushNamed(
- // locator().navigatorKey.currentContext!,
- // "zoom_call_page",
- // arguments: CallArguments("hoover-dam", "123", "Patient", "40", "1", false),
- // );
-
- // Navigator.pushNamed(navigatorKey.currentContext!, VIDEO_CALL_SCREEN,
- // arguments: VideoArgus(
- // reservationId: int.parse(callerId), token: null, isVideo: true));
+ voIPKit.onDidUpdatePushToken = (String token) {
+ log('🎈 example: onDidUpdatePushToken: $token');
+ };
+
+ voIPKit.onDidReceiveIncomingPush = (
+ Map payload,
+ ) async {
+ log('🎈 example: onDidReceiveIncomingPush $payload');
+ // _timeOut();
+ };
+
+ voIPKit.onDidRejectIncomingCall = (
+ String uuid,
+ String callerId,
+ ) async {
+ try {
+ log('🎈 example: onDidRejectIncomingCall $uuid - $callerId');
+ timeOutTimer.cancel();
+ // Cleanup on reject with API call
+ if (_currentCallId != null) {
+ await _endCallAndCleanup(_currentCallId!, isDeclined: true);
+ }
+ } catch (err) {
+ log(err.toString());
+ }
+ };
+
+ voIPKit.onDidAcceptIncomingCall = (
+ String uuid,
+ String callerId,
+ ) async {
+ log('🎈 example: onDidAcceptIncomingCall $uuid - $callerId');
+ await voIPKit.acceptIncomingCall(callerState: CallStateType.calling);
+ await voIPKit.callConnected();
+
+ // Cleanup on accept - cancel timer and reset flags
+ _callTimeoutTimer?.cancel();
+ _callTimeoutTimer = null;
+ _isCallInProgress = false;
+ _currentCallId = null;
+ await Future.delayed(Duration(seconds: 2)).then((val) async {
+ await voIPKit.endCall();
+ });
+
+ // Navigator.pushNamed(
+ // locator().navigatorKey.currentContext!,
+ // "zoom_call_page",
+ // arguments: CallArguments("hoover-dam", "123", "Patient", "40", "1", false),
+ // );
+
+ // Navigator.pushNamed(navigatorKey.currentContext!, VIDEO_CALL_SCREEN,
+ // arguments: VideoArgus(
+ // reservationId: int.parse(callerId), token: null, isVideo: true));
+
+ // timeOutTimer.cancel();
+ };
+ }
- // timeOutTimer.cancel();
- };
- }
+ if (Platform.isAndroid) {
+ try {
+ final fcmToken = await FirebaseMessaging.instance.getToken().catchError((err) {
+ log(err);
+ });
+ if (fcmToken != null) onToken(fcmToken);
+ // }
+ } catch (ex) {
+ log("Notification Exception: $ex");
+ }
+ FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
+ }
- if (Platform.isAndroid) {
- try {
- final fcmToken = await FirebaseMessaging.instance.getToken().catchError((err) {
- log(err);
+ if (Platform.isIOS) {
+ final permission = await FirebaseMessaging.instance.requestPermission();
+ await FirebaseMessaging.instance.getAPNSToken().then((value) async {
+ log("APNS token: $value");
+ await Utils.saveStringFromPrefs(CacheConst.apnsToken, value.toString());
});
- if (fcmToken != null) onToken(fcmToken);
- // }
- } catch (ex) {
- log("Notification Exception: $ex");
+ await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
+ alert: true, // Required to display a heads up notification
+ badge: true,
+ sound: true,
+ );
+ // if (permission.authorizationStatus == AuthorizationStatus.denied) return;
+ } else {
+ final permission = await FirebaseMessaging.instance.requestPermission();
}
- FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
- }
- if (Platform.isIOS) {
- final permission = await FirebaseMessaging.instance.requestPermission();
- await FirebaseMessaging.instance.getAPNSToken().then((value) async {
- log("APNS token: $value");
- await Utils.saveStringFromPrefs(CacheConst.apnsToken, value.toString());
- });
- await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
- alert: true, // Required to display a heads up notification
- badge: true,
- sound: true,
- );
- // if (permission.authorizationStatus == AuthorizationStatus.denied) return;
- } else {
- final permission = await FirebaseMessaging.instance.requestPermission();
- }
-
- try {
- FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) async {
- if (message != null) {
- if (Platform.isIOS) {
- await Future.delayed(Duration(milliseconds: 3000)).then((value) {
- if (message != null) newMessage(message);
- });
- } else if (message != null) newMessage(message);
+ try {
+ FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) async {
+ if (message != null) {
+ if (Platform.isIOS) {
+ await Future.delayed(Duration(milliseconds: 3000)).then((value) {
+ if (message != null) newMessage(message);
+ });
+ } else if (message != null) newMessage(message);
+ }
+ });
+ } catch (ex) {}
+
+ FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
+ log("Firebase onMessage!!!");
+ // showCallkitIncoming();
+ if (Platform.isIOS) {
+ await Future.delayed(Duration(milliseconds: 3000)).then((value) {
+ newMessage(message);
+ });
+ } else {
+ newMessage(message);
}
});
- } catch (ex) {}
- FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
- log("Firebase onMessage!!!");
- // showCallkitIncoming();
- if (Platform.isIOS) {
- await Future.delayed(Duration(milliseconds: 3000)).then((value) {
+ FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
+ log("Firebase onMessageOpenedApp!!!");
+ if (Platform.isIOS) {
+ await Future.delayed(Duration(milliseconds: 3000)).then((value) {
+ newMessage(message);
+ });
+ } else {
newMessage(message);
- });
- } else {
- newMessage(message);
- }
- });
+ }
+ });
- FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
- log("Firebase onMessageOpenedApp!!!");
if (Platform.isIOS) {
- await Future.delayed(Duration(milliseconds: 3000)).then((value) {
- newMessage(message);
+ FirebaseMessaging.instance.getAPNSToken().then((String? token) {
+ log("Push Notification getAPNSToken: ${token!}");
+ }).catchError((err) {
+ log("Push Notification getAPNSToken ERR: ${err.toString()}");
});
- } else {
- newMessage(message);
}
- });
- if (Platform.isIOS) {
- FirebaseMessaging.instance.getAPNSToken().then((String? token) {
- log("Push Notification getAPNSToken: ${token!}");
+ FirebaseMessaging.instance.getToken().then((String? token) {
+ log("Push Notification getToken: ${token!}");
+ onToken(token!);
}).catchError((err) {
- log("Push Notification getAPNSToken ERR: ${err.toString()}");
+ log(err.toString());
});
- }
- FirebaseMessaging.instance.getToken().then((String? token) {
- log("Push Notification getToken: ${token!}");
- onToken(token!);
- }).catchError((err) {
- log(err.toString());
- });
-
- FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
- log("Push Notification onTokenRefresh: $fcm_token");
- onToken(fcm_token);
- });
-
- if (Platform.isAndroid) {
- final deviceInfo = DeviceInfoPlugin();
- final androidInfo = await deviceInfo.androidInfo;
-
- // int sdkInt = androidInfo.version.sdkInt ?? 0;
- // if (sdkInt >= 33) {
- // await FlutterCallkitIncoming.requestFullIntentPermission();
- // }
+ FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
+ log("Push Notification onTokenRefresh: $fcm_token");
+ onToken(fcm_token);
+ });
+
+ if (Platform.isAndroid) {
+ final deviceInfo = DeviceInfoPlugin();
+ final androidInfo = await deviceInfo.androidInfo;
+
+ // int sdkInt = androidInfo.version.sdkInt ?? 0;
+ // if (sdkInt >= 33) {
+ // await FlutterCallkitIncoming.requestFullIntentPermission();
+ // }
+ }
}
}
@@ -523,30 +644,58 @@ class PushNotificationHandler {
if (remoteMessage.data.isEmpty) {
return;
}
- log('the value of the remote message is ${remoteMessage.data}');
+ log('the value of the remote message is 1 ${remoteMessage.data}');
if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) {
_incomingCall(remoteMessage.data);
// showCallkitIncoming();
} else {
- NotificationResponseModel notification = NotificationResponseModel();
-
- notification.createdOn = DateUtil.convertDateToString(DateTime.now());
- notification.isSentOn = DateUtil.convertDateToString(DateTime.now());
- notification.messageTypeData = remoteMessage.data['picture'];
- notification.messageType = notification.messageTypeData != null && notification.messageTypeData!.isNotEmpty ? "image" : "";
- notification.message = remoteMessage.data['message'];
- notification.notificationType = remoteMessage.data["NotificationType"].toString();
- if (remoteMessage.data["NotificationType"] == "2") {
- notification.videoURL = remoteMessage.data["VideoUrl"];
+
+ if(remoteMessage.data['isLiveActivity'] == true || remoteMessage.data['isLiveActivity'] == 'true'){
+ // print("live activity called");
+ // LiveActivities().init(appGroupId: "group.alhabib.patientApp");
+ // await LiveActivities().endAllActivities();
+ // // await Permission.notification.request();
+ // var buttonText = Utils.getCardButtonText(int.parse(remoteMessage.data['callType']??"1"), remoteMessage.data['roomNo']);
+ // PatientQueue _patientQueue =
+ // PatientQueue(
+ // queueNo: remoteMessage.data['queueNo'] ?? "IME-1",
+ // currentlyServingStatus: (remoteMessage.data['servingCallType'] ?? 0) == 1 ? "Call for vital signs".needTranslation : "Call for Doctor".needTranslation,
+ // currentlyServingTitle: remoteMessage.data['servingQueueNo'] ?? "IME-3",
+ // nextTicketStatus: buttonText,
+ // callType: int.parse(remoteMessage.data['callType']??"1"),currentlyServingCallType: int.parse(remoteMessage.data['servingCallType']??"1"));
+ // var activity = await LiveActivities().createActivity(
+ // DateTime.now().millisecondsSinceEpoch.toString(),
+ // _patientQueue.toMap(),
+ // );
+ // print("the activity is $activity");
+
+ Utils.addLiveNotification(remoteMessage, isBackgroundMessage: false);
+
}
+ else {
+ NotificationResponseModel notification = NotificationResponseModel();
+
+ notification.createdOn = DateUtil.convertDateToString(DateTime.now());
+ notification.isSentOn = DateUtil.convertDateToString(DateTime.now());
+ notification.messageTypeData = remoteMessage.data['picture'];
+ notification.messageType = notification.messageTypeData != null && notification.messageTypeData!.isNotEmpty ? "image" : "";
+ notification.message = remoteMessage.data['message'];
+ notification.notificationType = remoteMessage.data["NotificationType"].toString();
+ if (remoteMessage.data["NotificationType"] == "2") {
+ notification.videoURL = remoteMessage.data["VideoUrl"];
+ }
- Navigator.of(getIt.get().navigatorKey.currentContext!).push(
- CustomPageRoute(
- page: NotificationDetailsPage(
- notification: notification,
+ Navigator.of(getIt
+ .get()
+ .navigatorKey
+ .currentContext!).push(
+ CustomPageRoute(
+ page: NotificationDetailsPage(
+ notification: notification,
+ ),
),
- ),
- );
+ );
+ }
// GetNotificationsResponseModel notification = new GetNotificationsResponseModel();
//
diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart
index 320bd1cf..9818d592 100644
--- a/lib/core/utils/utils.dart
+++ b/lib/core/utils/utils.dart
@@ -15,8 +15,11 @@ import 'package:get_it/get_it.dart';
import 'package:google_api_availability/google_api_availability.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
+import 'package:hmg_patient_app_new/core/cache_consts.dart';
+import 'package:hmg_patient_app_new/core/common_models/patient_queue.dart';
import 'package:hmg_patient_app_new/core/common_models/privilege/ProjectDetailListModel.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/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
@@ -30,6 +33,7 @@ import 'package:hmg_patient_app_new/widgets/dialogs/confirm_dialog.dart';
import 'package:hmg_patient_app_new/widgets/loading_dialog.dart';
import 'package:hmg_patient_app_new/widgets/accessibility/preserve_image_colors.dart';
import 'package:hmg_patient_app_new/widgets/accessibility/preserve_svg_colors.dart';
+import 'package:live_activities/live_activities.dart';
import 'package:lottie/lottie.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -1172,4 +1176,61 @@ class Utils {
return normalized;
}
+
+ static addLiveNotification(dynamic data, {bool isBackgroundMessage = false}) async {
+ debugPrint("live activity is enabled or not ${getIt().isLiveActivityEnabled}");
+ if(!getIt().isLiveActivityEnabled) return;
+
+ var liveActivity = LiveActivities();
+
+ 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(data.data['callType'] ?? "0"), data.data['roomNo']);
+ PatientQueue _patientQueue = PatientQueue(
+ queueNo: data.data['queueNo'] ?? "",
+ currentlyServingStatus: (data.data['servingCallType'] ?? 0) == "1" ? LocaleKeys.callForVitalSign.tr() : LocaleKeys.callForDoctor.tr(),
+ currentlyServingToken: data.data['servingQueueNo'] ?? "",
+ nextTicketStatus: buttonText,
+ callType: int.parse(data.data['callType'] ?? "0"),
+ currentlyServingCallType: data.data['servingCallType'].isEmpty?0:int.parse(data.data['servingCallType'] ?? "0"),
+ yourTicketHeader: LocaleKeys.yourQueueNumber.tr(),
+ currentlyServingTitle: LocaleKeys.currentServing.tr());
+ if ((queueNoForWhichActivityIdCreated ?? "") != (_patientQueue.queueNo ?? "")) {
+ liveActivity.endAllActivities();
+ activityId = "";
+ }
+
+ if (activityId == "") {
+ String? id = await liveActivity.createActivity(
+ DateTime.now().millisecondsSinceEpoch.toString(),
+ _patientQueue.toMap(),
+ );
+ await Utils.saveStringFromPrefs(_patientQueue.queueNo ?? "", id ?? "");
+ await Utils.saveStringFromPrefs(CacheConst.patientQueueNoForLiveActivity ?? "", _patientQueue.queueNo ?? "");
+ return;
+ }
+ // if (Platform.isIOS) {
+ // await liveActivity.createOrUpdateActivity(
+ // activityId,
+ // _patientQueue.toMap(),
+ // );
+ // } else {
+ try{
+ await liveActivity.updateActivity(
+ activityId,
+ _patientQueue.toMap(),
+ );}
+ catch(e){
+ await liveActivity.createOrUpdateActivity(
+ activityId,
+ _patientQueue.toMap(),
+ );
+ }
+ // }
+ }
}
diff --git a/lib/features/my_appointments/models/patient_queue_live_notification_model.dart b/lib/features/my_appointments/models/patient_queue_live_notification_model.dart
new file mode 100644
index 00000000..d151e6db
--- /dev/null
+++ b/lib/features/my_appointments/models/patient_queue_live_notification_model.dart
@@ -0,0 +1,3 @@
+class QueueLiveNotificationModel {
+ Map data = {};
+}
diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart
index b480a354..1fe3dccb 100644
--- a/lib/features/my_appointments/my_appointments_view_model.dart
+++ b/lib/features/my_appointments/my_appointments_view_model.dart
@@ -12,6 +12,7 @@ import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_favorite_doctors_list.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/appointemnet_filters.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/patient_queue_live_notification_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/reminder_type.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/appointment_parking_QR_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/appointment_rated_response_model.dart';
@@ -1026,6 +1027,19 @@ class MyAppointmentsViewModel extends ChangeNotifier {
// if (patientQueueDetailsList.length > 1) {
patientQueueDetailsList.removeWhere((element) => element.patientID == patientArrivedAppointmentsHistoryList.first.patientID);
// }
+
+ QueueLiveNotificationModel queueLiveNotificationModel = QueueLiveNotificationModel();
+
+ queueLiveNotificationModel.data = {
+ "queueNo": currentPatientQueueDetails.queueNo,
+ "callType": currentPatientQueueDetails.callType.toString(),
+ "servingQueueNo": patientQueueDetailsList.isEmpty ? null : patientQueueDetailsList.first.queueNo,
+ "servingCallType": patientQueueDetailsList.isEmpty ? null : patientQueueDetailsList.first.callType.toString(),
+ "roomNo": patientQueueDetailsList.isEmpty ? "" : patientQueueDetailsList.first.roomNo,
+ "servingNow": "true"
+ };
+
+ Utils.addLiveNotification(queueLiveNotificationModel, isBackgroundMessage: false);
} else {
patientQueueDetailsList.clear();
isPatientHasQueueAppointment = false;
diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart
index 80cea8b4..e9f6d9c5 100644
--- a/lib/generated/locale_keys.g.dart
+++ b/lib/generated/locale_keys.g.dart
@@ -932,6 +932,10 @@ 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';
static const appointmentDetails = 'appointmentDetails';
static const checkingDoctorAvailability = 'checkingDoctorAvailability';
static const cancellingAppointmentPleaseWait = 'cancellingAppointmentPleaseWait';
@@ -1043,7 +1047,6 @@ abstract class LocaleKeys {
static const thankYouForPatience = 'thankYouForPatience';
static const servingNow = 'servingNow';
static const callForVitalSigns = 'callForVitalSigns';
- static const callForDoctor = 'callForDoctor';
static const thingsToAskDoctor = 'thingsToAskDoctor';
static const improveOverallHealth = 'improveOverallHealth';
static const routineScreenings = 'routineScreenings';
diff --git a/lib/main.dart b/lib/main.dart
index aa266871..8d0e041b 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -56,6 +56,7 @@ import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/app_theme.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_calendar_model.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart' show DateRangeSelectorRangeViewModel;
+import 'package:live_activities/live_activities.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
@@ -121,6 +122,7 @@ Future callInitializations() async {
}
await AppDependencies.addDependencies();
+ LiveActivities().init(appGroupId: "group.alhabib.patientApp");
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
HttpOverrides.global = MyHttpOverrides();
await callAppStateInitializations();
diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart
index 85f1e972..b292347d 100644
--- a/lib/presentation/home/landing_page.dart
+++ b/lib/presentation/home/landing_page.dart
@@ -27,6 +27,7 @@ import 'package:hmg_patient_app_new/features/hospital/hospital_selection_view_mo
import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/appointment_rating_view_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/patient_queue_live_notification_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.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/features/my_appointments/my_appointments_view_model.dart';
@@ -316,6 +317,28 @@ class _LandingPageState extends State {
padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0),
height: 40.h,
),
+ ElevatedButton(onPressed: (){
+ QueueLiveNotificationModel queueLiveNotificationModel = QueueLiveNotificationModel();
+
+ queueLiveNotificationModel.data = {
+ "msgID": "123",
+ "notfID": "123",
+ "isLiveActivity":"true",
+ "notification_foreground": "true",
+ "patientID": "12345",
+ "patientName": "John Doe",
+ "queueNo": "A-104",
+ "callType": "1",
+ "servingQueueNo": "",
+ "servingCallType": "",
+ "roomNo": "204",
+ "calledOn": "2024-05-21T14:30:00Z",
+ "servingNow": "true"
+ };
+
+ Utils.addLiveNotification(queueLiveNotificationModel, isBackgroundMessage: false);
+
+ }, child: Text("press")).paddingOnly(top: 56.h),
Consumer(builder: (context, todoSectionVM, child) {
return Row(
mainAxisSize: MainAxisSize.min,
diff --git a/lib/presentation/onboarding/onboarding_screen.dart b/lib/presentation/onboarding/onboarding_screen.dart
index 0af63b40..3cc1747e 100644
--- a/lib/presentation/onboarding/onboarding_screen.dart
+++ b/lib/presentation/onboarding/onboarding_screen.dart
@@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/core/utils/size_utils.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/extensions/widget_extensions.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/patient_queue_live_notification_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
@@ -64,6 +65,28 @@ class _OnboardingScreenState extends State {
child: Column(
spacing: 24.h,
children: [
+ ElevatedButton(onPressed: (){
+ QueueLiveNotificationModel queueLiveNotificationModel = QueueLiveNotificationModel();
+
+ queueLiveNotificationModel.data = {
+ "msgID": "123",
+ "notfID": "123",
+ "isLiveActivity":"true",
+ "notification_foreground": "true",
+ "patientID": "12345",
+ "patientName": "John Doe",
+ "queueNo": "A-109",
+ "callType": "0",
+ "servingQueueNo": "",
+ "servingCallType": "",
+ "roomNo": "204",
+ "calledOn": "2024-05-21T14:30:00Z",
+ "servingNow": "true"
+ };
+
+ Utils.addLiveNotification(queueLiveNotificationModel, isBackgroundMessage: false);
+
+ }, child: Text("press")).paddingOnly(top: 56.h),
PageView(
controller: pageController,
children: [
diff --git a/lib/services/notification_service.dart b/lib/services/notification_service.dart
index fd154c61..e978f29f 100644
--- a/lib/services/notification_service.dart
+++ b/lib/services/notification_service.dart
@@ -5,6 +5,10 @@ import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz show TZDateTime, local, setLocalLocation, getLocation;
+///it will be used to not call init every time it has the live activity notification channel created
+///will stop the calling reduntant code again and again
+bool isNotificationChannelCreatedForLiveActivity = false;
+
/// Abstract class defining the notification service interface
abstract class NotificationService {
/// Initialize the notification service
diff --git a/lib/splashPage.dart b/lib/splashPage.dart
index dc49428a..881f9895 100644
--- a/lib/splashPage.dart
+++ b/lib/splashPage.dart
@@ -16,6 +16,7 @@ import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/patient_queue_live_notification_model.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/presentation/onboarding/onboarding_screen.dart';
import 'package:hmg_patient_app_new/presentation/onboarding/splash_animation_screen.dart';
diff --git a/pubspec.lock b/pubspec.lock
index 4f2c35ac..e4df9f82 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -117,10 +117,10 @@ packages:
dependency: transitive
description:
name: characters
- sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
+ sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
url: "https://pub.dev"
source: hosted
- version: "1.4.0"
+ version: "1.4.1"
chewie:
dependency: transitive
description:
@@ -145,6 +145,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.2"
+ cloudflare_turnstile:
+ dependency: "direct main"
+ description:
+ name: cloudflare_turnstile
+ sha256: f04191fd1f9c658e98c11175356f34aaeca42b4ed91ee66d42fb250b3346160d
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.8.0"
collection:
dependency: transitive
description:
@@ -499,6 +507,22 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ flutter_amazonpaymentservices:
+ dependency: "direct main"
+ description:
+ name: flutter_amazonpaymentservices
+ sha256: "23f45fd3b1e12a0933da3704d66cebd19c4c41e28a50d4fd458d3e3e6311f332"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.13"
+ flutter_app_group_directory:
+ dependency: transitive
+ description:
+ name: flutter_app_group_directory
+ sha256: "680ef9b2dee84c237cd7bb7fc78bc45867b32556a8a5f0de61278078b9fefd05"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
flutter_cache_manager:
dependency: transitive
description:
@@ -720,6 +744,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.1"
+ flutter_screenshot_blocker:
+ dependency: "direct main"
+ description:
+ name: flutter_screenshot_blocker
+ sha256: "20e36b4aaca20259008dbb1403b77af6207d48cd8382a772b9c27619bc116849"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.4"
flutter_staggered_animations:
dependency: "direct main"
description:
@@ -773,10 +805,10 @@ packages:
dependency: "direct main"
description:
name: flutter_zoom_videosdk
- sha256: "46a4dea664b1c969099328a499c198a1755adf9ac333dea28bea5187910b3bf9"
+ sha256: "8f6dba6b5c910097aca7f3c582a11b10a6fb5def49fead745d837283b5f5ef52"
url: "https://pub.dev"
source: hosted
- version: "2.1.10"
+ version: "2.4.0"
fluttertoast:
dependency: "direct main"
description:
@@ -1233,6 +1265,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.1.1"
+ live_activities:
+ dependency: "direct main"
+ description:
+ name: live_activities
+ sha256: "060f4d8f57b399e5c8beb255fa8426b9b4789320414ae68c8510aec113269dbd"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.9"
local_auth:
dependency: "direct main"
description:
@@ -1341,18 +1381,18 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
+ sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
url: "https://pub.dev"
source: hosted
- version: "0.12.17"
+ version: "0.12.19"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+ sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
url: "https://pub.dev"
source: hosted
- version: "0.11.1"
+ version: "0.13.0"
meta:
dependency: transitive
description:
@@ -1641,6 +1681,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
+ screen_brightness:
+ dependency: "direct main"
+ description:
+ name: screen_brightness
+ sha256: "7d4ac84ae26b37c01d6f5db7123a72db7933e1f2a2a8c369a51e08f81b3178d8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ screen_brightness_android:
+ dependency: transitive
+ description:
+ name: screen_brightness_android
+ sha256: "8c69d3ac475e4d625e7fa682a3a51a69ff59abe5b4a9e57f6ec7d830a6c69bd6"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ screen_brightness_ios:
+ dependency: transitive
+ description:
+ name: screen_brightness_ios
+ sha256: f08f70ca1ac3e30719764b5cfb8b3fe1e28163065018a41b3e6f243ab146c2f1
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ screen_brightness_macos:
+ dependency: transitive
+ description:
+ name: screen_brightness_macos
+ sha256: "70c2efa4534e22b927e82693488f127dd4a0f008469fccf4f0eefe9061bbdd6a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ screen_brightness_platform_interface:
+ dependency: transitive
+ description:
+ name: screen_brightness_platform_interface
+ sha256: "9f3ebf7f22d5487e7676fe9ddaf3fc55b6ff8057707cf6dc0121c7dfda346a16"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ screen_brightness_windows:
+ dependency: transitive
+ description:
+ name: screen_brightness_windows
+ sha256: c8e12a91cf6dd912a48bd41fcf749282a51afa17f536c3460d8d05702fb89ffa
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
scrollable_positioned_list:
dependency: "direct main"
description:
@@ -1890,10 +1978,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
+ sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
url: "https://pub.dev"
source: hosted
- version: "0.7.7"
+ version: "0.7.10"
time:
dependency: transitive
description:
@@ -2175,5 +2263,5 @@ packages:
source: hosted
version: "1.2.0"
sdks:
- dart: ">=3.9.0 <4.0.0"
- flutter: ">=3.35.0"
+ dart: ">=3.11.0 <4.0.0"
+ flutter: ">=3.41.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index bdce8130..17e59274 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -63,7 +63,7 @@ dependencies:
geolocator: ^14.0.2
dropdown_search: ^6.0.2
google_maps_flutter: ^2.13.1
- flutter_zoom_videosdk: 2.1.10
+ flutter_zoom_videosdk: 2.4.0
dart_jsonwebtoken: ^3.2.0
dartz: ^0.10.1
equatable: ^2.0.7
@@ -110,6 +110,7 @@ dependencies:
screen_brightness: ^1.0.1
flutter_screenshot_blocker: ^1.0.4
cloudflare_turnstile: ^3.7.2
+ live_activities: ^2.4.2
dev_dependencies:
flutter_test: