final touches

faiz_kiosk
FaizHashmiCS22 10 months ago
parent 2aae8ee5e8
commit 6c8ede60d9

@ -10,15 +10,15 @@
</intent>
</queries>
<application
android:label="QLine"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/ic_launcher"
android:label="QLine">
<!-- Define the BroadcastReceiver that listens to the BOOT_COMPLETED event -->
<receiver
android:name="BootReceiver"
android:name=".BootBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
@ -28,24 +28,23 @@
</receiver>
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
@ -61,8 +60,8 @@
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
<action android:name="android.intent.action.PROCESS_TEXT" />
<data android:mimeType="text/plain" />
</intent>
</queries>
</manifest>

@ -1,14 +1,19 @@
package com.example.hmg_qline.hmg_qline
import android.content.BroadcastReceiver
import android.content.Context;
import android.content.Intent;
import android.content.Context
import android.content.Intent
import android.util.Log
class BootReceiver : BroadcastReceiver() {
class BootBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED ||
intent.action == "android.intent.action.QUICKBOOT_POWERON"
) {
// Launch the app automatically on boot
val i = Intent(context, MainActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // Start activity outside of an existing task
context.startActivity(i)
}
}

@ -1,5 +1,19 @@
package com.example.hmg_qline.hmg_qline
import android.os.Build
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity()
class MainActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// var REQUEST_OVERLAY_PERMISSIONS = 100
// if (!Settings.canDrawOverlays(applicationContext)) {
// val myIntent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
// val uri: Uri = Uri.fromParts("package", packageName, null)
// myIntent.data = uri
// startActivityForResult(myIntent, REQUEST_OVERLAY_PERMISSIONS)
// return
// }
}
}

Binary file not shown.

