From 686f73a98bd516a602045edf3e2cb7f3ddda6248 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Tue, 12 Nov 2024 10:36:52 +0300 Subject: [PATCH 01/10] Upgraded to latest --- android/app/build.gradle | 4 +++ android/build.gradle | 19 +++++++++--- .../gradle/wrapper/gradle-wrapper.properties | 4 +-- android/settings.gradle | 31 ++++++++++++++----- lib/home/app_provider.dart | 29 ++++++++++++++--- lib/main.dart | 4 +-- lib/utils/utils.dart | 4 +-- macos/Flutter/GeneratedPluginRegistrant.swift | 10 +++--- pubspec.yaml | 19 ++++++------ .../flutter/generated_plugin_registrant.cc | 3 ++ windows/flutter/generated_plugins.cmake | 1 + 11 files changed, 91 insertions(+), 37 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index fa40e32..bcce007 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -27,6 +27,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { + namespace = "com.example.queuing_system" compileSdkVersion flutter.compileSdkVersion compileOptions { @@ -51,6 +52,7 @@ android { targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName + multiDexEnabled true } buildTypes { @@ -68,4 +70,6 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2' + } diff --git a/android/build.gradle b/android/build.gradle index a1ce039..2f92b4e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -6,26 +6,35 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.2.0' + classpath 'com.android.tools.build:gradle:8.7.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } - allprojects { repositories { google() mavenCentral() } + subprojects { + afterEvaluate { project -> + if (project.hasProperty('android')) { + project.android { + if (namespace == null) { + namespace project.group + } + } + } + } + } + } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { project.evaluationDependsOn(':app') } tasks.register("clean", Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index c021028..e464997 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 23 08:50:38 CEST 2017 +#Tue Nov 12 09:01:21 AST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index 44e62bc..f86bddf 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,11 +1,26 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version '8.7.0' apply false + id "org.jetbrains.kotlin.android" version "1.8.22" apply false + +} + +include ":app" \ No newline at end of file diff --git a/lib/home/app_provider.dart b/lib/home/app_provider.dart index b8c6e51..dcd634c 100644 --- a/lib/home/app_provider.dart +++ b/lib/home/app_provider.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:developer'; import 'dart:io'; -import 'package:connectivity/connectivity.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_tts/flutter_tts.dart'; import 'package:intl/intl.dart'; @@ -198,7 +198,9 @@ class AppProvider extends ChangeNotifier { Future getPrayerDetailsFromServer() async { PrayersWidgetModel? prayersWidgetModel = await API.getPrayerDetailsFromServer( - latitude: currentWidgetsConfigModel!.projectLatitude ?? 0, longitude: currentWidgetsConfigModel!.projectLongitude ?? 0, onFailure: (error) => logger.i("Api call failed with this error: ${error.toString()}")); + latitude: currentWidgetsConfigModel!.projectLatitude ?? 0, + longitude: currentWidgetsConfigModel!.projectLongitude ?? 0, + onFailure: (error) => logger.i("Api call failed with this error: ${error.toString()}")); if (prayersWidgetModel != null) { currentPrayersWidgetModel = prayersWidgetModel; @@ -494,7 +496,13 @@ class AppProvider extends ChangeNotifier { onDisconnect(exception) { logger.i("SignalR: onDisconnect"); - signalRHelper.startSignalRConnection(currentDeviceIp, onUpdateAvailable: onPingReceived, onConnect: onConnect, onConnecting: onConnecting, onDisconnect: onDisconnect,); + signalRHelper.startSignalRConnection( + currentDeviceIp, + onUpdateAvailable: onPingReceived, + onConnect: onConnect, + onConnecting: onConnecting, + onDisconnect: onDisconnect, + ); } onConnecting() { @@ -502,9 +510,10 @@ class AppProvider extends ChangeNotifier { } listenNetworkConnectivity() async { - Connectivity().onConnectivityChanged.listen((event) async { - switch (event) { + Connectivity().onConnectivityChanged.listen((List event) async { + switch (event.first) { case ConnectivityResult.wifi: + case ConnectivityResult.ethernet: updateInternetConnection(true); await getCurrentIP(); if (signalRHelper.connection != null) { @@ -517,6 +526,16 @@ class AppProvider extends ChangeNotifier { break; case ConnectivityResult.mobile: break; + case ConnectivityResult.bluetooth: + // TODO: Handle this case. + break; + // TODO: Handle this case. + case ConnectivityResult.vpn: + // TODO: Handle this case. + break; + case ConnectivityResult.other: + // TODO: Handle this case. + break; } }); } diff --git a/lib/main.dart b/lib/main.dart index f24b04b..8623150 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,7 +7,7 @@ import 'package:logger/logger.dart'; import 'package:provider/provider.dart'; import 'package:queuing_system/core/api.dart'; import 'package:queuing_system/home/app_provider.dart'; -import 'package:wakelock/wakelock.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; import 'core/config/size_config.dart'; import 'home/home_screen.dart'; @@ -23,7 +23,7 @@ void main() { //TODO: WE HAVE TO UPDATE THIS BEFORE GOING LIVE. HttpOverrides.global = MyHttpOverrides(); WidgetsFlutterBinding.ensureInitialized(); - Wakelock.enable(); + WakelockPlus.enable(); runApp(const MyApp()); } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 11ed84f..1ee4a21 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -1,4 +1,4 @@ -import 'package:connectivity/connectivity.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:queuing_system/core/config/size_config.dart'; class Utils { @@ -16,7 +16,7 @@ class Utils { } static Future checkConnection() async { - ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); + List connectivityResult = await (Connectivity().checkConnectivity()); if ((connectivityResult == ConnectivityResult.mobile) || (connectivityResult == ConnectivityResult.wifi)) { return true; } else { diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index fda5d83..dbf44b3 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,19 +6,21 @@ import FlutterMacOS import Foundation import audio_session -import connectivity_macos +import connectivity_plus import flutter_tts import just_audio +import package_info_plus import path_provider_foundation import shared_preferences_foundation -import wakelock_macos +import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) - ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) - WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) } diff --git a/pubspec.yaml b/pubspec.yaml index 385f42a..6f783bf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -33,22 +33,23 @@ dependencies: # Base packages provider: ^6.0.1 - get_it: ^7.1.3 - connectivity: ^3.0.6 + get_it: ^8.0.2 + connectivity_plus: ^6.1.0 # flutter_gifimage: ^1.0.1 - flutter_svg: ^1.0.3 - http: ^0.13.0 + flutter_svg: ^2.0.14 + http: ^1.2.2 blinking_text: ^1.0.2 - just_audio: 0.9.31 - flutter_tts: 3.6.3 + just_audio: ^0.9.42 + flutter_tts: ^4.1.0 # flutter_tts: ^4.0.2 - wakelock: ^0.6.2 + wakelock_plus: ^1.2.8 shared_preferences: ^2.2.1 #signalr core signalr_core: ^1.1.1 - intl: ^0.18.1 + intl: ^0.19.0 marquee: ^2.2.3 logger: ^2.4.0 + win32: ^5.8.0 @@ -61,7 +62,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^1.0.0 + flutter_lints: ^5.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 63d4407..661b0ef 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,9 +6,12 @@ #include "generated_plugin_registrant.h" +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); FlutterTtsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterTtsPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 26bfe68..7363fb2 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + connectivity_plus flutter_tts ) From ca664cda0f3228b314540396c85d50199cdfc2ea Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Sun, 15 Dec 2024 15:04:11 +0300 Subject: [PATCH 02/10] Added connection checks --- lib/core/base/base_app_client.dart | 3 +++ lib/home/app_provider.dart | 9 ++++++--- lib/utils/utils.dart | 15 ++++++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/core/base/base_app_client.dart b/lib/core/base/base_app_client.dart index b14ee46..9529f52 100644 --- a/lib/core/base/base_app_client.dart +++ b/lib/core/base/base_app_client.dart @@ -20,7 +20,10 @@ class BaseAppClient { 'Content-Type': 'application/json', 'Accept': 'application/json', }); + final int statusCode = response.statusCode; + logger.i("statusCode : $statusCode"); + if (statusCode < 200 || statusCode >= 400) { if (onFailure != null) { onFailure(Utils.generateContactAdminMsg(), statusCode); diff --git a/lib/home/app_provider.dart b/lib/home/app_provider.dart index dcd634c..6caf9e4 100644 --- a/lib/home/app_provider.dart +++ b/lib/home/app_provider.dart @@ -226,13 +226,13 @@ class AppProvider extends ChangeNotifier { // if (currentWidgetsConfigModel == null) return; await getInfoWidgetsConfigurationsFromServer().whenComplete(() async { - if (currentWidgetsConfigModel!.isWeatherReq!) { + if (currentWidgetsConfigModel!.isWeatherReq != null && currentWidgetsConfigModel!.isWeatherReq!) { await getWeatherDetailsFromServer(); } - if (currentWidgetsConfigModel!.isPrayerTimeReq!) { + if (currentWidgetsConfigModel!.isPrayerTimeReq != null && currentWidgetsConfigModel!.isPrayerTimeReq!) { await getPrayerDetailsFromServer(); } - if (currentWidgetsConfigModel!.isRssFeedReq!) { + if (currentWidgetsConfigModel!.isRssFeedReq != null && currentWidgetsConfigModel!.isRssFeedReq!) { await getRssFeedDetailsFromServer(); } }); @@ -245,6 +245,9 @@ class AppProvider extends ChangeNotifier { Future getTheWidgetsConfigurationsEveryMidnight() async { if (currentWidgetsConfigModel == null) return; + if (!(currentWidgetsConfigModel!.isWeatherReq ?? false) && !(currentWidgetsConfigModel!.isPrayerTimeReq ?? false) && !(currentWidgetsConfigModel!.isRssFeedReq ?? false)) { + return; + } if (!currentWidgetsConfigModel!.isWeatherReq! && !currentWidgetsConfigModel!.isPrayerTimeReq! && !currentWidgetsConfigModel!.isRssFeedReq!) { return; } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 1ee4a21..f431d71 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -1,5 +1,6 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:queuing_system/core/config/size_config.dart'; +import 'package:queuing_system/main.dart'; class Utils { static getHeight() { @@ -17,11 +18,19 @@ class Utils { static Future checkConnection() async { List connectivityResult = await (Connectivity().checkConnectivity()); - if ((connectivityResult == ConnectivityResult.mobile) || (connectivityResult == ConnectivityResult.wifi)) { + int indexEthernet = connectivityResult.indexWhere((element) => element == ConnectivityResult.ethernet); + + if (indexEthernet != -1) { + return true; + } + + int indexWifi = connectivityResult.indexWhere((element) => element == ConnectivityResult.wifi); + + if (indexWifi != -1) { return true; - } else { - return false; } + + return false; } // static TextStyle textStyle(context) => TextStyle(color: Theme.of(context).primaryColor); // From 366541f20f778285e840e0d42fddb20dccdf3bf1 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Thu, 9 Jan 2025 10:26:45 +0300 Subject: [PATCH 03/10] Added connection checks --- lib/core/api.dart | 17 +++++++---------- lib/home/app_provider.dart | 16 +++++++++++++++- pubspec.yaml | 6 +++--- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/lib/core/api.dart b/lib/core/api.dart index 6c54639..ee14684 100644 --- a/lib/core/api.dart +++ b/lib/core/api.dart @@ -27,16 +27,14 @@ class MyHttpOverrides extends HttpOverrides { class API { static getCallRequestInfoByClinicInfo(String deviceIp, - {required Function(List, List, CallConfig callConfig) onSuccess, - required Function(dynamic) onFailure}) async { + {required Function(List, List, CallConfig callConfig) onSuccess, required Function(dynamic) onFailure}) async { final body = {"ipAdress": deviceIp, "apiKey": apiKey}; bool isDevMode = false; if (isDevMode) { final Map response = testPatientsData["data"] as Map; CallConfig callConfig = CallConfig.fromJson(response["callConfig"]); - var callPatients = - (response["callPatients"] as List).map((j) => PatientTicketModel.fromJson(j)).toList().where((element) => element.callType != 0).toList(); + var callPatients = (response["callPatients"] as List).map((j) => PatientTicketModel.fromJson(j)).toList().where((element) => element.callType != 0).toList(); var isQueuePatients = callPatients.where((element) => (element.isQueue == false && element.callType != 0)).toList(); log("callPatients: ${callPatients.toString()}"); log("isQueuePatients: ${isQueuePatients.toString()}"); @@ -50,11 +48,7 @@ class API { final response = apiResp["data"]; CallConfig callConfig = CallConfig.fromJson(response["callConfig"]); - var callPatients = (response["callPatients"] as List) - .map((j) => PatientTicketModel.fromJson(j)) - .toList() - .where((element) => element.callType != 0) - .toList(); + var callPatients = (response["callPatients"] as List).map((j) => PatientTicketModel.fromJson(j)).toList().where((element) => element.callType != 0).toList(); var isQueuePatients = callPatients.where((element) => (element.isQueue == false && element.callType != 0)).toList(); callPatients.sort((a, b) => a.editedOnTimeStamp.compareTo(b.editedOnTimeStamp)); @@ -108,7 +102,10 @@ class API { body: body, onSuccess: (response, status) { if (status == 200 && response["data"] != null) { - widgetsConfigModel = (response["data"] as List).map((e) => WidgetsConfigModel.fromJson(e)).toList().first; + List list = (response["data"] as List).map((e) => WidgetsConfigModel.fromJson(e)).toList(); + if (list.isNotEmpty) { + widgetsConfigModel = list.first; + } } }, onFailure: (error, status) => log("error: ${error.toString()}")); diff --git a/lib/home/app_provider.dart b/lib/home/app_provider.dart index 6caf9e4..1581fe4 100644 --- a/lib/home/app_provider.dart +++ b/lib/home/app_provider.dart @@ -25,7 +25,18 @@ bool isVoiceActualCompletedGlobally = false; class AppProvider extends ChangeNotifier { AppProvider() { - callInitializations(); + waitForIPAndCallInitializations(); + } + + Future waitForIPAndCallInitializations() async { + while (currentDeviceIp == "") { + await getCurrentIP(); + if (currentDeviceIp != "") { + callInitializations(); + } else { + await Future.delayed(const Duration(seconds: 2)); + } + } } Future callInitializations() async { @@ -226,6 +237,9 @@ class AppProvider extends ChangeNotifier { // if (currentWidgetsConfigModel == null) return; await getInfoWidgetsConfigurationsFromServer().whenComplete(() async { + if (currentWidgetsConfigModel == null) { + return; + } if (currentWidgetsConfigModel!.isWeatherReq != null && currentWidgetsConfigModel!.isWeatherReq!) { await getWeatherDetailsFromServer(); } diff --git a/pubspec.yaml b/pubspec.yaml index 6f783bf..f09c4e5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,15 +35,15 @@ dependencies: provider: ^6.0.1 get_it: ^8.0.2 connectivity_plus: ^6.1.0 -# flutter_gifimage: ^1.0.1 + # flutter_gifimage: ^1.0.1 flutter_svg: ^2.0.14 http: ^1.2.2 blinking_text: ^1.0.2 just_audio: ^0.9.42 flutter_tts: ^4.1.0 -# flutter_tts: ^4.0.2 + # flutter_tts: ^4.0.2 wakelock_plus: ^1.2.8 - shared_preferences: ^2.2.1 + shared_preferences: ^2.3.5 #signalr core signalr_core: ^1.1.1 intl: ^0.19.0 From 49d69ab809d9b660d80ee82bea744f75f03a0e57 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Mon, 13 Jan 2025 16:05:54 +0300 Subject: [PATCH 04/10] Added Longpooling temporary as a transport type. Need to update that to websockets --- lib/core/config/config.dart | 5 ++--- lib/home/app_provider.dart | 3 ++- lib/main.dart | 8 ++------ lib/utils/signalR_utils.dart | 6 ++++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/core/config/config.dart b/lib/core/config/config.dart index aca4a27..89bf1b2 100644 --- a/lib/core/config/config.dart +++ b/lib/core/config/config.dart @@ -4,9 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://ms.hmg.com/nscapi'; // UAT -// const BASE_URL = 'https://qline.hmg.com'; // LIVE +// const BASE_URL = 'https://ms.hmg.com/nscapi'; // UAT +const BASE_URL = 'https://qline.hmg.com'; // LIVE const apiKey = 'EE17D21C7943485D9780223CCE55DCE5'; // UAT // const BASE_URL = 'http://10.200.204.11:2222/Services/Nurses.svc/REST'; // const BASE_URL = 'https://hmgwebservices.com/'; diff --git a/lib/home/app_provider.dart b/lib/home/app_provider.dart index 1581fe4..9da8e25 100644 --- a/lib/home/app_provider.dart +++ b/lib/home/app_provider.dart @@ -32,7 +32,7 @@ class AppProvider extends ChangeNotifier { while (currentDeviceIp == "") { await getCurrentIP(); if (currentDeviceIp != "") { - callInitializations(); + await callInitializations(); } else { await Future.delayed(const Duration(seconds: 2)); } @@ -145,6 +145,7 @@ class AppProvider extends ChangeNotifier { WidgetsConfigModel? currentWidgetsConfigModel; Future getInfoWidgetsConfigurationsFromServer() async { + log(" errorHellpo:"); WidgetsConfigModel? widgetsConfigModel = await API.getWidgetConfigsFromServer(currentDeviceIp, onFailure: (error) { logger.i("Api call failed with this error: ${error.toString()}"); }); diff --git a/lib/main.dart b/lib/main.dart index 8623150..d4d7486 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -41,12 +41,8 @@ class MyApp extends StatelessWidget { builder: (context, constraints) { return OrientationBuilder(builder: (context, orientation) { SizeConfig().init(constraints, orientation); - SystemChrome.setPreferredOrientations([ - DeviceOrientation.portraitUp, - // DeviceOrientation.portraitDown, - // DeviceOrientation.landscapeLeft, - // DeviceOrientation.landscapeRight, - ]); + SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]); + SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); return MultiProvider( providers: [ diff --git a/lib/utils/signalR_utils.dart b/lib/utils/signalR_utils.dart index 3ebd26e..cc2f82c 100644 --- a/lib/utils/signalR_utils.dart +++ b/lib/utils/signalR_utils.dart @@ -34,14 +34,16 @@ class SignalRHelper { required VoidCallback onConnecting, }) async { logger.i("Connecting Signal R with: $deviceIp"); - final url = hubBaseURL + "?IPAddress=$deviceIp"; + final url = "$hubBaseURL?IPAddress=$deviceIp"; // final url = hubBaseURL; connection = HubConnectionBuilder() .withUrl( url, HttpConnectionOptions( client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), - // transport: HttpTransportType.webSockets, + + //TODO: IT MUST BE WEB SOCKETS + transport: HttpTransportType.longPolling, logging: (level, message) => log(message), )) .withAutomaticReconnect() From 6f4bf07e9cb805b8cda9b7ba66caedebc2c491b8 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Thu, 8 May 2025 16:53:03 +0300 Subject: [PATCH 05/10] tested QueuingSystem 5thApril --- lib/core/config/config.dart | 3 +- lib/header/app_header.dart | 2 +- lib/home/app_provider.dart | 2 +- lib/home/priority_calls_components.dart | 42 ++++++++++++++----------- lib/main.dart | 3 +- lib/utils/call_by_voice.dart | 6 ++-- lib/utils/signalR_utils.dart | 2 +- 7 files changed, 33 insertions(+), 27 deletions(-) diff --git a/lib/core/config/config.dart b/lib/core/config/config.dart index 89bf1b2..d952eae 100644 --- a/lib/core/config/config.dart +++ b/lib/core/config/config.dart @@ -5,7 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; // const BASE_URL = 'https://ms.hmg.com/nscapi'; // UAT -const BASE_URL = 'https://qline.hmg.com'; // LIVE +const BASE_URL = 'https://ms.hmg.com/nscapi2'; // UAT 2 Development DB +// const BASE_URL = 'https://qline.hmg.com'; // LIVE const apiKey = 'EE17D21C7943485D9780223CCE55DCE5'; // UAT // const BASE_URL = 'http://10.200.204.11:2222/Services/Nurses.svc/REST'; // const BASE_URL = 'https://hmgwebservices.com/'; diff --git a/lib/header/app_header.dart b/lib/header/app_header.dart index 884aee1..5fde76a 100644 --- a/lib/header/app_header.dart +++ b/lib/header/app_header.dart @@ -74,7 +74,7 @@ class AppHeader extends StatelessWidget implements PreferredSizeWidget { return Consumer( builder: (BuildContext context, AppProvider appProvider, Widget? child) { return Container( - height: 100, + height: 115, padding: const EdgeInsets.only(left: 20, right: 20), decoration: BoxDecoration(color: AppGlobal.vitalSignColor), child: Directionality( diff --git a/lib/home/app_provider.dart b/lib/home/app_provider.dart index 9da8e25..eeb3de8 100644 --- a/lib/home/app_provider.dart +++ b/lib/home/app_provider.dart @@ -98,7 +98,7 @@ class AppProvider extends ChangeNotifier { ); } - logger.i("here logger.ig: ${isQueuePatients.length}"); + logger.i("isQueuePatients: ${isQueuePatients.length}"); if (isQueuePatients.isEmpty) { isCallingInProgress = false; diff --git a/lib/home/priority_calls_components.dart b/lib/home/priority_calls_components.dart index f92f3c6..7d7619c 100644 --- a/lib/home/priority_calls_components.dart +++ b/lib/home/priority_calls_components.dart @@ -82,7 +82,7 @@ class TicketItem extends StatelessWidget { String getFormattedTicket(String ticketNo, bool isClinicAdded) { if (isClinicAdded) { var formattedString = ticketNo.split(" "); - return formattedString[0] + " " + formattedString[1]; + return "${formattedString[0]} ${formattedString[1]}"; } return ticketNo; } @@ -94,19 +94,21 @@ class TicketItem extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - BlinkText(getFormattedTicket(ticketNo, isClinicAdded), - style: TextStyle( - fontSize: SizeConfig.getWidthMultiplier() * 10, - letterSpacing: -1, - height: 0.5, - fontWeight: FontWeight.bold, - ), - beginColor: Colors.black, - endColor: blink ? Colors.black.withOpacity(0.1) : Colors.black, - // endColor: blink ? AppGlobal.appRedColor : Colors.black, - times: 0, - duration: const Duration(seconds: 1)), - const SizedBox(height: 13), + BlinkText( + getFormattedTicket(ticketNo, isClinicAdded), + style: TextStyle( + fontSize: SizeConfig.getWidthMultiplier() * 10, + letterSpacing: -1, + height: 0.5, + fontWeight: FontWeight.bold, + ), + beginColor: Colors.black, + endColor: blink ? Colors.black.withOpacity(0.1) : Colors.black, + // endColor: blink ? AppGlobal.appRedColor : Colors.black, + times: 0, + duration: const Duration(seconds: 1), + ), + const SizedBox(height: 25), Directionality( textDirection: callConfig.textDirection, child: Row( @@ -114,8 +116,8 @@ class TicketItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( - padding: EdgeInsets.only(bottom: callType == CallType.vitalSign ? 0 : 8), - child: callType.icon(SizeConfig.getHeightMultiplier() * 3), + padding: EdgeInsets.only(bottom: callType == CallType.vitalSign ? 8 : 8), + child: callType.icon(SizeConfig.getHeightMultiplier() * 2), ), const SizedBox(width: 13), AppText( @@ -160,7 +162,9 @@ Widget noPatientInQueue({required ScreenOrientationEnum screenOrientationEnum}) child: AppText( "Awaiting Patients Arrival", fontFamily: 'Poppins-SemiBold.ttf', - fontSize: (screenOrientationEnum == ScreenOrientationEnum.portraitDown || screenOrientationEnum == ScreenOrientationEnum.portraitUp) ? SizeConfig.getWidthMultiplier() * 9 : SizeConfig.getWidthMultiplier() * 7, + fontSize: (screenOrientationEnum == ScreenOrientationEnum.portraitDown || screenOrientationEnum == ScreenOrientationEnum.portraitUp) + ? SizeConfig.getWidthMultiplier() * 9 + : SizeConfig.getWidthMultiplier() * 7, ), ), ], @@ -356,5 +360,7 @@ Widget priorityTicketsWithSideList({required List tickets, r ), ) ]; - return (appProvider.currentScreenRotation == ScreenOrientationEnum.portraitUp || appProvider.currentScreenRotation == ScreenOrientationEnum.portraitDown) ? Row(children: children) : Column(children: children); + return (appProvider.currentScreenRotation == ScreenOrientationEnum.portraitUp || appProvider.currentScreenRotation == ScreenOrientationEnum.portraitDown) + ? Row(children: children) + : Column(children: children); } diff --git a/lib/main.dart b/lib/main.dart index d4d7486..9c2e947 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -20,7 +20,6 @@ Logger logger = Logger( )); void main() { - //TODO: WE HAVE TO UPDATE THIS BEFORE GOING LIVE. HttpOverrides.global = MyHttpOverrides(); WidgetsFlutterBinding.ensureInitialized(); WakelockPlus.enable(); @@ -50,7 +49,7 @@ class MyApp extends StatelessWidget { ], child: MaterialApp( showSemanticsDebugger: false, - title: 'Doctors App', + title: 'Qline Appointments', theme: ThemeData( primaryColor: Colors.grey, fontFamily: 'Poppins', diff --git a/lib/utils/call_by_voice.dart b/lib/utils/call_by_voice.dart index 2661e33..4a8bfae 100644 --- a/lib/utils/call_by_voice.dart +++ b/lib/utils/call_by_voice.dart @@ -58,7 +58,7 @@ class CallByVoice { flutterTts.setVolume(1.0); isVoiceActualCompletedGlobally = true; await flutterTts.awaitSpeakCompletion(true); - await flutterTts.speak(preVoice + " .. " + clinicName + " .. " + patientAlpha + " .. " + patientNumeric + " .. " + postVoice); + await flutterTts.speak("$preVoice .. $clinicName .. $patientAlpha .. $patientNumeric .. $postVoice"); return; } @@ -69,9 +69,9 @@ class CallByVoice { await flutterTts.awaitSpeakCompletion(true); // await flutterTts.speak(preVoice + " .. " + clinicName + " .. " + patientAlpha + " .. " + patientNumeric + " .. " + postVoice); - await flutterTts.speak(preVoice + " .. "); + await flutterTts.speak("$preVoice .. "); await flutterTts.setLanguage("en"); - await flutterTts.speak(clinicName + " .. " + patientAlpha + " .. " + patientNumeric + " .. "); + await flutterTts.speak("$clinicName .. $patientAlpha .. $patientNumeric .. "); await flutterTts.setLanguage(lang); isVoiceActualCompletedGlobally = true; await flutterTts.speak(postVoice); diff --git a/lib/utils/signalR_utils.dart b/lib/utils/signalR_utils.dart index cc2f82c..64586a5 100644 --- a/lib/utils/signalR_utils.dart +++ b/lib/utils/signalR_utils.dart @@ -43,7 +43,7 @@ class SignalRHelper { client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), //TODO: IT MUST BE WEB SOCKETS - transport: HttpTransportType.longPolling, + transport: HttpTransportType.webSockets, logging: (level, message) => log(message), )) .withAutomaticReconnect() From a0b625f0b996fa38b79904768920aca8bd1db529 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Thu, 19 Jun 2025 09:17:25 +0300 Subject: [PATCH 06/10] Refactor --- lib/core/config/config.dart | 4 ++-- lib/home/priority_calls_components.dart | 4 ++-- lib/utils/signalR_utils.dart | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/core/config/config.dart b/lib/core/config/config.dart index d952eae..3790482 100644 --- a/lib/core/config/config.dart +++ b/lib/core/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -// const BASE_URL = 'https://ms.hmg.com/nscapi'; // UAT -const BASE_URL = 'https://ms.hmg.com/nscapi2'; // UAT 2 Development DB +const BASE_URL = 'https://ms.hmg.com/nscapi'; // UAT +// const BASE_URL = 'https://ms.hmg.com/nscapi2'; // UAT 2 Development DB // const BASE_URL = 'https://qline.hmg.com'; // LIVE const apiKey = 'EE17D21C7943485D9780223CCE55DCE5'; // UAT // const BASE_URL = 'http://10.200.204.11:2222/Services/Nurses.svc/REST'; diff --git a/lib/home/priority_calls_components.dart b/lib/home/priority_calls_components.dart index 7d7619c..4125b5d 100644 --- a/lib/home/priority_calls_components.dart +++ b/lib/home/priority_calls_components.dart @@ -26,7 +26,7 @@ class PriorityTickets extends StatelessWidget { children: [ const SizedBox(height: 50), TicketItem( - ticketNo: firstTicket.queueNo ?? '', + ticketNo: firstTicket.queueNo, callType: firstTicket.getCallType(), scale: 1.2, blink: true, @@ -43,7 +43,7 @@ class PriorityTickets extends StatelessWidget { .map((ticket) => Padding( padding: EdgeInsets.only(top: SizeConfig.getHeightMultiplier() * 2), child: TicketItem( - ticketNo: ticket.queueNo ?? '', + ticketNo: ticket.queueNo, callType: ticket.getCallType(), scale: 0.8, roomNo: ticket.roomNo, diff --git a/lib/utils/signalR_utils.dart b/lib/utils/signalR_utils.dart index 64586a5..be1436f 100644 --- a/lib/utils/signalR_utils.dart +++ b/lib/utils/signalR_utils.dart @@ -78,6 +78,7 @@ class SignalRHelper { } } + // startConnection(BuildContext context) async { // if (connection!.state == HubConnectionState.connected || connection!.state == HubConnectionState.connecting) { // connection!.off('addChatMessage'); From 0a87036fcd40b013efc701d5fe1ecae7f1381da4 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Thu, 26 Jun 2025 10:55:29 +0300 Subject: [PATCH 07/10] icon size updated --- lib/core/base/base_app_client.dart | 10 +++++----- lib/core/config/config.dart | 2 +- lib/core/response_models/widgets_config_model.dart | 2 ++ lib/home/priority_calls_components.dart | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/core/base/base_app_client.dart b/lib/core/base/base_app_client.dart index 9529f52..02c2337 100644 --- a/lib/core/base/base_app_client.dart +++ b/lib/core/base/base_app_client.dart @@ -10,7 +10,7 @@ class BaseAppClient { static post(String endPoint, {Map? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure}) async { String url; - url = "$BASE_URL/api/PatientCall" + endPoint; + url = "$BASE_URL/api/PatientCall$endPoint"; // try { logger.i("URL : $url"); @@ -29,7 +29,7 @@ class BaseAppClient { onFailure(Utils.generateContactAdminMsg(), statusCode); } } else { - logger.i("Response: ${response.body.toString()}"); + log("Response: ${response.body.toString()}"); var parsed = json.decode(response.body.toString()); if (onSuccess != null) { onSuccess(parsed, statusCode); @@ -50,7 +50,7 @@ class BaseAppClient { static get(String endPoint, {Map? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure}) async { String url; - url = "$BASE_URL/api/PatientCall" + endPoint; + url = "$BASE_URL/api/PatientCall$endPoint"; try { // String token = await sharedPref.getString(TOKEN); @@ -86,11 +86,11 @@ class BaseAppClient { //TODO change this fun String error = parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']; if (parsed["ValidationErrors"] != null) { - error = parsed["ValidationErrors"]["StatusMessage"].toString() + "\n"; + error = "${parsed["ValidationErrors"]["StatusMessage"]}\n"; if (parsed["ValidationErrors"]["ValidationErrors"] != null && parsed["ValidationErrors"]["ValidationErrors"].length != 0) { for (var i = 0; i < parsed["ValidationErrors"]["ValidationErrors"].length; i++) { - error = error + parsed["ValidationErrors"]["ValidationErrors"][i]["Messages"][0] + "\n"; + error = "${error + parsed["ValidationErrors"]["ValidationErrors"][i]["Messages"][0]}\n"; } } } diff --git a/lib/core/config/config.dart b/lib/core/config/config.dart index 3790482..f7597d6 100644 --- a/lib/core/config/config.dart +++ b/lib/core/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; +// const BASE_URL = 'https://ms.hmg.com/nscapi2'; // Development DB const BASE_URL = 'https://ms.hmg.com/nscapi'; // UAT -// const BASE_URL = 'https://ms.hmg.com/nscapi2'; // UAT 2 Development DB // const BASE_URL = 'https://qline.hmg.com'; // LIVE const apiKey = 'EE17D21C7943485D9780223CCE55DCE5'; // UAT // const BASE_URL = 'http://10.200.204.11:2222/Services/Nurses.svc/REST'; diff --git a/lib/core/response_models/widgets_config_model.dart b/lib/core/response_models/widgets_config_model.dart index ef93c27..30e0f73 100644 --- a/lib/core/response_models/widgets_config_model.dart +++ b/lib/core/response_models/widgets_config_model.dart @@ -9,6 +9,8 @@ class WidgetsConfigModel { double? projectLongitude; int? cityKey; + + WidgetsConfigModel({ this.waitingAreaID, this.waitingAreaName, diff --git a/lib/home/priority_calls_components.dart b/lib/home/priority_calls_components.dart index 4125b5d..bd7fe60 100644 --- a/lib/home/priority_calls_components.dart +++ b/lib/home/priority_calls_components.dart @@ -190,7 +190,7 @@ Widget priorityTicketsWithSideList({required List tickets, r log("appProvider.currentScreenRotation: ${appProvider.currentScreenRotation}"); final List children = [ - Expanded(flex: 7, child: PriorityTickets(callConfig: callConfig, tickets: priorityTickets)), + Expanded(flex: 8, child: PriorityTickets(callConfig: callConfig, tickets: priorityTickets)), Container(color: Colors.grey.withOpacity(0.1), width: 10, margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 50)), Expanded( flex: 6, @@ -311,7 +311,7 @@ Widget priorityTicketsWithSideList({required List tickets, r Padding( padding: const EdgeInsets.only(bottom: 10), child: SizedBox( - width: SizeConfig.getWidthMultiplier() * 3.5, + width: SizeConfig.getWidthMultiplier() * 2.5, child: itm.getCallType().icon(SizeConfig.getHeightMultiplier() * 2.5), ), ), From b39ec7eb17acd549d88c5e9e75417ca6a15ccde4 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Mon, 30 Jun 2025 18:33:08 +0300 Subject: [PATCH 08/10] updated URL --- lib/core/config/config.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/config/config.dart b/lib/core/config/config.dart index f7597d6..6cba86c 100644 --- a/lib/core/config/config.dart +++ b/lib/core/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; // const BASE_URL = 'https://ms.hmg.com/nscapi2'; // Development DB -const BASE_URL = 'https://ms.hmg.com/nscapi'; // UAT -// const BASE_URL = 'https://qline.hmg.com'; // LIVE +// const BASE_URL = 'https://ms.hmg.com/nscapi'; // UAT +const BASE_URL = 'https://qline.hmg.com'; // LIVE const apiKey = 'EE17D21C7943485D9780223CCE55DCE5'; // UAT // const BASE_URL = 'http://10.200.204.11:2222/Services/Nurses.svc/REST'; // const BASE_URL = 'https://hmgwebservices.com/'; From 95a92e6ccdb37567378b94a55ff9358758faac8d Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Mon, 30 Jun 2025 18:46:43 +0300 Subject: [PATCH 09/10] Added Icon and Name --- android/app/src/main/AndroidManifest.xml | 2 +- .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 2916 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 2016 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 3949 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 6584 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 8594 bytes lib/footer/app_footer.dart | 2 +- 7 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 5a6de5c..aa876a1 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -14,7 +14,7 @@ + android:label="HMG Qline"> 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 AQ2+n{ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..720700d2875658551a02bc3ca88b677eb2ff36d8 100644 GIT binary patch delta 2013 zcmV<32O{{o1KfpSs73S}UJwdQP6Qe8cDErcG*LiPA7LWiV zD}_RUX;v@@Q`VH}O!XWifcZQiG&C)L2Ki6FKz8jquz%JTz@RcS@OT3tw+Rky^f^F7 zzyeV%#>fPM!#s2t#_l~};l^^{j6r6z;PGaNv(L0nP-#sG@R13GZoe4~7oLyg9rKWT z_dT$9vkw4--Y~!-VZ?X54}M&m?}{W-eMru^2l@9u0*gflHnT0t+FB7?zZ%*(XZc=} zyqTP}5P!K%+iCz%Fuu>gfc&!yjgKrw zItU6w^1P-YIdlFH0erI6KLAQza^8VX=$B6hvRUhpDjWr5w~pxQ7ZIFt zUH`j5-9R8X{|^ChW&s#K$s53$We85a-U_Y3Jbysw900f9jojw#LkOW-J#Y+wE2xfn z;8+N`s?bo9m@%sg)!N9=7()D$Ef6P+P&5JD)d$>shRP@<@%~?{m(d$0dRL)RwrM2; z<$w@K-ZBTd?H__Q`{~5=q2Q1`M-f}M3W2M}S1#9zVieI`#$X;k0{xN+iZ)OUcbbvx z>VHP;%~ue(_KI=!&zzMEQPpGwZo&7IGW6g0;l04YOIW5yR24V>|e;<2*aN+0|`R4@b-r@ynxc$qHmv zuC}R3IZ3R{Mu~i7vS7ggSW~2gVUl$lE`J$^=*lG)aZ|+1=I)Ha*t;L8N1uSH>tKvS z777U8HxGepF7IznR)|<(mwIvuGB2$G3x+I1sVESTxg5xIEF7-LimTFT6$0emehO=c zizZ+m`U6cXpGV`Y+x&Od;*hh$rttkP=;J3ULxGY0u-U!(Uv6oDO7xuUR!tA|$A5@B zVQp>`oG~5Ij;G22(B{R5rG@DCVu57SiOkx!(YxRQPp+@__e$oPG(?v@ z>)!*#>pB2ldkeh_s{k0}EdD&;UZmIqFFx(BEV{i|?1A}T|Z1A6D)2NF9BT%yE@bOR)4k+ky0oRbYXjRewfRKVeoG z)q5;;SHTmN8(FFk+67|~UH%;SFqbZt(gNk-ZfO|Mubc|w+wZ`dV`^jS1K>h6GI9E; z{q?`ZA$n3ZF4a#AOHPs((;Y7%vvQ3xqZrkSifS5HP>;tkfVuTS&HDa$^NPq?L`*X1d=o7A-AcPv5GU5s7Vjl0QMcQ z*r*qPS33~AagzVOK>#>Ia`qzR-q{QmkNcbp{aXNP)dK`Ta3t?qSbrk`XRt*cpb&D? z0NIsrQgXrJs4C9wfrNc!L=5%dAy64D8Lc}dR}Bg> z;B777Cns#}Yk%t+*)ZC}zV%Vveb0VKU00)aH>su-{Eo^fl@aJO4q)l?{w_vJKJ1>XNbEh86<4M!G5 v7#l@*h;<6WY+!8f2dUJGo4WQsL$>}4<0=MYT>f_j00000NkvXXu0mjf#WKXL literal 442 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�Ig{{~D){c1rq!7lIAA=jeE@w)D^j)(`VruCf{F6{W=2m8Lt=k+ zmVhiZ%^c7QtVPMEo{>NmG^eXY#xmW0K^bqRZ_ywSD5l&Hg6)dS)bMGtQd)X<;``6> zfiYDAo1G^YNonz8A0vA3eXty-sU$6P5wV1Ui7QM*I%10AU?XWBP5NkhimKe{(gvD% zx>uNJsfpqWlV~&vk88Ijw?+cQ?HW#zo0`&9a@Kp&2B1|3Vy7zT7LwM+m-wV&lvDsD z8?&AbNYa%CqofZ&ssUS{8=`;(fFUwvu9J0@VdiLS; zgbw^7y46hPkQF;$#%AZ`b(>z&`w&xj8E3-!&XCut15>=|)On0^UMAbaOZ+w86{=`g zaldJm1V|%E2(U{Yp&tRhgxj(=s_UOOE#n^B^ zS0Z*;AY_1Rc!cw40h1g7iM_w!vy%fKLUp}3{*GSuB>EMME0;HwF?+=+B?1XjjLrzO zR8p&<5Kf9X=e9D*j+2PKS5E_uRWN8w;EQ~CkO z*LqodHe<{qwp9#ha6tN`!KUn6>+!68(DV6W?dzmjL~#56!b--`py!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..995d278c37cea9496ffd26b63afe676a2ce6702e 100644 GIT binary patch literal 6584 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 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 4d6372eebdb28e45604e46eeda8dd24651419bc0..4474fdb110087cef8f044c2145268fb762bac03e 100644 GIT binary patch literal 8594 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

-kFxKdImWxQ7K$H9 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 diff --git a/lib/footer/app_footer.dart b/lib/footer/app_footer.dart index 298f2f1..3123c1c 100644 --- a/lib/footer/app_footer.dart +++ b/lib/footer/app_footer.dart @@ -37,7 +37,7 @@ class AppFooter extends StatelessWidget { fontFamily: 'Poppins-Medium.ttf', ), ), - Text(appProvider.currentDeviceIp, + Text("v${appProvider.currentDeviceIp}", style: TextStyle(fontWeight: FontWeight.w500, fontSize: SizeConfig.getWidthMultiplier() * 2.2)), Row( children: [ From ba3a9a2d9c4f8f7358241b723590d1d66ae2cabd Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Mon, 7 Jul 2025 10:52:35 +0300 Subject: [PATCH 10/10] Debugged HTTPTransportType --- lib/home/app_provider.dart | 1 - lib/utils/signalR_utils.dart | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/home/app_provider.dart b/lib/home/app_provider.dart index eeb3de8..16bd180 100644 --- a/lib/home/app_provider.dart +++ b/lib/home/app_provider.dart @@ -145,7 +145,6 @@ class AppProvider extends ChangeNotifier { WidgetsConfigModel? currentWidgetsConfigModel; Future getInfoWidgetsConfigurationsFromServer() async { - log(" errorHellpo:"); WidgetsConfigModel? widgetsConfigModel = await API.getWidgetConfigsFromServer(currentDeviceIp, onFailure: (error) { logger.i("Api call failed with this error: ${error.toString()}"); }); diff --git a/lib/utils/signalR_utils.dart b/lib/utils/signalR_utils.dart index be1436f..53e4318 100644 --- a/lib/utils/signalR_utils.dart +++ b/lib/utils/signalR_utils.dart @@ -41,8 +41,6 @@ class SignalRHelper { url, HttpConnectionOptions( client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), - - //TODO: IT MUST BE WEB SOCKETS transport: HttpTransportType.webSockets, logging: (level, message) => log(message), )) @@ -57,7 +55,11 @@ class SignalRHelper { connection!.on('addChatMessage', (message) => onUpdateAvailable(message)); - await connection!.start(); + try { + await connection!.start(); + } catch (e) { + logger.i("Exception while connecting: ${e.toString()}"); + } } void sendMessage(List args) async { @@ -78,7 +80,6 @@ class SignalRHelper { } } - // startConnection(BuildContext context) async { // if (connection!.state == HubConnectionState.connected || connection!.state == HubConnectionState.connecting) { // connection!.off('addChatMessage');