@ -25,7 +25,8 @@ class MyApp extends StatelessWidget {
builder: (context, constraints) {
return OrientationBuilder(builder: (context, orientation) {
SizeConfig().init(constraints, orientation);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
return MultiProvider(
providers: [
ChangeNotifierProvider<ScreenConfigViewModel>(create: (context) => getIt.get<ScreenConfigViewModel>()),

@ -44,7 +44,7 @@ class GlobalConfigurationsModel {
dynamic editedOn;
bool isToneReq = false;
bool isVoiceReq = false;
int orientationType = 1;
ScreenOrientationEnum orientationTypeEnum = ScreenOrientationEnum.portraitUp;
bool? isTurnOn;
int? waitingAreaType;
int? gender;
@ -99,7 +99,7 @@ class GlobalConfigurationsModel {
this.editedOn,
this.isToneReq = false,
this.isVoiceReq = false,
this.orientationType = 1,
this.orientationTypeEnum = ScreenOrientationEnum.portraitUp,
this.isTurnOn,
this.waitingAreaType,
this.gender,
@ -157,7 +157,7 @@ class GlobalConfigurationsModel {
isVoiceReq = json['isVoiceReq'] ?? false;
// isToneReq = true;
// isVoiceReq = true;
orientationType = json['orientationType'] ?? 1;
orientationTypeEnum = ((json['orientationType'] ?? 1) as int).toScreenOrientationEnum();
isTurnOn = json['isTurnOn'];
waitingAreaType = json['waitingAreaType'];
gender = json['gender'];

@ -34,6 +34,8 @@ class TicketData {
String? patientEmail;
int? preferredLang;
LanguageEnum voiceLanguageEnum = LanguageEnum.english;
String ticketNoText = "Ticket Number";
String postVoiceText = "Please Visit Counter";
int? patientGender;
String? roomNo;
bool? isActive;
@ -55,6 +57,9 @@ class TicketData {
this.mobileNo,
this.patientEmail,
this.preferredLang,
this.voiceLanguageEnum = LanguageEnum.english,
this.ticketNoText = "Ticket Number",
this.postVoiceText = "Please Visit Counter",
this.patientGender,
this.roomNo,
this.isActive,
@ -77,7 +82,9 @@ class TicketData {
mobileNo = json['mobileNo'];
patientEmail = json['patientEmail'];
preferredLang = (json['preferredLang'] != null && json['preferredLang'].trim() != "") ? int.parse(json['preferredLang']) : 1;
voiceLanguageEnum = (json['preferredLang'] != null && json['preferredLang'].trim() != "") ? (json['preferredLang'] as int).toLanguageEnum() : LanguageEnum.english;
voiceLanguageEnum = (json['preferredLang'] != null && json['preferredLang'].trim() != "") ? (int.parse(json['preferredLang'])).toLanguageEnum() : LanguageEnum.english;
ticketNoText = json['ticketNoText'] ?? "Ticket Number";
postVoiceText = json['pleaseVisitCounterText'] ?? "Please Visit Counter";
patientGender = json['patientGender'] ?? 1;
roomNo = json['roomNo'].toString();
isActive = json['isActive'];

@ -13,6 +13,8 @@ abstract class TextToSpeechService {
required GlobalConfigurationsModel globalConfigurationsModel,
});
Future<void> speechTextTest(String test);
void listenToTextToSpeechEvents({required Function() onVoiceCompleted});
}
@ -25,6 +27,14 @@ class TextToSpeechServiceImp implements TextToSpeechService {
double pitch = 0.6;
double rate = 0.2;
@override
Future<void> speechTextTest(String test) async {
await textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString());
textToSpeechInstance.setSpeechRate(0.37);
textToSpeechInstance.setPitch(0.8);
await textToSpeechInstance.speak(test);
}
@override
Future<void> speechText({
required TicketDetailsModel ticket,
@ -33,7 +43,7 @@ class TextToSpeechServiceImp implements TextToSpeechService {
const ttsGoogleEngine = 'com.google.android.tts';
// const ttsFlyTecEngine = 'com.iflytek.speechcloud';
LanguageEnum langEnum = globalConfigurationsModel.voiceLanguageEnum;
LanguageEnum langEnum = ticket.ticketModel!.voiceLanguageEnum;
List engines = await textToSpeechInstance.getEngines;
if (engines.contains(ttsGoogleEngine)) {
await textToSpeechInstance.setEngine(ttsGoogleEngine);
@ -51,9 +61,9 @@ class TextToSpeechServiceImp implements TextToSpeechService {
textToSpeechInstance.setPitch(0.85);
}
// String postVoice = globalConfigurationsModel.postVoiceText;
// String preVoice = globalConfigurationsModel.ticketNoText;
// String preVoice = ticket.ticketModel!.ticketNoText;
String postVoice = globalConfigurationsModel.postVoiceText;
String postVoice = ticket.ticketModel!.postVoiceText;
String preVoice = '';
String roomNo = '';
if (ticket.ticketModel!.roomNo != null && ticket.ticketModel!.roomNo!.isNotEmpty) {
@ -97,9 +107,9 @@ class TextToSpeechServiceImp implements TextToSpeechService {
textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString());
await textToSpeechInstance.speak(" $patientAlpha .. $patientNumeric .. ");
await textToSpeechInstance.setLanguage(langEnum.enumToString());
await textToSpeechInstance.speak(" $postVoice ");
await textToSpeechInstance.speak(" $postVoice $roomNo");
} else {
await textToSpeechInstance.speak("$preVoice $patientAlpha .. .. $patientNumeric .. .. $postVoice");
await textToSpeechInstance.speak("$preVoice $patientAlpha .. .. $patientNumeric .. .. $postVoice $roomNo");
}
}

@ -142,6 +142,11 @@ class QueuingViewModel extends ChangeNotifier {
notifyListeners();
}
Future<void> testSpeech() async {
audioService.playTone(path: AppAssets.callTone);
textToSpeechService.speechTextTest("Hello Qamar?");
}
Future<void> voiceCallTicket({required TicketData? ticketData}) async {
if (ticketData == null) return;
GlobalConfigurationsModel globalConfigurationsModel = getIt.get<ScreenConfigViewModel>().globalConfigurationsModel;

@ -27,7 +27,6 @@ class ScreenConfigViewModel extends ChangeNotifier {
});
Future<void> initializeScreenConfigVM() async {
await getCurrentScreenIP();
await getGlobalConfigurationsByIP();
await getInfoWidgetsDetailsFromServer();
await getLastTimeUpdatedFromCache();
@ -35,6 +34,17 @@ class ScreenConfigViewModel extends ChangeNotifier {
getTheWidgetsConfigurationsEveryMidnight();
}
Future<void> waitForIPAndInitializeConfigVM() async {
while (currentScreenIP == "") {
await getCurrentScreenIP();
if (currentScreenIP != "") {
initializeScreenConfigVM();
} else {
await Future.delayed(const Duration(seconds: 2));
}
}
}
bool isInternetConnected = true;
updateIsInternetConnected(bool value) {
@ -56,10 +66,8 @@ class ScreenConfigViewModel extends ChangeNotifier {
notifyListeners();
}
ScreenOrientationEnum currentScreenRotation = ScreenOrientationEnum.portraitUp;
updateCurrentScreenRotation(ScreenOrientationEnum value) {
currentScreenRotation = value;
globalConfigurationsModel.orientationTypeEnum = value;
notifyListeners();
}
@ -82,6 +90,7 @@ class ScreenConfigViewModel extends ChangeNotifier {
currentScreenIP = AppConstants.testIP;
} else {
currentScreenIP = await connectivityService.getCurrentScreenIP();
log("currentScreenIP: $currentScreenIP");
}
}
@ -269,8 +278,7 @@ class ScreenConfigViewModel extends ChangeNotifier {
}
}
Future<void> createAutoTickets() async {
int numOfTicketsToCreate = 20;
Future<void> createAutoTickets({required int numOfTicketsToCreate}) async {
int startTicket = 123456920;
for (int i = 0; i < numOfTicketsToCreate; i++) {
@ -281,5 +289,7 @@ class ScreenConfigViewModel extends ChangeNotifier {
return;
}
}
log("last ticket is: $startTicket ");
}
}

@ -79,7 +79,7 @@ class AppFooter extends StatelessWidget {
const SizedBox(width: 10),
InkWell(
onTap: () {
// context.read<ScreenConfigViewModel>().createAutoTickets();
// context.read<ScreenConfigViewModel>().createAutoTickets(numOfTicketsToCreate: 20);
},
child: Image.asset(
AppAssets.cloudLogo,

@ -64,7 +64,7 @@ class AppHeader extends StatelessWidget implements PreferredSizeWidget {
children: [
Container(
alignment: Alignment.center,
height: SizeConfig.getHeightMultiplier() * 0.8,
height: SizeConfig.getHeightMultiplier() * 0.65,
padding: const EdgeInsets.only(left: 20, right: 20),
decoration: BoxDecoration(color: AppColors.redColor),
child: Directionality(

@ -22,7 +22,7 @@ class MainQueueScreen extends StatelessWidget {
return const SizedBox.shrink();
}
return Container(
height: (screenConfigViewModel.currentScreenRotation == ScreenOrientationEnum.portraitUp || screenConfigViewModel.currentScreenRotation == ScreenOrientationEnum.portraitDown)
height: (screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown)
? SizeConfig.getHeightMultiplier() * 2
: SizeConfig.getHeightMultiplier() * 0.9,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
@ -66,7 +66,7 @@ class MainQueueScreen extends StatelessWidget {
}
return SizedBox(
child: Container(
height: (screenConfigViewModel.currentScreenRotation == ScreenOrientationEnum.portraitUp || screenConfigViewModel.currentScreenRotation == ScreenOrientationEnum.portraitDown)
height: (screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown)
? SizeConfig.getHeightMultiplier() * 2
: SizeConfig.getHeightMultiplier() * 0.9,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
@ -147,7 +147,7 @@ class MainQueueScreen extends StatelessWidget {
widget = PriorityTicketsSidelist(
tickets: queuingViewModel.currentTickets,
globalConfigurationsModel: screenConfigViewModel.globalConfigurationsModel,
screenOrientationEnum: screenConfigViewModel.currentScreenRotation,
screenOrientationEnum: screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum,
);
} else {
widget = PriorityTickets(
@ -165,13 +165,13 @@ class MainQueueScreen extends StatelessWidget {
int flex = 1;
if (screenConfigVM.currentScreenTypeEnum == ScreenTypeEnum.roomLevelScreen) {
if (screenConfigVM.currentScreenRotation == ScreenOrientationEnum.portraitUp || screenConfigVM.currentScreenRotation == ScreenOrientationEnum.portraitDown) {
if (screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) {
flex = 2;
} else {
flex = 3;
}
} else {
if (screenConfigVM.currentScreenRotation == ScreenOrientationEnum.portraitUp || screenConfigVM.currentScreenRotation == ScreenOrientationEnum.portraitDown) {
if (screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) {
flex = 2;
} else {
flex = 1;
@ -216,7 +216,7 @@ class MainQueueScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Selector<ScreenConfigViewModel, ScreenOrientationEnum>(
selector: (context, screenConfigViewModel) => screenConfigViewModel.currentScreenRotation,
selector: (context, screenConfigViewModel) => screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum,
builder: (BuildContext context, ScreenOrientationEnum screenOrientationEnum, Widget? child) {
//TODO: For Testing Only
// context.read<QueuingViewModel>().voiceCallTicket(ticketData: context.read<QueuingViewModel>().currentTickets.first.ticketModel);

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:hmg_qline/config/routes.dart';
import 'package:hmg_qline/constants/app_constants.dart';
import 'package:hmg_qline/utilities/extensions.dart';
import 'package:hmg_qline/view_models/queuing_view_model.dart';
import 'package:hmg_qline/view_models/screen_config_view_model.dart';
@ -12,7 +11,7 @@ class SplashScreen extends StatelessWidget {
Future<void> _loadData(BuildContext context) async {
final screenConfigViewModel = context.read<ScreenConfigViewModel>();
final queuingViewModel = context.read<QueuingViewModel>();
await screenConfigViewModel.initializeScreenConfigVM();
await screenConfigViewModel.waitForIPAndInitializeConfigVM();
await queuingViewModel.initializeQueueingVM();
}

Loading…
Cancel
Save