# Conflicts:
#	assets/langs/ar-SA.json
#	assets/langs/en-US.json
#	lib/classes/consts.dart
#	lib/generated/locale_keys.g.dart
#	lib/ui/landing/dashboard_screen.dart
sultan-dev
Sultan khan 3 years ago
commit 61904ca5f7

@ -21,6 +21,12 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0' flutterVersionName = '1.0'
} }
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
@ -44,18 +50,24 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.cloudSolutions.mohemmtest" applicationId "hmg.cloudSolutions.mohem"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 32 targetSdkVersion 33
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
} }
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes { buildTypes {
release { release {
// TODO: Add your own signing config for the release build. signingConfig signingConfigs.release
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
} }
} }
} }

@ -10,7 +10,7 @@
"client_info": { "client_info": {
"mobilesdk_app_id": "1:679409052782:android:dba155ac0859d7fea78a7f", "mobilesdk_app_id": "1:679409052782:android:dba155ac0859d7fea78a7f",
"android_client_info": { "android_client_info": {
"package_name": "com.cloudSolutions.mohemmtest" "package_name": "hmg.cloudSolutions.mohem"
} }
}, },
"oauth_client": [ "oauth_client": [

@ -7,11 +7,12 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application <application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="Mohemm" android:label="Mohemm"
android:allowBackup="false"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"> android:roundIcon="@mipmap/ic_launcher_round">
<activity <activity
@ -37,15 +38,21 @@
<meta-data <meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable" android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" /> android:resource="@drawable/launch_background" />
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
</application> </application>
</manifest> </manifest>

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#E2E5E7;" d="M128,0c-17.6,0-32,14.4-32,32v448c0,17.6,14.4,32,32,32h320c17.6,0,32-14.4,32-32V128L352,0H128z"/>
<path style="fill:#B0B7BD;" d="M384,128h96L352,0v96C352,113.6,366.4,128,384,128z"/>
<polygon style="fill:#CAD1D8;" points="480,224 384,128 480,128 "/>
<path style="fill:#F15642;" d="M416,416c0,8.8-7.2,16-16,16H48c-8.8,0-16-7.2-16-16V256c0-8.8,7.2-16,16-16h352c8.8,0,16,7.2,16,16
V416z"/>
<g>
<path style="fill:#FFFFFF;" d="M88.368,384c-4.096-2.304-6.656-6.912-4.096-12.288l36.72-71.744c3.456-6.784,12.656-7.04,15.856,0
l36.08,71.744c5.248,9.984-10.24,17.904-14.848,7.936l-5.632-11.248h-47.2l-5.52,11.248C97.712,384,92.992,384.912,88.368,384z
M143.392,351.52l-14.464-31.616l-15.744,31.616H143.392z"/>
<path style="fill:#FFFFFF;" d="M189.184,384c-4.096-2.304-6.656-6.912-4.096-12.288l36.704-71.744
c3.456-6.784,12.672-7.04,15.872,0l36.064,71.744c5.248,9.984-10.24,17.904-14.832,7.936l-5.648-11.248h-47.2l-5.504,11.248
C198.512,384,193.776,384.912,189.184,384z M244.192,351.52l-14.448-31.616l-15.728,31.616H244.192z"/>
<path style="fill:#FFFFFF;" d="M282.416,339.088c0-24.688,15.488-45.904,44.912-45.904c11.136,0,19.952,3.312,29.296,11.376
c3.456,3.184,3.84,8.832,0.384,12.4c-3.456,3.056-8.704,2.688-11.76-0.368c-5.248-5.504-10.624-7.024-17.92-7.024
c-19.696,0-29.168,13.936-29.168,29.536c0,15.872,9.344,30.464,29.168,30.464c7.296,0,14.08-2.96,19.952-8.192
c3.968-3.072,9.472-1.552,11.776,1.536c2.048,2.816,3.056,7.536-1.408,12.016c-8.96,8.336-19.696,9.984-30.336,9.984
C296.368,384.912,282.416,363.792,282.416,339.088z"/>
</g>
<path style="fill:#CAD1D8;" d="M400,432H96v16h304c8.8,0,16-7.2,16-16v-16C416,424.8,408.8,432,400,432z"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#E2E5E7;" d="M128,0c-17.6,0-32,14.4-32,32v448c0,17.616,14.4,32,32,32h320c17.6,0,32-14.384,32-32V128L352,0H128z
"/>
<path style="fill:#B0B7BD;" d="M384,128h96L352,0v96C352,113.6,366.4,128,384,128z"/>
<polygon style="fill:#CAD1D8;" points="480,224 384,128 480,128 "/>
<path style="fill:#50BEE8;" d="M416,416c0,8.8-7.2,16-16,16H48c-8.8,0-16-7.2-16-16V256c0-8.8,7.2-16,16-16h352c8.8,0,16,7.2,16,16
V416z"/>
<g>
<path style="fill:#FFFFFF;" d="M117.184,327.84v47.344c0,5.632-4.592,8.832-9.216,8.832c-4.096,0-7.664-3.2-7.664-8.832v-72.032
c0-6.64,5.632-8.832,7.664-8.832c3.712,0,5.888,2.192,8.064,4.608l28.16,38l29.152-39.408c4.24-5.248,14.592-3.2,14.592,5.632
v72.032c0,5.632-3.6,8.832-7.68,8.832c-4.592,0-8.192-3.2-8.192-8.832V327.84l-21.232,26.88c-4.592,5.632-10.352,5.632-14.576,0
L117.184,327.84z"/>
<path style="fill:#FFFFFF;" d="M210.288,303.152c0-4.224,3.328-8.832,8.704-8.832h29.552c16.64,0,31.616,11.136,31.616,32.496
c0,20.224-14.976,31.472-31.616,31.472h-21.36v16.896c0,5.632-3.584,8.832-8.192,8.832c-4.224,0-8.704-3.2-8.704-8.832V303.152z
M227.168,310.448v31.856h21.36c8.576,0,15.36-7.552,15.36-15.488c0-8.96-6.784-16.368-15.36-16.368L227.168,310.448
L227.168,310.448z"/>
<path style="fill:#FFFFFF;" d="M322.064,311.472h-21.872c-10.736,0-10.096-15.984,0-15.984h39.152c7.792,0,11.376,8.96,5.632,14.72
l-21.232,19.824c15.616-1.152,27.888,10.48,27.888,24.816c0,15.728-11.136,29.168-34.544,29.168
c-10.24,0-20.336-4.224-26.224-13.44c-6.144-9.072,7.024-17.776,13.936-8.832c3.328,4.352,8.704,6.528,14.448,6.528
c7.808,0,15.488-3.328,15.488-13.44c0-13.296-16.256-11.248-25.072-10.352c-10.752,2.048-13.936-9.6-7.664-14.448L322.064,311.472z
"/>
</g>
<path style="fill:#CAD1D8;" d="M400,432H96v16h304c8.8,0,16-7.2,16-16v-16C416,424.8,408.8,432,400,432z"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@ -0,0 +1,522 @@
[
{
"id": "b8f10b10-221c-495d-b99b-6a8094892549",
"titleEn": "How many time Uruguay won FIFA World Cups?",
"titleAr": "How many time Uruguay won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/51b598b6-c837-45be-8734-1374978bd426_congratulations-gif.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 1,
"questionOptions": [
{
"id": "772e6062-543c-4ddc-e516-08dae8b36b35",
"titleEn": "1",
"titleAr": "1",
"questionId": "b8f10b10-221c-495d-b99b-6a8094892549",
"sequence": 1,
"image": "null",
"isCorrectOption": false
},
{
"id": "ea3c673e-78c7-41dd-e517-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "b8f10b10-221c-495d-b99b-6a8094892549",
"sequence": 3,
"image": "null",
"isCorrectOption": true
},
{
"id": "7adbdfec-ef77-417e-e518-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "b8f10b10-221c-495d-b99b-6a8094892549",
"sequence": 2,
"image": "null",
"isCorrectOption": false
},
{
"id": "895eab85-e321-4d3e-e519-08dae8b36b35",
"titleEn": "4",
"titleAr": "4",
"questionId": "b8f10b10-221c-495d-b99b-6a8094892549",
"sequence": 4,
"image": "null",
"isCorrectOption": false
}
]
},
{
"id": "0d60d55f-4067-48f9-9ace-b6309c6a7cf0",
"titleEn": "Who is the current FIFA World Cup Winner?",
"titleAr": "Who is the current FIFA World Cup Winner?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/24dddc50-7583-48b4-9fec-8a490d246191_great-thumbs.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "dd0ba127-26ed-4308-e50e-08dae8b36b35",
"titleEn": "Brazil",
"titleAr": "Brazil",
"questionId": "0d60d55f-4067-48f9-9ace-b6309c6a7cf0",
"sequence": 1,
"image": "null",
"isCorrectOption": false
},
{
"id": "4748df31-95f0-4fee-e50f-08dae8b36b35",
"titleEn": "Argentina",
"titleAr": "Argentina",
"questionId": "0d60d55f-4067-48f9-9ace-b6309c6a7cf0",
"sequence": 4,
"image": "null",
"isCorrectOption": true
},
{
"id": "4079d32a-891b-4e83-e510-08dae8b36b35",
"titleEn": "Germany",
"titleAr": "Germany",
"questionId": "0d60d55f-4067-48f9-9ace-b6309c6a7cf0",
"sequence": 3,
"image": "null",
"isCorrectOption": false
},
{
"id": "1c17cfcd-9f19-4020-e511-08dae8b36b35",
"titleEn": "France",
"titleAr": "France",
"questionId": "0d60d55f-4067-48f9-9ace-b6309c6a7cf0",
"sequence": 2,
"image": "null",
"isCorrectOption": false
}
]
},
{
"id": "489659b0-0400-4b64-8ce2-e6fe48db61db",
"titleEn": "How many times England won FIFA World Cups?",
"titleAr": "How many times England won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/a9ffa364-231c-4877-824f-84febac51086_thumbs-up-simon-cowell.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "7f63cd45-ce2c-417f-e502-08dae8b36b35",
"titleEn": "1",
"titleAr": "1",
"questionId": "489659b0-0400-4b64-8ce2-e6fe48db61db",
"sequence": 1,
"image": "null",
"isCorrectOption": true
},
{
"id": "34690bfa-0ffd-453f-e503-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "489659b0-0400-4b64-8ce2-e6fe48db61db",
"sequence": 2,
"image": "null",
"isCorrectOption": false
},
{
"id": "4526efdd-ff6f-4340-e504-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "489659b0-0400-4b64-8ce2-e6fe48db61db",
"sequence": 3,
"image": "null",
"isCorrectOption": false
},
{
"id": "65d06188-fa63-49fd-e505-08dae8b36b35",
"titleEn": "4",
"titleAr": "4",
"questionId": "489659b0-0400-4b64-8ce2-e6fe48db61db",
"sequence": 4,
"image": "null",
"isCorrectOption": false
}
]
},
{
"id": "253fc396-dab9-41ca-82bd-511f98c5dee8",
"titleEn": "How many time Germany won FIFA World Cups?",
"titleAr": "How many time Germany won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/012d6493-3612-42c9-8f6f-84417d4736d4_good-job-well-done.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "dce4999c-5629-45f4-e4f6-08dae8b36b35",
"titleEn": "1",
"titleAr": "1",
"questionId": "253fc396-dab9-41ca-82bd-511f98c5dee8",
"sequence": 1,
"image": "null",
"isCorrectOption": false
},
{
"id": "00913ba1-5ccc-4d7c-e4f7-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "253fc396-dab9-41ca-82bd-511f98c5dee8",
"sequence": 2,
"image": "null",
"isCorrectOption": false
},
{
"id": "9e5f5e89-608e-4fc9-e4f8-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "253fc396-dab9-41ca-82bd-511f98c5dee8",
"sequence": 3,
"image": "null",
"isCorrectOption": false
},
{
"id": "a535cacf-ee4d-4895-e4f9-08dae8b36b35",
"titleEn": "4",
"titleAr": "4",
"questionId": "253fc396-dab9-41ca-82bd-511f98c5dee8",
"sequence": 4,
"image": "null",
"isCorrectOption": true
}
]
},
{
"id": "669c4fe2-a3e6-4e29-8c56-ae09efa9ba6c",
"titleEn": "How many times Portugal won FIFA World Cups?",
"titleAr": "How many times Portugal won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/ca3f32a1-ed9f-45df-b2fb-3d1df78d5651_congrats-14.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "597c308e-3f09-4a05-e506-08dae8b36b35",
"titleEn": "0",
"titleAr": "0",
"questionId": "669c4fe2-a3e6-4e29-8c56-ae09efa9ba6c",
"sequence": 1,
"image": "null",
"isCorrectOption": true
},
{
"id": "2face927-7c8e-4945-e507-08dae8b36b35",
"titleEn": "1",
"titleAr": "1",
"questionId": "669c4fe2-a3e6-4e29-8c56-ae09efa9ba6c",
"sequence": 2,
"image": "null",
"isCorrectOption": false
},
{
"id": "bde21640-798e-4750-e508-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "669c4fe2-a3e6-4e29-8c56-ae09efa9ba6c",
"sequence": 3,
"image": "null",
"isCorrectOption": false
},
{
"id": "9312acac-f0c3-4ed4-e509-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "669c4fe2-a3e6-4e29-8c56-ae09efa9ba6c",
"sequence": 4,
"image": "null",
"isCorrectOption": false
}
]
},
{
"id": "f91774ce-14f0-4af0-9a77-e649bc013b44",
"titleEn": "How many times Spain won FIFA World Cups?",
"titleAr": "How many times Spain won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/6484c5bc-09fd-4586-8036-67868afbe27b_good-job-well-done.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "2f968964-ce91-4478-e512-08dae8b36b35",
"titleEn": "1",
"titleAr": "1",
"questionId": "f91774ce-14f0-4af0-9a77-e649bc013b44",
"sequence": 1,
"image": "null",
"isCorrectOption": true
},
{
"id": "4fed9355-2c9f-458d-e513-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "f91774ce-14f0-4af0-9a77-e649bc013b44",
"sequence": 2,
"image": "null",
"isCorrectOption": false
},
{
"id": "8f232a43-3792-4cd0-e514-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "f91774ce-14f0-4af0-9a77-e649bc013b44",
"sequence": 3,
"image": "null",
"isCorrectOption": false
},
{
"id": "24478e43-bf4c-4852-e515-08dae8b36b35",
"titleEn": "4",
"titleAr": "4",
"questionId": "f91774ce-14f0-4af0-9a77-e649bc013b44",
"sequence": 4,
"image": "null",
"isCorrectOption": false
}
]
},
{
"id": "fd3a90e6-5b35-4035-bc1c-4483facaf6d3",
"titleEn": "How many times France won FIFA World Cups?",
"titleAr": "How many times France won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/24dddc50-7583-48b4-9fec-8a490d246191_great-thumbs.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "9d0743e0-9f3f-48d0-e4fa-08dae8b36b35",
"titleEn": "1",
"titleAr": "1",
"questionId": "fd3a90e6-5b35-4035-bc1c-4483facaf6d3",
"sequence": 1,
"image": "null",
"isCorrectOption": false
},
{
"id": "a81eda99-d9ad-49e0-e4fb-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "fd3a90e6-5b35-4035-bc1c-4483facaf6d3",
"sequence": 2,
"image": "null",
"isCorrectOption": true
},
{
"id": "7ca78891-890d-4023-e4fc-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "fd3a90e6-5b35-4035-bc1c-4483facaf6d3",
"sequence": 3,
"image": "null",
"isCorrectOption": false
},
{
"id": "d1a98bd9-8afa-49c1-e4fd-08dae8b36b35",
"titleEn": "4",
"titleAr": "4",
"questionId": "fd3a90e6-5b35-4035-bc1c-4483facaf6d3",
"sequence": 4,
"image": "null",
"isCorrectOption": false
}
]
},
{
"id": "3a35855d-3ed7-4d45-8864-9135d71378de",
"titleEn": "How many time Argentina won FIFA World Cups?",
"titleAr": "How many time Argentina won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/24dddc50-7583-48b4-9fec-8a490d246191_great-thumbs.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "f0766816-837f-47e6-e51a-08dae8b36b35",
"titleEn": "1",
"titleAr": "1",
"questionId": "3a35855d-3ed7-4d45-8864-9135d71378de",
"sequence": 1,
"image": "null",
"isCorrectOption": false
},
{
"id": "dc9c68de-afa4-4b63-e51b-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "3a35855d-3ed7-4d45-8864-9135d71378de",
"sequence": 2,
"image": "null",
"isCorrectOption": false
},
{
"id": "52f2d024-8a29-4781-e51c-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "3a35855d-3ed7-4d45-8864-9135d71378de",
"sequence": 3,
"image": "null",
"isCorrectOption": true
},
{
"id": "122636e4-5e98-499e-e51d-08dae8b36b35",
"titleEn": "4",
"titleAr": "4",
"questionId": "3a35855d-3ed7-4d45-8864-9135d71378de",
"sequence": 4,
"image": "null",
"isCorrectOption": false
}
]
},
{
"id": "6c9d809d-683b-4d77-b98e-62a0d083488a",
"titleEn": "How many times Brazil won FIFA World Cups?",
"titleAr": "How many times Brazil won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/a9ffa364-231c-4877-824f-84febac51086_thumbs-up-simon-cowell.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "4e94437a-b10d-46c6-e4fe-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "6c9d809d-683b-4d77-b98e-62a0d083488a",
"sequence": 1,
"image": "null",
"isCorrectOption": false
},
{
"id": "6e0e8baa-c13e-45f1-e4ff-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "6c9d809d-683b-4d77-b98e-62a0d083488a",
"sequence": 2,
"image": "null",
"isCorrectOption": false
},
{
"id": "3065d26a-9aa4-4626-e500-08dae8b36b35",
"titleEn": "4",
"titleAr": "4",
"questionId": "6c9d809d-683b-4d77-b98e-62a0d083488a",
"sequence": 3,
"image": "null",
"isCorrectOption": false
},
{
"id": "6cc3ff60-02cc-4e59-e501-08dae8b36b35",
"titleEn": "5",
"titleAr": "5",
"questionId": "6c9d809d-683b-4d77-b98e-62a0d083488a",
"sequence": 4,
"image": "null",
"isCorrectOption": true
}
]
},
{
"id": "e8c8442e-f370-444d-bee9-f7f75d146e5c",
"titleEn": "How many times Italy won FIFA World Cups?",
"titleAr": "How many times Italy won FIFA World Cups?",
"marathonId": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"questionTypeId": 1,
"questionTime": 10,
"nextQuestGap": 5,
"gapType": 0,
"gapText": null,
"gapImage": "Questions/34f3c402-1244-4320-98c2-751cb2a347c5_congrats-1.gif",
"questOptionsLimit": 0,
"remainingParticipantCount": 0,
"questionOptions": [
{
"id": "53d456b7-8f56-4c58-e50a-08dae8b36b35",
"titleEn": "1",
"titleAr": "1",
"questionId": "e8c8442e-f370-444d-bee9-f7f75d146e5c",
"sequence": 1,
"image": "null",
"isCorrectOption": false
},
{
"id": "280df6d7-ca61-4d78-e50b-08dae8b36b35",
"titleEn": "2",
"titleAr": "2",
"questionId": "e8c8442e-f370-444d-bee9-f7f75d146e5c",
"sequence": 2,
"image": "null",
"isCorrectOption": false
},
{
"id": "769939dc-4a46-4f4f-e50c-08dae8b36b35",
"titleEn": "3",
"titleAr": "3",
"questionId": "e8c8442e-f370-444d-bee9-f7f75d146e5c",
"sequence": 3,
"image": "null",
"isCorrectOption": false
},
{
"id": "c389fae7-0019-4922-e50d-08dae8b36b35",
"titleEn": "4",
"titleAr": "4",
"questionId": "e8c8442e-f370-444d-bee9-f7f75d146e5c",
"sequence": 4,
"image": "null",
"isCorrectOption": true
}
]
}
]

@ -0,0 +1,46 @@
{
"id": "979813be-eafa-4d3e-d27e-08dae8a08a3b",
"titleEn": "FIFA World Cup",
"titleAr": "undefined",
"descEn": "FIFA World Cup Description",
"descAr": "undefined",
"questionTime": 10,
"winDeciderTime": 30,
"winnersCount": 1,
"questGapTime": 5,
"startTime": "2022-12-28T10:44:41",
"endTime": null,
"marathoneStatusId": 4,
"scheduleTime": "2022-12-28T10:14:41",
"selectedLanguage": 0,
"projects": {
"id": "b1cd3fa3-bb27-422e-a4c1-08dac09254df",
"nameEn": "Cloud Solutions",
"nameAr": "333شركة حلول السحابة للاتصالات وتقنية المعلومات",
"projectCode": "CS"
},
"sponsors": [
{
"id": "3272b127-b388-4f09-425b-08dac2eb788e",
"nameEn": "Cloud Solutions",
"nameAr": "حل السحابة",
"image": "SponsorImage/b9aed4a8-42b2-45fc-b6f1-47ee0c7b4138_sponsor.jpeg",
"video": "SponsorVideo/9ab678ab-1b4c-4ea4-aaf2-32ce1353d3fe_sample-10s.mp4",
"logo": "SponsorLogo/eb029f0d-bce1-4a61-b0c0-abaa484912a0_sponsor.jpeg",
"videoDuration": null,
"sponsorPrizes": [
{
"id": "e657a18c-6fb2-4099-07c8-08dae89efcd3",
"marathonPrizeEn": "SAR 500",
"marathonPrizeAr": "SAR 500"
}
]
}
],
"questions": null,
"isEmailSent": false,
"totalQuestions": 10,
"cancelReason": null,
"marathonBufferTime": 30,
"currentTime": "2022-12-28T08:03:24.3671803Z"
}

@ -480,6 +480,7 @@
"gameTime": "وقت اللعب:", "gameTime": "وقت اللعب:",
"joinMarathon": "انضم إلى ماراثون", "joinMarathon": "انضم إلى ماراثون",
"joinDemoMarathon": "انضم إلى الماراثون التجريبي", "joinDemoMarathon": "انضم إلى الماراثون التجريبي",
"demo":"تجريبي",
"minutes": "الدقائق", "minutes": "الدقائق",
"seconds": "ثواني", "seconds": "ثواني",
"note": "ملحوظة:", "note": "ملحوظة:",
@ -489,9 +490,11 @@
"sponsoredBy": "برعاية:", "sponsoredBy": "برعاية:",
"question": "سؤال", "question": "سؤال",
"marathoners": "الماراثون", "marathoners": "الماراثون",
"marathoner": "ماراثونر",
"prize": "جائزة:", "prize": "جائزة:",
"winnerSelection": "اختيار الفائز", "winnerSelection": "اختيار الفائز",
"qualifiers": "تصفيات", "qualifiers": "تصفيات",
"qualifier": "المؤهل",
"getReadyForContest": "استعد للمسابقة القادمة:", "getReadyForContest": "استعد للمسابقة القادمة:",
"winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.", "winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.",
"fingersCrossed": "تشابك الاصابع!!!", "fingersCrossed": "تشابك الاصابع!!!",
@ -514,8 +517,12 @@
"startingIn": "يبدأ في", "startingIn": "يبدأ في",
"youAreOutOfContest": "أنت خارج المسابقة.", "youAreOutOfContest": "أنت خارج المسابقة.",
"winners": "الفائزين!!!", "winners": "الفائزين!!!",
"fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية",
"expireAfter":"تنتهي بعد", "expireAfter":"تنتهي بعد",
"oneWeek":"أسبوع 1", "oneWeek":"أسبوع 1",
"twoWeek":"2 أسبوع" "twoWeek":"2 أسبوع",
"noUpcoming": "لا يوجد قادم",
"fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية",
"noWinner": "حزين! لم يفز أحد اليوم.",
"myTeam" : "فريقي",
"youCanPlayDemo": "لكن يمكنك لعب العرض"
} }

@ -469,6 +469,7 @@
"gameTime": "Game Time:", "gameTime": "Game Time:",
"joinMarathon": "Join Marathon", "joinMarathon": "Join Marathon",
"joinDemoMarathon": "Join Demo Marathon", "joinDemoMarathon": "Join Demo Marathon",
"demo":"Demo",
"minutes": "Minutes", "minutes": "Minutes",
"seconds": "Seconds", "seconds": "Seconds",
"note": "Note:", "note": "Note:",
@ -478,6 +479,7 @@
"sponsoredBy": "Sponsored By:", "sponsoredBy": "Sponsored By:",
"question": "Question", "question": "Question",
"marathoners": "Marathoners", "marathoners": "Marathoners",
"marathoner": "Marathoner",
"prize": "Prize:", "prize": "Prize:",
"advancedSearch": "Advanced Search", "advancedSearch": "Advanced Search",
"openNot": "Open Notifications", "openNot": "Open Notifications",
@ -492,6 +494,7 @@
"none": "None", "none": "None",
"winnerSelection": "Winner Selection", "winnerSelection": "Winner Selection",
"qualifiers": "Qualifiers", "qualifiers": "Qualifiers",
"qualifier": "Qualifier",
"getReadyForContest": "Get Ready for the coming contest:", "getReadyForContest": "Get Ready for the coming contest:",
"winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.", "winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.",
"fingersCrossed": "Fingers Crossed!!!", "fingersCrossed": "Fingers Crossed!!!",
@ -505,8 +508,8 @@
"favorite": "My Favorites", "favorite": "My Favorites",
"searchfromchat": "Search from chat", "searchfromchat": "Search from chat",
"yourAnswerCorrect": "Your answer is correct", "yourAnswerCorrect": "Your answer is correct",
"youMissedTheQuestion": "You ran out of time. You are out of the game. But you can continue and as a viewer.", "youMissedTheQuestion": "You ran out of time. You are out of the game. But you can continue as a viewer.",
"wrongAnswer": "Your answer is Incorrect. You are out of the game. But you can continue and as a viewer.", "wrongAnswer": "Your answer is Incorrect. You are out of the game. But you can continue as a viewer.",
"oops": "Ooopsss!!!!", "oops": "Ooopsss!!!!",
"winner": "WINNER", "winner": "WINNER",
"youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.", "youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.",
@ -514,8 +517,12 @@
"startingIn": "Starting in", "startingIn": "Starting in",
"youAreOutOfContest": "You are out of the contest.", "youAreOutOfContest": "You are out of the contest.",
"winners": "WINNERS!!!", "winners": "WINNERS!!!",
"fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.",
"expireAfter":"Expires After", "expireAfter":"Expires After",
"oneWeek":"1 Week", "oneWeek":"1 Week",
"twoWeek":"2 Week" "twoWeek":"2 Week",
"noUpcoming": "There is no upcoming",
"fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.",
"noWinner": "Sad! No one won today.",
"myTeam" : "My Team",
"youCanPlayDemo": "But you can play demo"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,5 +1,7 @@
import UIKit import UIKit
import Flutter import Flutter
import Firebase
@UIApplicationMain @UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate { @objc class AppDelegate: FlutterAppDelegate {
@ -7,6 +9,7 @@ import Flutter
_ application: UIApplication, _ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool { ) -> Bool {
FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self) GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions) return super.application(application, didFinishLaunchingWithOptions: launchOptions)
} }

@ -13,7 +13,7 @@
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>mohem_flutter_app</string> <string>MOHEMM</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
@ -46,10 +46,14 @@
<string>This app requires photo library access to select image as document &amp; upload it.</string> <string>This app requires photo library access to select image as document &amp; upload it.</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access to for call.</string> <string>This app requires microphone access to for call.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to select image as document &amp; upload it.</string>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>remote-notification</string> <string>remote-notification</string>
</array> </array>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>LaunchScreen</string> <string>LaunchScreen</string>
<key>UIMainStoryboardFile</key> <key>UIMainStoryboardFile</key>
@ -69,6 +73,13 @@
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
<array>
<string>0000</string>
</array>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>com.apple.developer.nfc.readersession.formats</key> <key>com.apple.developer.nfc.readersession.formats</key>
<array> <array>
<string>TAG</string> <string>TAG</string>

@ -14,11 +14,16 @@ typedef FactoryConstructor<U> = U Function(dynamic);
class APIError { class APIError {
int? errorCode; int? errorCode;
int? errorType;
String? errorMessage; String? errorMessage;
APIError(this.errorCode, this.errorMessage); APIError(this.errorCode, this.errorMessage, this.errorType);
Map<String, dynamic> toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage}; Map<String, dynamic> toJson() => {
'errorCode': errorCode,
'errorMessage': errorMessage,
'errorType': errorType,
};
@override @override
String toString() { String toString() {
@ -33,14 +38,14 @@ APIException _throwAPIException(Response response) {
if (response.body != null && response.body.isNotEmpty) { if (response.body != null && response.body.isNotEmpty) {
var jsonError = jsonDecode(response.body); var jsonError = jsonDecode(response.body);
print(jsonError); print(jsonError);
apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage']); apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage'], jsonError['ErrorType']);
} }
return APIException(APIException.BAD_REQUEST, error: apiError); return APIException(APIException.BAD_REQUEST, error: apiError);
case 400: case 400:
APIError? apiError; APIError? apiError;
if (response.body != null && response.body.isNotEmpty) { if (response.body != null && response.body.isNotEmpty) {
var jsonError = jsonDecode(response.body); var jsonError = jsonDecode(response.body);
apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage']); apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage'], jsonError['ErrorType']);
} }
return APIException(APIException.BAD_REQUEST, error: apiError); return APIException(APIException.BAD_REQUEST, error: apiError);
case 401: case 401:
@ -78,28 +83,30 @@ class ApiClient {
print("body:$bodyJson"); print("body:$bodyJson");
} }
var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes, isFormData: isFormData); var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes, isFormData: isFormData);
// try { try {
if (!kReleaseMode) { if (!kReleaseMode) {
logger.i("res: " + response.body); logger.i("res: " + response.body);
} }
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
if (jsonData["IsAuthenticated"] != null) { if (jsonData["MessageStatus"] == 2) {
AppState().setIsAuthenticated = jsonData["IsAuthenticated"]; AppState().setIsAuthenticated = false;
} }
if (jsonData["ErrorMessage"] == null) {
return factoryConstructor(jsonData);
} else { if (jsonData["ErrorMessage"] == null && jsonData["MessageStatus"] == 1) {
APIError? apiError; return factoryConstructor(jsonData);
apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorEndUserMessage']); } else {
throw APIException(APIException.BAD_REQUEST, error: apiError); APIError? apiError;
apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorEndUserMessage'], jsonData['ErrorType'] ?? 0);
throw APIException(APIException.BAD_REQUEST, error: apiError);
}
} catch (ex) {
if (ex is APIException) {
rethrow;
} else {
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
}
} }
// } catch (ex) {
// if (ex is APIException) {
// rethrow;
// } else {
// throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
// }
// }
} }
Future<Response> postJsonForResponse<T>(String url, T jsonObject, Future<Response> postJsonForResponse<T>(String url, T jsonObject,

@ -30,11 +30,13 @@ class ChatApiClient {
{ {
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG", "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
"isMobile": true,
"deviceToken": AppState().getDeviceToken,
}, },
); );
if (!kReleaseMode) { if (!kReleaseMode) {
print("Status Code is ================" + response.statusCode.toString()); logger.i("login-res: " + response.body);
logger.i("res: " + response.body);
} }
if (response.statusCode == 200) { if (response.statusCode == 200) {
userLoginResponse = user.userAutoLoginModelFromJson(response.body); userLoginResponse = user.userAutoLoginModelFromJson(response.body);
@ -47,17 +49,18 @@ class ChatApiClient {
return userLoginResponse; return userLoginResponse;
} }
Future<List<ChatUser>?> getChatMemberFromSearch(String sName, int cUserId) async { Future<ChatUserModel> getChatMemberFromSearch(String searchParam, int cUserId, int pageNo) async {
Response response = await ApiClient().getJsonForResponse( ChatUserModel chatUserModel;
"${ApiConsts.chatLoginTokenUrl}getUserWithStatusAndFavAsync/$sName/$cUserId", Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatLoginTokenUrl}getUserWithStatusAndFavAsync", {"employeeNumber": cUserId, "userName": searchParam, "pageNumber": pageNo},
token: AppState().chatDetails!.response!.token, token: AppState().chatDetails!.response!.token);
);
if (!kReleaseMode) { if (!kReleaseMode) {
logger.i("res: " + response.body); logger.i("res: " + response.body);
} }
return List<ChatUser>.from(json.decode(response.body).map((x) => ChatUser.fromJson(x))); chatUserModel = chatUserModelFromJson(response.body);
return chatUserModel;
} }
//Get User Recent Chats
Future<ChatUserModel> getRecentChats() async { Future<ChatUserModel> getRecentChats() async {
try { try {
Response response = await ApiClient().getJsonForResponse( Response response = await ApiClient().getJsonForResponse(
@ -75,6 +78,7 @@ class ChatApiClient {
} }
} }
// Get Favorite Users
Future<ChatUserModel> getFavUsers() async { Future<ChatUserModel> getFavUsers() async {
Response favRes = await ApiClient().getJsonForResponse( Response favRes = await ApiClient().getJsonForResponse(
"${ApiConsts.chatFavUser}getFavUserById/${AppState().chatDetails!.response!.id}", "${ApiConsts.chatFavUser}getFavUserById/${AppState().chatDetails!.response!.id}",
@ -86,6 +90,7 @@ class ChatApiClient {
return ChatUserModel.fromJson(json.decode(favRes.body)); return ChatUserModel.fromJson(json.decode(favRes.body));
} }
//Get User Chat History
Future<Response> getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async { Future<Response> getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async {
try { try {
Response response = await ApiClient().getJsonForResponse( Response response = await ApiClient().getJsonForResponse(
@ -97,10 +102,12 @@ class ChatApiClient {
} }
return response; return response;
} catch (e) { } catch (e) {
getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal);
throw e; throw e;
} }
} }
//Favorite Users
Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async { Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatFavUser}addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token); Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatFavUser}addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
if (!kReleaseMode) { if (!kReleaseMode) {
@ -110,6 +117,7 @@ class ChatApiClient {
return favoriteChatUser; return favoriteChatUser;
} }
//UnFavorite Users
Future<fav.FavoriteChatUser> unFavUser({required int userID, required int targetUserID}) async { Future<fav.FavoriteChatUser> unFavUser({required int userID, required int targetUserID}) async {
try { try {
Response response = await ApiClient().postJsonForResponse( Response response = await ApiClient().postJsonForResponse(
@ -120,7 +128,6 @@ class ChatApiClient {
if (!kReleaseMode) { if (!kReleaseMode) {
logger.i("res: " + response.body); logger.i("res: " + response.body);
} }
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser; return favoriteChatUser;
} catch (e) { } catch (e) {
@ -129,33 +136,37 @@ class ChatApiClient {
} }
} }
Future<StreamedResponse> uploadMedia(String userId, File file) async { // Upload Chat Media
Future<Object?> uploadMedia(String userId, File file) async {
if (kDebugMode) {
print("${ApiConsts.chatMediaImageUploadUrl}upload");
print(AppState().chatDetails!.response!.token);
}
dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatMediaImageUploadUrl}upload')); dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatMediaImageUploadUrl}upload'));
request.fields.addAll({'userId': userId, 'fileSource': '1'}); request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.files.add(await MultipartFile.fromPath('files', file.path)); request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'}); request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
StreamedResponse response = await request.send(); StreamedResponse response = await request.send();
if (!kReleaseMode) {} String data = await response.stream.bytesToString();
return response; if (!kReleaseMode) {
logger.i("res: " + data);
}
return jsonDecode(data);
} }
// Download File For Chat // Download File For Chat
Future<Uint8List> downloadURL({required String fileName, required String fileTypeDescription}) async { Future<Uint8List> downloadURL({required String fileName, required String fileTypeDescription}) async {
print(fileName);
print(fileTypeDescription);
print("${ApiConsts.chatMediaImageUploadUrl}download");
print(AppState().chatDetails!.response!.token);
Response response = await ApiClient().postJsonForResponse( Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatMediaImageUploadUrl}download", "${ApiConsts.chatMediaImageUploadUrl}download",
{"fileType": fileTypeDescription, "fileName": fileName, "fileSource": 1}, {"fileType": fileTypeDescription, "fileName": fileName, "fileSource": 1},
token: AppState().chatDetails!.response!.token, token: AppState().chatDetails!.response!.token,
); );
Uint8List data = Uint8List.fromList(response.bodyBytes); Uint8List data = Uint8List.fromList(response.bodyBytes);
return data; return data;
} }
//Get Chat Users & Favorite Images
Future<List<ChatUserImageModel>> getUsersImages({required List<String> encryptedEmails}) async { Future<List<ChatUserImageModel>> getUsersImages({required List<String> encryptedEmails}) async {
List<ChatUserImageModel> imagesData = []; List<ChatUserImageModel> imagesData = [];
Response response = await ApiClient().postJsonForResponse( Response response = await ApiClient().postJsonForResponse(

@ -32,7 +32,7 @@ class ItemsForSaleApiClient {
getSaleCategoriesListObj.titleAr = "الجميع"; getSaleCategoriesListObj.titleAr = "الجميع";
getSaleCategoriesListObj.isActive = true; getSaleCategoriesListObj.isActive = true;
getSaleCategoriesListObj.content = getSaleCategoriesListObj.content =
'<svg xmlns="http://www.w3.org/2000/svg" width="33.925" height="25.841" viewBox="0 0 33.925 25.841"><g id="More_Select" data-name="More Select"><path d="m30 1h-24a1 1 0 0 0 -1 1v1h21a3 3 0 0 1 3 3v21h1a1 1 0 0 0 1-1v-24a1 1 0 0 0 -1-1z"/><path d="m26 5h-24a1 1 0 0 0 -1 1v24a1 1 0 0 0 1 1h24a1 1 0 0 0 1-1v-24a1 1 0 0 0 -1-1zm-4.747 9.344-8.728 8.726a1 1 0 0 1 -1.414 0l-4.364-4.363a1 1 0 0 1 1.414-1.414l3.657 3.656 8.021-8.019a1 1 0 0 1 1.414 1.414z"/></g></svg>'; '<svg xmlns="http://www.w3.org/2000/svg" width="26.213" height="26.213" viewBox="0 0 26.213 26.213"> <g id="More_Select" data-name="More Select" transform="translate(-1 -1)"> <path id="Path_4860" data-name="Path 4860" d="M26.844,1H5.874A.874.874,0,0,0,5,1.874v.874H23.349A2.621,2.621,0,0,1,25.97,5.369V23.718h.874a.874.874,0,0,0,.874-.874V1.874A.874.874,0,0,0,26.844,1Z" transform="translate(-0.505)" fill="#2bb8a6"/> <path id="Path_4861" data-name="Path 4861" d="M22.844,5H1.874A.874.874,0,0,0,1,5.874v20.97a.874.874,0,0,0,.874.874h20.97a.874.874,0,0,0,.874-.874V5.874A.874.874,0,0,0,22.844,5ZM18.7,13.164,11.07,20.789a.874.874,0,0,1-1.236,0L6.022,16.977a.874.874,0,1,1,1.236-1.236l3.2,3.195,7.008-7.007A.874.874,0,1,1,18.7,13.165Z" transform="translate(0 -0.505)" fill="#125765"/> </g> </svg>';
getSaleCategoriesList.add(getSaleCategoriesListObj); getSaleCategoriesList.add(getSaleCategoriesListObj);

@ -0,0 +1,25 @@
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:logger/logger.dart' as L;
import 'package:mohem_flutter_app/models/marathon/marathon_model.dart';
import 'package:mohem_flutter_app/models/marathon/question_model.dart';
class DemoMarathonRepo {
L.Logger logger = L.Logger();
Future<MarathonDetailModel> getDemoMarathonDetails() async {
String response = await rootBundle.loadString('assets/json/demo_upcoming_marathon');
var json = jsonDecode(response);
MarathonDetailModel marathonDetailModel = MarathonDetailModel.fromJson(json);
return marathonDetailModel;
}
Future<QuestionModel> getDemoNextQuestion({required int currentQuestionNumber}) async {
String response = await rootBundle.loadString('assets/json/demo_questions_marathon');
List json = jsonDecode(response);
QuestionModel currentQuestion = QuestionModel.fromJson(json.elementAt(currentQuestionNumber));
return currentQuestion;
}
}

@ -1,69 +1,58 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:logger/logger.dart' as L; import 'package:logger/logger.dart' as L;
import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/models/marathon/marathon_generic_model.dart'; import 'package:mohem_flutter_app/models/marathon/marathon_generic_model.dart';
import 'package:mohem_flutter_app/models/marathon/marathon_model.dart'; import 'package:mohem_flutter_app/models/marathon/marathon_model.dart';
import 'package:mohem_flutter_app/models/marathon/question_model.dart'; import 'package:mohem_flutter_app/models/marathon/question_model.dart';
import 'package:mohem_flutter_app/models/marathon/winner_model.dart'; import 'package:mohem_flutter_app/models/marathon/winner_model.dart';
import 'package:signalr_netcore/hub_connection.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
import 'package:provider/provider.dart';
class MarathonApiClient { class MarathonApiClient {
late HubConnection hubConnection;
L.Logger logger = L.Logger(); L.Logger logger = L.Logger();
Future<String> getMarathonToken() async { Future<String> getMarathonToken() async {
String employeeUserName = AppState().getUserName ?? ""; String employeeUserName = AppState().getUserName ?? "";
String employeeSession = AppState().postParamsObject?.pSessionId.toString() ?? ""; String employeeSession = AppState().postParamsObject?.pSessionId.toString() ?? "";
Map<String, String> jsonObject = <String, String>{"userName": employeeUserName, "password": employeeSession}; Map<String, String> jsonObject = <String, String>{"userName": employeeUserName, "password": employeeSession};
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonParticipantLoginUrl, jsonObject); return await ApiClient().postJsonForObject(
(json) {
var json = jsonDecode(response.body); MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json);
MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json);
if (marathonModel.statusCode == 200) {
if (marathonModel.data != null && marathonModel.isSuccessful == true) {
AppState().setMarathonToken = marathonModel.data["token"] ?? ""; AppState().setMarathonToken = marathonModel.data["token"] ?? "";
return marathonModel.data["token"] ?? ""; return marathonModel.data["token"] ?? "";
} else { },
//TODO : DO ERROR HANDLING HERE ApiConsts.marathonParticipantLoginUrl,
return ""; jsonObject,
} );
} else {
//TODO : DO ERROR HANDLING HERE
return "";
}
} }
Future<String> getProjectId() async { Future<String> getProjectId() async {
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonProjectGetUrl, <String, dynamic>{}, token: AppState().getMarathonToken ?? await getMarathonToken()); return await ApiClient().postJsonForObject(
(json) {
var json = jsonDecode(response.body); MarathonGenericModel responseData = MarathonGenericModel.fromJson(json);
MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); return responseData.data[0]["id"] ?? "";
},
if (marathonModel.statusCode == 200) { ApiConsts.marathonProjectGetUrl,
if (marathonModel.data != null && marathonModel.isSuccessful == true) { <String, dynamic>{},
logger.i("message: ${marathonModel.data[0]["id"]}"); token: AppState().getMarathonToken == null || AppState().getMarathonToken == "" ? await getMarathonToken() : AppState().getMarathonToken,
AppState().setMarathonProjectId = marathonModel.data[0]["id"] ?? ""; );
return marathonModel.data[0]["id"] ?? "";
} else {
return "";
}
} else {
return "";
}
} }
Future<MarathonDetailModel> getMarathonDetails() async { Future<MarathonDetailModel> getMarathonDetails() async {
String payrollString = AppState().postParamsObject?.payrollCodeStr.toString() ?? "CS"; String payrollString = AppState().postParamsObject?.payrollCodeStr.toString() ?? "CS";
Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonUpcomingUrl + payrollString, token: AppState().getMarathonToken ?? await getMarathonToken()); Response response = await ApiClient().getJsonForResponse(
ApiConsts.marathonUpcomingUrl + payrollString,
token: AppState().getMarathonToken == null || AppState().getMarathonToken == "" ? await getMarathonToken() : AppState().getMarathonToken,
);
var json = jsonDecode(response.body); var json = jsonDecode(response.body);
logger.i("json in getMarathonDetails: $json"); logger.i("json in getMarathonDetails: $json");
@ -89,72 +78,73 @@ class MarathonApiClient {
"marathonId": AppState().getMarathonProjectId!, "marathonId": AppState().getMarathonProjectId!,
}; };
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonJoinParticipantUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); return await ApiClient().postJsonForObject(
(json) {
var json = jsonDecode(response.body); MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json);
MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json);
if (marathonModel.statusCode == 208) {
// means participant is already in the marathon i.e already joined
//TODO: NEED TO LOOK UPON THIS
return marathonModel.data["remainingTime"];
}
if (marathonModel.statusCode == 200) {
if (marathonModel.data != null && marathonModel.isSuccessful == true) {
logger.i("joinMarathonAsParticipant: ${marathonModel.data}");
return marathonModel.data["remainingTime"]; return marathonModel.data["remainingTime"];
} else { },
return null; ApiConsts.marathonJoinParticipantUrl,
} jsonObject,
} else { token: AppState().getMarathonToken == null || AppState().getMarathonToken == "" ? await getMarathonToken() : AppState().getMarathonToken,
return null; );
}
} }
Future<QuestionModel?> getNextQuestion({required String? questionId, required String marathonId}) async { Future<QuestionModel> getNextQuestion({required String? questionId, required String marathonId}) async {
Map<String, String?> jsonObject = <String, String?>{ Map<String, String?> jsonObject = <String, String?>{
"previousQuestionId": questionId, "previousQuestionId": questionId,
"marathonId": marathonId, "marathonId": marathonId,
}; };
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonNextQuestionUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); return await ApiClient().postJsonForObject(
(json) {
var json = jsonDecode(response.body); MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json);
if (marathonModel.statusCode == 404 || marathonModel.statusCode == 208 || marathonModel.statusCode == 204 || marathonModel.statusCode == 500) {
logger.i("json in NextQuestion: $json"); Utils.confirmDialog(
var data = json["data"]; AppRoutes.navigatorKey.currentContext,
marathonModel.message!,
if (data != null) { onTap: () {
QuestionModel newQuestion = QuestionModel.fromJson(data); AppRoutes.navigatorKey.currentContext!.read<MarathonProvider>().resetValues();
return newQuestion; Navigator.of(
} else { AppRoutes.navigatorKey.currentContext!,
return null; ).popUntil(ModalRoute.withName(AppRoutes.dashboard));
} },
);
}
QuestionModel newQuestion = QuestionModel.fromJson(marathonModel.data);
return newQuestion;
},
ApiConsts.marathonNextQuestionUrl,
jsonObject,
token: AppState().getMarathonToken == null || AppState().getMarathonToken == "" ? await getMarathonToken() : AppState().getMarathonToken,
);
} }
Future<bool> submitSelectedOption({required String marathonId, required String? questionId, required String? selectedAnswerId}) async { Future<bool> submitSelectedOption({required String marathonId, required String? questionId, required String? selectedAnswerId}) async {
Map<String, String?> jsonObject = <String, String?>{"marathonId": marathonId, "questionId": questionId, "selectedOptionId" : selectedAnswerId}; Map<String, String?> jsonObject = <String, String?>{"marathonId": marathonId, "questionId": questionId, "selectedOptionId": selectedAnswerId};
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonSubmitAnswerUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); return await ApiClient().postJsonForObject(
(json) {
var json = jsonDecode(response.body); MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json);
logger.i("json in submitSelectedOption : $json"); if (marathonModel.data != null) {
bool isOptionCorrect = marathonModel.data["isCorrect"];
MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); return isOptionCorrect;
}
if (marathonModel.isSuccessful == null) { return false;
return false; },
} ApiConsts.marathonSubmitAnswerUrl,
jsonObject,
return marathonModel.isSuccessful!; token: AppState().getMarathonToken == null || AppState().getMarathonToken == "" ? await getMarathonToken() : AppState().getMarathonToken,
);
} }
Future<int?> getQualifiers({required String marathonId}) async { Future<int?> getQualifiers({required String marathonId}) async {
Map<String, String> params = <String, String>{"marathonId": marathonId}; Map<String, String> params = <String, String>{"marathonId": marathonId};
Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonQualifiersUrl, queryParameters: params, token: AppState().getMarathonToken ?? await getMarathonToken()); Response response = await ApiClient().getJsonForResponse(
ApiConsts.marathonQualifiersUrl,
queryParameters: params,
token: AppState().getMarathonToken == null || AppState().getMarathonToken == "" ? await getMarathonToken() : AppState().getMarathonToken,
);
var json = jsonDecode(response.body); var json = jsonDecode(response.body);
logger.i("json in getQualifiers: $json"); logger.i("json in getQualifiers: $json");
@ -169,7 +159,11 @@ class MarathonApiClient {
Future<List<WinnerModel>?> getSelectedWinner({required String marathonId}) async { Future<List<WinnerModel>?> getSelectedWinner({required String marathonId}) async {
Map<String, String> params = <String, String>{"marathonId": marathonId}; Map<String, String> params = <String, String>{"marathonId": marathonId};
Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonSelectedWinner, queryParameters: params, token: AppState().getMarathonToken ?? await getMarathonToken()); Response response = await ApiClient().getJsonForResponse(
ApiConsts.marathonSelectedWinner,
queryParameters: params,
token: AppState().getMarathonToken == null || AppState().getMarathonToken == "" ? await getMarathonToken() : AppState().getMarathonToken,
);
var json = jsonDecode(response.body); var json = jsonDecode(response.body);
logger.i("json in getSelectedWinner: $json"); logger.i("json in getSelectedWinner: $json");
@ -188,6 +182,7 @@ class MarathonApiClient {
return null; return null;
} }
// late HubConnection hubConnection;
// Future<void> buildHubConnection(BuildContext context, String prizeId) async { // Future<void> buildHubConnection(BuildContext context, String prizeId) async {
// HttpConnectionOptions httpOptions = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); // HttpConnectionOptions httpOptions = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
// hubConnection = HubConnectionBuilder() // hubConnection = HubConnectionBuilder()

@ -30,7 +30,7 @@ class OffersAndDiscountsApiClient {
getSaleCategoriesListObj.categoryNameAr = "الجميع"; getSaleCategoriesListObj.categoryNameAr = "الجميع";
getSaleCategoriesListObj.isActive = true; getSaleCategoriesListObj.isActive = true;
getSaleCategoriesListObj.content = getSaleCategoriesListObj.content =
'<svg xmlns="http://www.w3.org/2000/svg" width="33.925" height="25.841" viewBox="0 0 33.925 25.841"><g id="More_Select" data-name="More Select"><path d="m30 1h-24a1 1 0 0 0 -1 1v1h21a3 3 0 0 1 3 3v21h1a1 1 0 0 0 1-1v-24a1 1 0 0 0 -1-1z"/><path d="m26 5h-24a1 1 0 0 0 -1 1v24a1 1 0 0 0 1 1h24a1 1 0 0 0 1-1v-24a1 1 0 0 0 -1-1zm-4.747 9.344-8.728 8.726a1 1 0 0 1 -1.414 0l-4.364-4.363a1 1 0 0 1 1.414-1.414l3.657 3.656 8.021-8.019a1 1 0 0 1 1.414 1.414z"/></g></svg>'; '<svg xmlns="http://www.w3.org/2000/svg" width="26.213" height="26.213" viewBox="0 0 26.213 26.213"> <g id="More_Select" data-name="More Select" transform="translate(-1 -1)"> <path id="Path_4860" data-name="Path 4860" d="M26.844,1H5.874A.874.874,0,0,0,5,1.874v.874H23.349A2.621,2.621,0,0,1,25.97,5.369V23.718h.874a.874.874,0,0,0,.874-.874V1.874A.874.874,0,0,0,26.844,1Z" transform="translate(-0.505)" fill="#2bb8a6"/> <path id="Path_4861" data-name="Path 4861" d="M22.844,5H1.874A.874.874,0,0,0,1,5.874v20.97a.874.874,0,0,0,.874.874h20.97a.874.874,0,0,0,.874-.874V5.874A.874.874,0,0,0,22.844,5ZM18.7,13.164,11.07,20.789a.874.874,0,0,1-1.236,0L6.022,16.977a.874.874,0,1,1,1.236-1.236l3.2,3.195,7.008-7.007A.874.874,0,1,1,18.7,13.165Z" transform="translate(0 -0.505)" fill="#125765"/> </g> </svg>';
getSaleCategoriesList.add(getSaleCategoriesListObj); getSaleCategoriesList.add(getSaleCategoriesListObj);

File diff suppressed because one or more lines are too long

@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
class ApiConsts { class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server //static String baseUrl = "http://10.200.204.20:2801/"; // Local server
// static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server
static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
// static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";

@ -459,7 +459,7 @@ class DateUtil {
/// get data formatted like 10:30 according to lang /// get data formatted like 10:30 according to lang
static String formatDateToTimeLang(DateTime date, bool isArabic) { static String formatDateToTimeLang(DateTime date, bool isArabic) {
return DateFormat('HH:mm a', isArabic ? "ar_SA" : "en_US").format(date); return DateFormat('hh:mm a', isArabic ? "ar_SA" : "en_US").format(date);
} }
/// get data formatted like 26/4/2020 10:30 /// get data formatted like 26/4/2020 10:30

@ -7,4 +7,6 @@ class MyLottieConsts {
static const String marathonWaiting = "assets/lottie/marathon_waiting.json"; static const String marathonWaiting = "assets/lottie/marathon_waiting.json";
static const String wrongAnswerGif = "assets/images/wrong_answer.gif"; static const String wrongAnswerGif = "assets/images/wrong_answer.gif";
static const String congratsGif = "assets/images/congrats.gif"; static const String congratsGif = "assets/images/congrats.gif";
static const String loadingLottie = "assets/lottie/loading_lottie.json";
static const String noWinnerLottie = "assets/lottie/no_winner.json";
} }

@ -0,0 +1,59 @@
import 'dart:convert';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:permission_handler/permission_handler.dart';
//final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
class AppNotifications {
static final AppNotifications _instance = AppNotifications._internal();
AppNotifications._internal();
factory AppNotifications() => _instance;
// Future<void> requestPermissions() async {
// if (Platform.isIOS) {
// await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true, badge: true, sound: true);
// } else if (Platform.isAndroid) {
// AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>();
// bool? granted = await androidImplementation?.requestPermission();
// if (granted == false) {
// print("-------------------- Permission Granted ------------------------");
// print(granted);
// await Permission.notification.request();
// }
// }
// }
// Future<void> isAndroidPermGranted() async {
// if (Platform.isAndroid) {
// bool granted = await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.areNotificationsEnabled() ?? false;
// }
// }
void initNotification(String? firebaseToken) async {
// await requestPermissions();
AppState().setDeviceToken = firebaseToken;
// await Permission.notification.isDenied.then((value) {
// if (value) {
// Permission.notification.request();
// }
// });
RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) _handleMessage(initialMessage);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) _handleMessage(message);
});
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
}
void _handleMessage(RemoteMessage message) {
print("Handle Message");
logger.w(json.encode(message));
}
}

@ -0,0 +1,59 @@
import 'dart:async';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
// |--> Push Notification Background
Future<dynamic> backgroundMessageHandler(message) async {
print("Firebase backgroundMessageHandler!!!");
}
class PushNotificationHandler {
final BuildContext context;
static PushNotificationHandler? _instance;
PushNotificationHandler(this.context) {
PushNotificationHandler._instance = this;
}
static PushNotificationHandler getInstance() => _instance!;
void init() async {
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
newMessage(message);
});
} else {
newMessage(message);
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
newMessage(message);
});
} else {
newMessage(message);
}
});
FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
print("Push Notification onTokenRefresh: " + fcm_token);
AppState().setDeviceToken = fcm_token;
});
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
}
void newMessage(RemoteMessage remoteMessage) async {
print("Remote Message: " + remoteMessage.data.toString());
if (remoteMessage.data.isEmpty) {
return;
}
}
}

@ -98,43 +98,58 @@ class Utils {
static void handleException(dynamic exception, cxt, Function(String)? onErrorMessage) { static void handleException(dynamic exception, cxt, Function(String)? onErrorMessage) {
String errorMessage; String errorMessage;
if (exception is APIException) { if (exception.error.errorType != null && exception.error.errorType == 4) {
if (exception.message == APIException.UNAUTHORIZED) { Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.appUpdateScreen, (_) => false, arguments: exception.error?.errorMessage);
return; } else {
if (exception is APIException) {
if (exception.message == APIException.UNAUTHORIZED) {
return;
} else {
errorMessage = exception.error?.errorMessage ?? exception.message;
}
} else { } else {
errorMessage = exception.error?.errorMessage ?? exception.message; errorMessage = APIException.UNKNOWN;
} }
} else { if (onErrorMessage != null) {
errorMessage = APIException.UNKNOWN; onErrorMessage(errorMessage);
}
if (onErrorMessage != null) {
onErrorMessage(errorMessage);
} else {
if (!AppState().isAuthenticated) {
showDialog(
context: cxt,
builder: (cxt) => ConfirmDialog(
message: errorMessage,
onTap: () {
Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route<dynamic> route) => false);
},
),
);
} else { } else {
if (cxt != null) { if (!AppState().isAuthenticated) {
confirmDialog(cxt, errorMessage); showDialog(
context: cxt,
builder: (cxt) => ConfirmDialog(
message: errorMessage,
onTap: () {
Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route<dynamic> route) => false);
},
),
);
} else { } else {
showToast(errorMessage); if (cxt != null) {
confirmDialog(cxt, errorMessage);
} else {
showToast(errorMessage);
}
} }
} }
} }
} }
static void confirmDialog(cxt, String message) { static Future showErrorDialog({required BuildContext context, required VoidCallback onOkTapped, required String message}) async {
return showDialog(
context: context,
builder: (BuildContext context) => ConfirmDialog(
message: message,
onTap: onOkTapped,
),
);
}
static void confirmDialog(cxt, String message, {VoidCallback? onTap}) {
showDialog( showDialog(
context: cxt, context: cxt,
builder: (cxt) => ConfirmDialog( builder: (BuildContext cxt) => ConfirmDialog(
message: message, message: message,
onTap: onTap,
), ),
); );
} }
@ -310,17 +325,23 @@ class Utils {
} }
static String formatDateDefault(String date) { static String formatDateDefault(String date) {
if (date.toLowerCase().contains("t")) { if (date.isNotEmpty) {
date = date.toLowerCase().split("t")[0]; if (date.toLowerCase().contains("t")) {
// return DateFormat('yyyy-MM-dd').format(DateFormat('dd-MM-yyyy').parseLoose(date)); date = date.toLowerCase().split("t")[0];
return DateFormat('dd-MM-yyyy').format(DateFormat('yyyy-MM-dd').parseLoose(date)); if (!date.contains("00:00:00")) {
} else { date = date + ' 00:00:00';
if(date.toLowerCase().split("-")[1].length == 3) { }
return DateFormat('dd-MM-yyyy').format(DateFormat('dd-MMM-yyyy').parseLoose(date)); return date;
} else { } else {
return DateFormat('dd-MM-yyyy').format(DateFormat('yyyy-MM-dd').parseLoose(date)); if (date.toLowerCase().split("-")[1].length == 3) {
return DateFormat('dd-MM-yyyy').format(DateFormat('dd-MMM-yyyy').parseLoose(date));
} else {
return DateFormat('dd-MM-yyyy').format(DateFormat('yyyy-MM-dd').parseLoose(date));
}
// return DateFormat('yyyy-MM-dd').format(DateFormat('dd-MM-yyyy').parseLoose(date));
} }
// return DateFormat('yyyy-MM-dd').format(DateFormat('dd-MM-yyyy').parseLoose(date)); } else {
return date;
} }
} }
@ -328,13 +349,13 @@ class Utils {
if (!Platform.isIOS) { if (!Platform.isIOS) {
await showCupertinoModalPopup( await showCupertinoModalPopup(
context: context, context: context,
builder: (cxt) => Container( builder: (BuildContext cxt) => Container(
height: 250, height: 250,
color: Colors.white, color: Colors.white,
child: CupertinoDatePicker( child: CupertinoDatePicker(
backgroundColor: Colors.white, backgroundColor: Colors.white,
mode: CupertinoDatePickerMode.date, mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (value) { onDateTimeChanged: (DateTime value) {
if (value != null && value != selectedDate) { if (value != null && value != selectedDate) {
selectedDate = value; selectedDate = value;
} }
@ -354,7 +375,7 @@ class Utils {
static void readNFc({required Function(String) onRead}) { static void readNFc({required Function(String) onRead}) {
NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
var f; MifareUltralight f;
if (Platform.isAndroid) { if (Platform.isAndroid) {
f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
} else { } else {

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/ui/app_update_screen.dart';
import 'package:mohem_flutter_app/ui/attendance/add_vacation_rule_screen.dart'; import 'package:mohem_flutter_app/ui/attendance/add_vacation_rule_screen.dart';
import 'package:mohem_flutter_app/ui/attendance/monthly_attendance_screen.dart'; import 'package:mohem_flutter_app/ui/attendance/monthly_attendance_screen.dart';
import 'package:mohem_flutter_app/ui/attendance/vacation_rule_screen.dart'; import 'package:mohem_flutter_app/ui/attendance/vacation_rule_screen.dart';
@ -22,7 +23,6 @@ import 'package:mohem_flutter_app/ui/marathon/marathon_intro_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_sponsor_video_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_sponsor_video_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_waiting_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_waiting_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/winner_screen.dart';
import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart'; import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart';
import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart'; import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart';
import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart'; import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart';
@ -191,6 +191,7 @@ class AppRoutes {
static const String marathonWaitingScreen = "/marathonWaitingScreen"; static const String marathonWaitingScreen = "/marathonWaitingScreen";
static const String unsafeDeviceScreen = "/unsafeDeviceScreen"; static const String unsafeDeviceScreen = "/unsafeDeviceScreen";
static const String appUpdateScreen = "/appUpdateScreen";
static final Map<String, WidgetBuilder> routes = { static final Map<String, WidgetBuilder> routes = {
login: (BuildContext context) => LoginScreen(), login: (BuildContext context) => LoginScreen(),
@ -297,10 +298,10 @@ class AppRoutes {
// Marathon // Marathon
marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(), marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(),
marathonScreen: (BuildContext context) => MarathonScreen(), marathonScreen: (BuildContext context) => MarathonScreen(),
marathonWinnerScreen: (BuildContext context) => WinnerScreen(),
marathonSponsorVideoScreen: (BuildContext context) => const SponsorVideoScreen(), marathonSponsorVideoScreen: (BuildContext context) => const SponsorVideoScreen(),
marathonWaitingScreen: (BuildContext context) => const MarathonWaitingScreen(), marathonWaitingScreen: (BuildContext context) => const MarathonWaitingScreen(),
unsafeDeviceScreen: (BuildContext context) => const UnsafeDeviceScreen(), unsafeDeviceScreen: (BuildContext context) => const UnsafeDeviceScreen(),
appUpdateScreen: (BuildContext context) => const AppUpdateScreen(),
}; };
} }

@ -13,6 +13,15 @@ extension CapExtension on String {
String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : ""; String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : "";
} }
extension TrimString on String {
String trimString(int minThreshold) {
if (length > minThreshold) {
return "${substring(0, 10)}...${substring(length - 4, length)}";
}
return this;
}
}
extension EmailValidator on String { extension EmailValidator on String {
Widget get toWidget => Text(this); Widget get toWidget => Text(this);
@ -90,9 +99,9 @@ extension EmailValidator on String {
style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null), style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null),
); );
Widget toText14({Color? color, bool isUnderLine = false, bool isBold = false, FontWeight? weight, int? maxlines, bool isCenter = false}) => Text( Widget toText14({Color? color, bool isUnderLine = false, bool isBold = false, FontWeight? weight, int? maxlines, TextAlign? textAlign, bool isCenter = false}) => Text(
this, this,
textAlign: isCenter ? TextAlign.center : TextAlign.left, textAlign: isCenter ? TextAlign.center : (textAlign ?? TextAlign.left),
maxLines: maxlines, maxLines: maxlines,
style: TextStyle( style: TextStyle(
color: color ?? MyColors.darkTextColor, color: color ?? MyColors.darkTextColor,
@ -131,8 +140,9 @@ extension EmailValidator on String {
style: TextStyle(fontSize: 19, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -1.14), style: TextStyle(fontSize: 19, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -1.14),
); );
Widget toText20({Color? color, bool isBold = false}) => Text( Widget toText20({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this, this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(fontSize: 20, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), style: TextStyle(fontSize: 20, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4),
); );

@ -496,6 +496,7 @@ class CodegenLoader extends AssetLoader{
"gameTime": "وقت اللعب:", "gameTime": "وقت اللعب:",
"joinMarathon": "انضم إلى ماراثون", "joinMarathon": "انضم إلى ماراثون",
"joinDemoMarathon": "انضم إلى الماراثون التجريبي", "joinDemoMarathon": "انضم إلى الماراثون التجريبي",
"demo": "تجريبي",
"minutes": "الدقائق", "minutes": "الدقائق",
"seconds": "ثواني", "seconds": "ثواني",
"note": "ملحوظة:", "note": "ملحوظة:",
@ -505,9 +506,11 @@ class CodegenLoader extends AssetLoader{
"sponsoredBy": "برعاية:", "sponsoredBy": "برعاية:",
"question": "سؤال", "question": "سؤال",
"marathoners": "الماراثون", "marathoners": "الماراثون",
"marathoner": "ماراثونر",
"prize": "جائزة:", "prize": "جائزة:",
"winnerSelection": "اختيار الفائز", "winnerSelection": "اختيار الفائز",
"qualifiers": "تصفيات", "qualifiers": "تصفيات",
"qualifier": "المؤهل",
"getReadyForContest": "استعد للمسابقة القادمة:", "getReadyForContest": "استعد للمسابقة القادمة:",
"winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.", "winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.",
"fingersCrossed": "تشابك الاصابع!!!", "fingersCrossed": "تشابك الاصابع!!!",
@ -530,7 +533,11 @@ class CodegenLoader extends AssetLoader{
"startingIn": "يبدأ في", "startingIn": "يبدأ في",
"youAreOutOfContest": "أنت خارج المسابقة.", "youAreOutOfContest": "أنت خارج المسابقة.",
"winners": "الفائزين!!!", "winners": "الفائزين!!!",
"fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية" "noUpcoming": "لا يوجد قادم",
"fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية",
"noWinner": "حزين! لم يفز أحد اليوم.",
"myTeam": "فريقي",
"youCanPlayDemo": "لكن يمكنك لعب العرض"
}; };
static const Map<String,dynamic> en_US = { static const Map<String,dynamic> en_US = {
"mohemm": "Mohemm", "mohemm": "Mohemm",
@ -1003,6 +1010,7 @@ static const Map<String,dynamic> en_US = {
"gameTime": "Game Time:", "gameTime": "Game Time:",
"joinMarathon": "Join Marathon", "joinMarathon": "Join Marathon",
"joinDemoMarathon": "Join Demo Marathon", "joinDemoMarathon": "Join Demo Marathon",
"demo": "Demo",
"minutes": "Minutes", "minutes": "Minutes",
"seconds": "Seconds", "seconds": "Seconds",
"note": "Note:", "note": "Note:",
@ -1012,6 +1020,7 @@ static const Map<String,dynamic> en_US = {
"sponsoredBy": "Sponsored By:", "sponsoredBy": "Sponsored By:",
"question": "Question", "question": "Question",
"marathoners": "Marathoners", "marathoners": "Marathoners",
"marathoner": "Marathoner",
"prize": "Prize:", "prize": "Prize:",
"advancedSearch": "Advanced Search", "advancedSearch": "Advanced Search",
"openNot": "Open Notifications", "openNot": "Open Notifications",
@ -1026,6 +1035,7 @@ static const Map<String,dynamic> en_US = {
"none": "None", "none": "None",
"winnerSelection": "Winner Selection", "winnerSelection": "Winner Selection",
"qualifiers": "Qualifiers", "qualifiers": "Qualifiers",
"qualifier": "Qualifier",
"getReadyForContest": "Get Ready for the coming contest:", "getReadyForContest": "Get Ready for the coming contest:",
"winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.", "winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.",
"fingersCrossed": "Fingers Crossed!!!", "fingersCrossed": "Fingers Crossed!!!",
@ -1039,8 +1049,8 @@ static const Map<String,dynamic> en_US = {
"favorite": "My Favorites", "favorite": "My Favorites",
"searchfromchat": "Search from chat", "searchfromchat": "Search from chat",
"yourAnswerCorrect": "Your answer is correct", "yourAnswerCorrect": "Your answer is correct",
"youMissedTheQuestion": "You ran out of time. You are out of the game. But you can continue and as a viewer.", "youMissedTheQuestion": "You ran out of time. You are out of the game. But you can continue as a viewer.",
"wrongAnswer": "Your answer is Incorrect. You are out of the game. But you can continue and as a viewer.", "wrongAnswer": "Your answer is Incorrect. You are out of the game. But you can continue as a viewer.",
"oops": "Ooopsss!!!!", "oops": "Ooopsss!!!!",
"winner": "WINNER", "winner": "WINNER",
"youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.", "youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.",
@ -1048,7 +1058,11 @@ static const Map<String,dynamic> en_US = {
"startingIn": "Starting in", "startingIn": "Starting in",
"youAreOutOfContest": "You are out of the contest.", "youAreOutOfContest": "You are out of the contest.",
"winners": "WINNERS!!!", "winners": "WINNERS!!!",
"fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified." "noUpcoming": "There is no upcoming",
"fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.",
"noWinner": "Sad! No one won today.",
"myTeam": "My Team",
"youCanPlayDemo": "But you can play demo"
}; };
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
} }

@ -466,6 +466,7 @@ abstract class LocaleKeys {
static const gameTime = 'gameTime'; static const gameTime = 'gameTime';
static const joinMarathon = 'joinMarathon'; static const joinMarathon = 'joinMarathon';
static const joinDemoMarathon = 'joinDemoMarathon'; static const joinDemoMarathon = 'joinDemoMarathon';
static const demo = 'demo';
static const minutes = 'minutes'; static const minutes = 'minutes';
static const seconds = 'seconds'; static const seconds = 'seconds';
static const note = 'note'; static const note = 'note';
@ -475,9 +476,11 @@ abstract class LocaleKeys {
static const sponsoredBy = 'sponsoredBy'; static const sponsoredBy = 'sponsoredBy';
static const question = 'question'; static const question = 'question';
static const marathoners = 'marathoners'; static const marathoners = 'marathoners';
static const marathoner = 'marathoner';
static const prize = 'prize'; static const prize = 'prize';
static const winnerSelection = 'winnerSelection'; static const winnerSelection = 'winnerSelection';
static const qualifiers = 'qualifiers'; static const qualifiers = 'qualifiers';
static const qualifier = 'qualifier';
static const getReadyForContest = 'getReadyForContest'; static const getReadyForContest = 'getReadyForContest';
static const winnerSelectedRandomly = 'winnerSelectedRandomly'; static const winnerSelectedRandomly = 'winnerSelectedRandomly';
static const fingersCrossed = 'fingersCrossed'; static const fingersCrossed = 'fingersCrossed';
@ -500,8 +503,12 @@ abstract class LocaleKeys {
static const startingIn = 'startingIn'; static const startingIn = 'startingIn';
static const youAreOutOfContest = 'youAreOutOfContest'; static const youAreOutOfContest = 'youAreOutOfContest';
static const winners = 'winners'; static const winners = 'winners';
static const noUpcoming = 'noUpcoming';
static const fakeLocation = 'fakeLocation'; static const fakeLocation = 'fakeLocation';
static const expireAfter = 'expireAfter'; static const expireAfter = 'expireAfter';
static const oneWeek = 'oneWeek'; static const oneWeek = 'oneWeek';
static const twoWeek = 'twoWeek'; static const twoWeek = 'twoWeek';
static const noWinner = 'noWinner';
static const myTeam = 'myTeam';
static const youCanPlayDemo = 'youCanPlayDemo';
} }

@ -27,6 +27,7 @@ Logger logger = Logger(
// output: null, // U // output: null, // U
); );
class MyHttpOverrides extends HttpOverrides { class MyHttpOverrides extends HttpOverrides {
@override @override
HttpClient createHttpClient(SecurityContext? context) { HttpClient createHttpClient(SecurityContext? context) {

@ -1,5 +1,10 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
ChatUserModel chatUserModelFromJson(String str) => ChatUserModel.fromJson(json.decode(str));
String chatUserModelToJson(ChatUserModel data) => json.encode(data.toJson());
class ChatUserModel { class ChatUserModel {
ChatUserModel({ ChatUserModel({
this.response, this.response,
@ -7,16 +12,40 @@ class ChatUserModel {
}); });
List<ChatUser>? response; List<ChatUser>? response;
dynamic errorResponses; List<ErrorResponse>? errorResponses;
factory ChatUserModel.fromJson(Map<String, dynamic> json) => ChatUserModel( factory ChatUserModel.fromJson(Map<String, dynamic> json) => ChatUserModel(
response: json["response"] == null ? null : List<ChatUser>.from(json["response"].map((x) => ChatUser.fromJson(x))), response: json["response"] == null ? null : List<ChatUser>.from(json["response"].map((x) => ChatUser.fromJson(x))),
errorResponses: json["errorResponses"], errorResponses: json["errorResponses"] == null ? null : List<ErrorResponse>.from(json["errorResponses"].map((x) => ErrorResponse.fromJson(x))),
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"response": response == null ? null : List<dynamic>.from(response!.map((x) => x.toJson())), "response": response == null ? null : List<dynamic>.from(response!.map((x) => x.toJson())),
"errorResponses": errorResponses, "errorResponses": errorResponses == null ? null : List<dynamic>.from(errorResponses!.map((x) => x.toJson())),
};
}
class ErrorResponse {
ErrorResponse({
this.fieldName,
this.message,
});
dynamic? fieldName;
String? message;
factory ErrorResponse.fromRawJson(String str) => ErrorResponse.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory ErrorResponse.fromJson(Map<String, dynamic> json) => ErrorResponse(
fieldName: json["fieldName"],
message: json["message"] == null ? null : json["message"],
);
Map<String, dynamic> toJson() => {
"fieldName": fieldName,
"message": message == null ? null : message,
}; };
} }
@ -34,6 +63,8 @@ class ChatUser {
this.isPin, this.isPin,
this.isFav, this.isFav,
this.isAdmin, this.isAdmin,
this.rKey,
this.totalCount,
this.isTyping, this.isTyping,
this.isImageLoaded, this.isImageLoaded,
this.isImageLoading, this.isImageLoading,
@ -44,7 +75,7 @@ class ChatUser {
String? userName; String? userName;
String? email; String? email;
dynamic? phone; dynamic? phone;
dynamic? title; String? title;
int? userStatus; int? userStatus;
dynamic? image; dynamic? image;
int? unreadMessageCount; int? unreadMessageCount;
@ -52,17 +83,23 @@ class ChatUser {
bool? isPin; bool? isPin;
bool? isFav; bool? isFav;
bool? isAdmin; bool? isAdmin;
dynamic? rKey;
int? totalCount;
bool? isTyping; bool? isTyping;
bool? isImageLoaded; bool? isImageLoaded;
bool? isImageLoading; bool? isImageLoading;
File? userLocalDownlaodedImage; File? userLocalDownlaodedImage;
factory ChatUser.fromRawJson(String str) => ChatUser.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory ChatUser.fromJson(Map<String, dynamic> json) => ChatUser( factory ChatUser.fromJson(Map<String, dynamic> json) => ChatUser(
id: json["id"] == null ? null : json["id"], id: json["id"] == null ? null : json["id"],
userName: json["userName"] == null ? null : json["userName"], userName: json["userName"] == null ? null : json["userName"],
email: json["email"] == null ? null : json["email"], email: json["email"] == null ? null : json["email"],
phone: json["phone"], phone: json["phone"],
title: json["title"], title: json["title"] == null ? null : json["title"],
userStatus: json["userStatus"] == null ? null : json["userStatus"], userStatus: json["userStatus"] == null ? null : json["userStatus"],
image: json["image"], image: json["image"],
unreadMessageCount: json["unreadMessageCount"] == null ? null : json["unreadMessageCount"], unreadMessageCount: json["unreadMessageCount"] == null ? null : json["unreadMessageCount"],
@ -70,6 +107,8 @@ class ChatUser {
isPin: json["isPin"] == null ? null : json["isPin"], isPin: json["isPin"] == null ? null : json["isPin"],
isFav: json["isFav"] == null ? null : json["isFav"], isFav: json["isFav"] == null ? null : json["isFav"],
isAdmin: json["isAdmin"] == null ? null : json["isAdmin"], isAdmin: json["isAdmin"] == null ? null : json["isAdmin"],
rKey: json["rKey"],
totalCount: json["totalCount"] == null ? null : json["totalCount"],
isTyping: false, isTyping: false,
isImageLoaded: false, isImageLoaded: false,
isImageLoading: true, isImageLoading: true,
@ -80,7 +119,7 @@ class ChatUser {
"userName": userName == null ? null : userName, "userName": userName == null ? null : userName,
"email": email == null ? null : email, "email": email == null ? null : email,
"phone": phone, "phone": phone,
"title": title, "title": title == null ? null : title,
"userStatus": userStatus == null ? null : userStatus, "userStatus": userStatus == null ? null : userStatus,
"image": image, "image": image,
"unreadMessageCount": unreadMessageCount == null ? null : unreadMessageCount, "unreadMessageCount": unreadMessageCount == null ? null : unreadMessageCount,
@ -88,5 +127,7 @@ class ChatUser {
"isPin": isPin == null ? null : isPin, "isPin": isPin == null ? null : isPin,
"isFav": isFav == null ? null : isFav, "isFav": isFav == null ? null : isFav,
"isAdmin": isAdmin == null ? null : isAdmin, "isAdmin": isAdmin == null ? null : isAdmin,
"rKey": rKey,
"totalCount": totalCount == null ? null : totalCount,
}; };
} }

@ -1,7 +1,8 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:just_audio/just_audio.dart';
List<SingleUserChatModel> singleUserChatModelFromJson(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x))); List<SingleUserChatModel> singleUserChatModelFromJson(String str) => List<SingleUserChatModel>.from(json.decode(str).map((x) => SingleUserChatModel.fromJson(x)));
@ -32,7 +33,9 @@ class SingleUserChatModel {
this.userChatReplyResponse, this.userChatReplyResponse,
this.isReplied, this.isReplied,
this.isImageLoaded, this.isImageLoaded,
this.image}); this.image,
this.voice,
this.voiceController});
int? userChatHistoryId; int? userChatHistoryId;
int? userChatHistoryLineId; int? userChatHistoryLineId;
@ -58,6 +61,8 @@ class SingleUserChatModel {
bool? isReplied; bool? isReplied;
bool? isImageLoaded; bool? isImageLoaded;
Uint8List? image; Uint8List? image;
File? voice;
AudioPlayer? voiceController;
factory SingleUserChatModel.fromJson(Map<String, dynamic> json) => SingleUserChatModel( factory SingleUserChatModel.fromJson(Map<String, dynamic> json) => SingleUserChatModel(
userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"], userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"],
@ -83,7 +88,9 @@ class SingleUserChatModel {
userChatReplyResponse: json["userChatReplyResponse"] == null ? null : UserChatReplyResponse.fromJson(json["userChatReplyResponse"]), userChatReplyResponse: json["userChatReplyResponse"] == null ? null : UserChatReplyResponse.fromJson(json["userChatReplyResponse"]),
isReplied: false, isReplied: false,
isImageLoaded: false, isImageLoaded: false,
image: null); image: null,
voice: null,
voiceController: json["fileTypeId"] == 13 ? AudioPlayer() : null);
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId, "userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId,
@ -143,19 +150,19 @@ class FileTypeResponse {
} }
class UserChatReplyResponse { class UserChatReplyResponse {
UserChatReplyResponse({ UserChatReplyResponse(
this.userChatHistoryId, {this.userChatHistoryId,
this.chatEventId, this.chatEventId,
this.contant, this.contant,
this.contantNo, this.contantNo,
this.fileTypeId, this.fileTypeId,
this.createdDate, this.createdDate,
this.targetUserId, this.targetUserId,
this.targetUserName, this.targetUserName,
this.fileTypeResponse, this.fileTypeResponse,
this.isImageLoaded, this.isImageLoaded,
this.image, this.image,
}); this.voice});
int? userChatHistoryId; int? userChatHistoryId;
int? chatEventId; int? chatEventId;
@ -168,19 +175,22 @@ class UserChatReplyResponse {
FileTypeResponse? fileTypeResponse; FileTypeResponse? fileTypeResponse;
bool? isImageLoaded; bool? isImageLoaded;
Uint8List? image; Uint8List? image;
Uint8List? voice;
factory UserChatReplyResponse.fromJson(Map<String, dynamic> json) => UserChatReplyResponse( factory UserChatReplyResponse.fromJson(Map<String, dynamic> json) => UserChatReplyResponse(
userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"], userChatHistoryId: json["userChatHistoryId"] == null ? null : json["userChatHistoryId"],
chatEventId: json["chatEventId"] == null ? null : json["chatEventId"], chatEventId: json["chatEventId"] == null ? null : json["chatEventId"],
contant: json["contant"] == null ? null : json["contant"], contant: json["contant"] == null ? null : json["contant"],
contantNo: json["contantNo"] == null ? null : json["contantNo"], contantNo: json["contantNo"] == null ? null : json["contantNo"],
fileTypeId: json["fileTypeId"], fileTypeId: json["fileTypeId"],
createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]), createdDate: json["createdDate"] == null ? null : DateTime.parse(json["createdDate"]),
targetUserId: json["targetUserId"] == null ? null : json["targetUserId"], targetUserId: json["targetUserId"] == null ? null : json["targetUserId"],
targetUserName: json["targetUserName"] == null ? null : json["targetUserName"], targetUserName: json["targetUserName"] == null ? null : json["targetUserName"],
fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]), fileTypeResponse: json["fileTypeResponse"] == null ? null : FileTypeResponse.fromJson(json["fileTypeResponse"]),
isImageLoaded: false, isImageLoaded: false,
image: null); image: null,
voice: null,
);
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId, "userChatHistoryId": userChatHistoryId == null ? null : userChatHistoryId,

@ -16,25 +16,28 @@ class MarathonDetailModel {
List<Sponsors>? sponsors; List<Sponsors>? sponsors;
List<Questions>? questions; List<Questions>? questions;
int? totalQuestions; int? totalQuestions;
int? marathonBufferTime;
MarathonDetailModel(
{id, MarathonDetailModel({
titleEn, id,
titleAr, titleEn,
descEn, titleAr,
descAr, descEn,
winDeciderTime, descAr,
winnersCount, winDeciderTime,
questGapTime, winnersCount,
startTime, questGapTime,
endTime, startTime,
marathoneStatusId, endTime,
scheduleTime, marathoneStatusId,
selectedLanguage, scheduleTime,
projects, selectedLanguage,
sponsors, projects,
questions, sponsors,
totalQuestions}); questions,
totalQuestions,
marathonBufferTime,
});
MarathonDetailModel.fromJson(Map<String, dynamic> json) { MarathonDetailModel.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
@ -50,22 +53,21 @@ class MarathonDetailModel {
marathoneStatusId = json['marathoneStatusId']; marathoneStatusId = json['marathoneStatusId'];
scheduleTime = json['scheduleTime']; scheduleTime = json['scheduleTime'];
selectedLanguage = json['selectedLanguage']; selectedLanguage = json['selectedLanguage'];
projects = json['projects'] != null projects = json['projects'] != null ? Projects.fromJson(json['projects']) : null;
? Projects.fromJson(json['projects'])
: null;
if (json['sponsors'] != null) { if (json['sponsors'] != null) {
sponsors = <Sponsors>[]; sponsors = <Sponsors>[];
json['sponsors'].forEach((v) { json['sponsors'].forEach((v) {
sponsors!.add( Sponsors.fromJson(v)); sponsors!.add(Sponsors.fromJson(v));
}); });
} }
if (json['questions'] != null) { if (json['questions'] != null) {
questions = <Questions>[]; questions = <Questions>[];
json['questions'].forEach((v) { json['questions'].forEach((v) {
questions!.add( Questions.fromJson(v)); questions!.add(Questions.fromJson(v));
}); });
} }
totalQuestions = json["totalQuestions"]; totalQuestions = json["totalQuestions"];
marathonBufferTime = json["marathonBufferTime"];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -93,6 +95,7 @@ class MarathonDetailModel {
data['questions'] = questions!.map((v) => v.toJson()).toList(); data['questions'] = questions!.map((v) => v.toJson()).toList();
} }
data['totalQuestions'] = totalQuestions; data['totalQuestions'] = totalQuestions;
data['marathonBufferTime'] = marathonBufferTime;
return data; return data;
} }
@ -132,14 +135,7 @@ class Sponsors {
String? logo; String? logo;
List<SponsorPrizes>? sponsorPrizes; List<SponsorPrizes>? sponsorPrizes;
Sponsors( Sponsors({id, nameEn, nameAr, image, video, logo, sponsorPrizes});
{id,
nameEn,
nameAr,
image,
video,
logo,
sponsorPrizes});
Sponsors.fromJson(Map<String, dynamic> json) { Sponsors.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
@ -151,13 +147,13 @@ class Sponsors {
if (json['sponsorPrizes'] != null) { if (json['sponsorPrizes'] != null) {
sponsorPrizes = <SponsorPrizes>[]; sponsorPrizes = <SponsorPrizes>[];
json['sponsorPrizes'].forEach((v) { json['sponsorPrizes'].forEach((v) {
sponsorPrizes!.add( SponsorPrizes.fromJson(v)); sponsorPrizes!.add(SponsorPrizes.fromJson(v));
}); });
} }
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
Map<String, dynamic> data = <String, dynamic>{}; Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id; data['id'] = id;
data['nameEn'] = nameEn; data['nameEn'] = nameEn;
data['nameAr'] = nameAr; data['nameAr'] = nameAr;
@ -165,8 +161,7 @@ class Sponsors {
data['video'] = video; data['video'] = video;
data['logo'] = logo; data['logo'] = logo;
if (sponsorPrizes != null) { if (sponsorPrizes != null) {
data['sponsorPrizes'] = data['sponsorPrizes'] = sponsorPrizes!.map((v) => v.toJson()).toList();
sponsorPrizes!.map((v) => v.toJson()).toList();
} }
return data; return data;
} }
@ -186,7 +181,7 @@ class SponsorPrizes {
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
Map<String, dynamic> data = <String, dynamic>{}; Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id; data['id'] = id;
data['marathonPrizeEn'] = marathonPrizeEn; data['marathonPrizeEn'] = marathonPrizeEn;
data['marathonPrizeAr'] = marathonPrizeAr; data['marathonPrizeAr'] = marathonPrizeAr;
@ -208,19 +203,7 @@ class Questions {
int? questOptionsLimit; int? questOptionsLimit;
List? questionOptions; List? questionOptions;
Questions( Questions({id, titleEn, titleAr, marathonId, questionTypeId, questionTime, nextQuestGap, gapType, gapValue, gapImage, questOptionsLimit, questionOptions});
{id,
titleEn,
titleAr,
marathonId,
questionTypeId,
questionTime,
nextQuestGap,
gapType,
gapValue,
gapImage,
questOptionsLimit,
questionOptions});
Questions.fromJson(Map<String, dynamic> json) { Questions.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];

@ -51,6 +51,7 @@ class QuestionModel {
json['questionOptions'].forEach((v) { json['questionOptions'].forEach((v) {
questionOptions!.add(QuestionOptions.fromJson(v)); questionOptions!.add(QuestionOptions.fromJson(v));
}); });
questionOptions!.sort((QuestionOptions a, QuestionOptions b) => a.sequence!.compareTo(b.sequence!));
} }
} }

@ -8,16 +8,16 @@ class UpdateUserTypesList {
UpdateUserTypesList.fromJson(Map<String, dynamic> json) { UpdateUserTypesList.fromJson(Map<String, dynamic> json) {
itemID = json['ItemID']; itemID = json['ItemID'];
pFYAENABLEDFALG = json['P_FYAENABLED_FALG']; pFYAENABLEDFALG = json['P_FYA_ENABLED_FALG'];
pFYIENABLEDFALG = json['P_FYIENABLED_FALG']; pFYIENABLEDFALG = json['P_FYI_ENABLED_FLAG'];
pITEMTYPE = json['P_ITEM_TYPE']; pITEMTYPE = json['P_ITEM_TYPE'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>(); Map<String, dynamic> data = new Map<String, dynamic>();
data['ItemID'] = this.itemID; data['ItemID'] = this.itemID;
data['P_FYAENABLED_FALG'] = this.pFYAENABLEDFALG; data['P_FYA_ENABLED_FALG'] = this.pFYAENABLEDFALG;
data['P_FYIENABLED_FALG'] = this.pFYIENABLEDFALG; data['P_FYI_ENABLED_FLAG'] = this.pFYIENABLEDFALG;
data['P_ITEM_TYPE'] = this.pITEMTYPE; data['P_ITEM_TYPE'] = this.pITEMTYPE;
return data; return data;
} }

File diff suppressed because it is too large Load Diff

@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart'; import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
@ -35,8 +36,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
bool isWorkListLoading = true; bool isWorkListLoading = true;
int workListCounter = 0; int workListCounter = 0;
//Misssing Swipe //Misssing Swipe
bool isMissingSwipeLoading = true; bool isMissingSwipeLoading = true;
int missingSwipeCounter = 0; int missingSwipeCounter = 0;
@ -94,7 +93,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
accrualList = null; accrualList = null;
leaveBalanceAccrual = null; leaveBalanceAccrual = null;
ticketBalance = 0; ticketBalance = 0;
isServicesMenusLoading = true; isServicesMenusLoading = true;
homeMenus = null; homeMenus = null;
@ -107,7 +105,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
DrawerMenuItem("assets/images/drawer/performance_evaluation.svg", LocaleKeys.performanceEvaluation.tr(), AppRoutes.performanceEvaluation), DrawerMenuItem("assets/images/drawer/performance_evaluation.svg", LocaleKeys.performanceEvaluation.tr(), AppRoutes.performanceEvaluation),
DrawerMenuItem("assets/images/drawer/mowadhafi.svg", LocaleKeys.mowadhafhi.tr(), AppRoutes.mowadhafhi), DrawerMenuItem("assets/images/drawer/mowadhafi.svg", LocaleKeys.mowadhafhi.tr(), AppRoutes.mowadhafhi),
DrawerMenuItem("assets/images/drawer/pending_trasactions.svg", LocaleKeys.pendingTransactions.tr(), AppRoutes.pendingTransactions), DrawerMenuItem("assets/images/drawer/pending_trasactions.svg", LocaleKeys.pendingTransactions.tr(), AppRoutes.pendingTransactions),
DrawerMenuItem("assets/images/drawer/drawer_marathon.svg", LocaleKeys.brainMarathon.tr(), AppRoutes.marathonIntroScreen), // DrawerMenuItem("assets/images/drawer/drawer_marathon.svg", LocaleKeys.brainMarathon.tr(), AppRoutes.marathonIntroScreen),
DrawerMenuItem("assets/images/drawer/change_password.svg", LocaleKeys.changePassword.tr(), AppRoutes.changePassword), DrawerMenuItem("assets/images/drawer/change_password.svg", LocaleKeys.changePassword.tr(), AppRoutes.changePassword),
]; ];
@ -215,6 +213,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} }
List findMyTeam = menuList.where((element) => element.menuType == "M").toList(); List findMyTeam = menuList.where((element) => element.menuType == "M").toList();
if (findMyTeam.isNotEmpty) { if (findMyTeam.isNotEmpty) {
AppState().setempStatusIsManager = true;
drawerMenuItemList.insert(2, DrawerMenuItem("assets/images/drawer/my_team.svg", LocaleKeys.myTeamMembers.tr(), AppRoutes.myTeam)); drawerMenuItemList.insert(2, DrawerMenuItem("assets/images/drawer/my_team.svg", LocaleKeys.myTeamMembers.tr(), AppRoutes.myTeam));
} }
} catch (ex) { } catch (ex) {
@ -245,7 +244,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void getCategoryOffersListAPI(BuildContext context) async { void getCategoryOffersListAPI(BuildContext context) async {
try { try {
// Utils.showLoading(context); // Utils.showLoading(context);
getOffersList = await OffersAndDiscountsApiClient().getOffersList(0, 6); getOffersList = await OffersAndDiscountsApiClient().getOffersList(0, 10);
isOffersLoading = false; isOffersLoading = false;
notifyListeners(); notifyListeners();
} catch (ex) { } catch (ex) {

@ -0,0 +1,56 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:url_launcher/url_launcher.dart';
class AppUpdateScreen extends StatefulWidget {
const AppUpdateScreen({Key? key}) : super(key: key);
@override
State<AppUpdateScreen> createState() => _UnsafeDeviceScreenState();
}
class _UnsafeDeviceScreenState extends State<AppUpdateScreen> {
String? dynamicParams;
@override
Widget build(BuildContext context) {
dynamicParams ??= ModalRoute.of(context)!.settings.arguments as String;
return Scaffold(
body: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
21.height,
Center(child: Image.asset("assets/images/logos/main_mohemm_logo.png", width: 200, height: 50)),
50.height,
"Please Update Your App".toText24(isBold: true),
48.height,
dynamicParams.toString().toText14(isCenter: true).paddingOnly(left: 20.0, right: 20.0),
21.height,
DefaultButton(LocaleKeys.ok.tr(), () async {
if (Platform.isAndroid || Platform.isIOS) {
var appId = Platform.isAndroid ? 'hmg.cloudSolutions.mohem' : '1468856602';
var url = Uri.parse(
Platform.isAndroid ? "market://details?id=$appId" : "https://apps.apple.com/app/id$appId",
);
launchUrl(
url,
mode: LaunchMode.externalApplication,
);
}
}).paddingAll(24)
],
),
),
);
}
}

@ -85,8 +85,8 @@ class _MonthlyAttendanceScreenState extends State<MonthlyAttendanceScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Map<String, double> dataMap = { Map<String, double> dataMap = {
"Present": getTimeCardSummaryList?.aTTENDEDDAYS?.toDouble() ?? 75, "Present": getTimeCardSummaryList?.aTTENDEDDAYS?.toDouble() ?? 0,
"Absent": getTimeCardSummaryList?.aBSENTDAYS?.toDouble() ?? 25, "Absent": getTimeCardSummaryList?.aBSENTDAYS?.toDouble() ?? 0,
}; };
return Scaffold( return Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
@ -112,7 +112,8 @@ class _MonthlyAttendanceScreenState extends State<MonthlyAttendanceScreen> {
], ],
).onPress(() async { ).onPress(() async {
showMonthPicker( showMonthPicker(
context: context, //locale: EasyLocalization.of(context)?.locale, context: context,
//locale: EasyLocalization.of(context)?.locale,
initialDate: formattedDate, initialDate: formattedDate,
firstDate: DateTime(searchYear - 2), firstDate: DateTime(searchYear - 2),
lastDate: DateTime.now(), lastDate: DateTime.now(),
@ -419,211 +420,211 @@ class _MonthlyAttendanceScreenState extends State<MonthlyAttendanceScreen> {
} }
if (details.date!.month == formattedDate.month && details.date!.year == formattedDate.year) { if (details.date!.month == formattedDate.month && details.date!.year == formattedDate.year) {
int val = details.date!.day; int val = details.date!.day;
getDayHoursTypeDetailsList?[val - 1].aTTENDEDFLAG == 'Y' ? getDayHoursTypeDetailsList?[val - 1].aTTENDEDFLAG == 'Y'
showModalBottomSheet( ? showModalBottomSheet(
context: context, context: context,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
isScrollControlled: true, isScrollControlled: true,
backgroundColor: MyColors.backgroundBlackColor, backgroundColor: MyColors.backgroundBlackColor,
builder: (_) { builder: (_) {
return DraggableScrollableSheet( return DraggableScrollableSheet(
maxChildSize: 0.9, maxChildSize: 0.9,
expand: false, expand: false,
builder: (_, controller) { builder: (_, controller) {
dynamic dmyString = getScheduleShiftsDetailsList!.sCHEDULEDATE; dynamic dmyString = getScheduleShiftsDetailsList!.sCHEDULEDATE;
DateTime dateTime1 = DateFormat("MM/dd/yyyy hh:mm:ss").parse(dmyString); DateTime dateTime1 = DateFormat("MM/dd/yyyy hh:mm:ss").parse(dmyString);
return Column( return Column(
children: [ children: [
Container( Container(
width: 49, width: 49,
height: 7, height: 7,
margin: const EdgeInsets.symmetric(vertical: 10), margin: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25), borderRadius: BorderRadius.circular(25),
color: MyColors.darkGreyColor, color: MyColors.darkGreyColor,
), ),
), ),
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
controller: controller, controller: controller,
itemCount: 1, itemCount: 1,
itemBuilder: (_, i) => itemBuilder: (_, i) => Container(
Container( decoration: const BoxDecoration(
decoration: const BoxDecoration( borderRadius: BorderRadius.vertical(
borderRadius: BorderRadius.vertical( top: Radius.circular(25.0),
top: Radius.circular(25.0), ),
color: MyColors.backgroundBlackColor,
), ),
color: MyColors.backgroundBlackColor, child: Column(
), children: [
child: Column( Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
Column( children: [
crossAxisAlignment: CrossAxisAlignment.start, "${DateFormat("MMMM-dd-yyyy").format(dateTime1).replaceAll('-', " ")}".toText24(isBold: true, color: Colors.white),
children: [ LocaleKeys.attendanceDetails.tr().toText16(color: MyColors.greyACColor),
"${DateFormat("MMMM-dd-yyyy").format(dateTime1).replaceAll('-', " ")}".toText24(isBold: true, color: Colors.white), 12.height,
LocaleKeys.attendanceDetails.tr().toText16(color: MyColors.greyACColor), CircularStepProgressBar(
12.height, totalSteps: 16 * 4,
CircularStepProgressBar( currentStep: percentage,
totalSteps: 16 * 4, width: 224,
currentStep: percentage, height: 236,
width: 224, selectedColor: MyColors.gradiantEndColor,
height: 236, unselectedColor: MyColors.grey70Color,
selectedColor: MyColors.gradiantEndColor, child: Column(
unselectedColor: MyColors.grey70Color, mainAxisSize: MainAxisSize.min,
child: Column( children: [
mainAxisSize: MainAxisSize.min, "${getScheduleShiftsDetailsList!.pERCENTAGE}".toText44(color: Colors.white, isBold: true),
children: [ LocaleKeys.completed.tr().toText11(color: MyColors.greyACColor),
"${getScheduleShiftsDetailsList!.pERCENTAGE}".toText44(color: Colors.white, isBold: true), 28.height,
LocaleKeys.completed.tr().toText11(color: MyColors.greyACColor), LocaleKeys.shiftTime.tr().toText11(color: MyColors.greyACColor),
28.height, "${getScheduleShiftsDetailsList!.sHTNAME}".toText22(color: Colors.white, isBold: true),
LocaleKeys.shiftTime.tr().toText11(color: MyColors.greyACColor), ],
"${getScheduleShiftsDetailsList!.sHTNAME}".toText22(color: Colors.white, isBold: true), ).center,
],
).center, ).center,
).center, ],
], ).paddingOnly(left: 21, right: 21, top: 27, bottom: 37),
).paddingOnly(left: 21, right: 21, top: 27, bottom: 37), Stack(
Stack( children: [
children: [ Container(
Container( width: double.infinity,
width: double.infinity, decoration: const BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
decoration: const BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), padding: const EdgeInsets.only(left: 31, right: 31, top: 30, bottom: 29),
padding: const EdgeInsets.only(left: 31, right: 31, top: 30, bottom: 29), child: Column(
child: Column( children: [
children: [ Row(
Row( children: [
children: [ Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ LocaleKeys.actualCheckIn.tr().toText11(
LocaleKeys.actualCheckIn.tr().toText11( color: MyColors.grey67Color,
color: MyColors.grey67Color, ),
), "${getScheduleShiftsDetailsList!.sHTACTUALSTARTTIME}" != ""
"${getScheduleShiftsDetailsList!.sHTACTUALSTARTTIME}" != "" ? "${getScheduleShiftsDetailsList!.sHTACTUALSTARTTIME}".toText22(color: Colors.black, isBold: true)
? "${getScheduleShiftsDetailsList!.sHTACTUALSTARTTIME}".toText22(color: Colors.black, isBold: true) : "__".toText22(color: Colors.black, isBold: true),
: "__".toText22(color: Colors.black, isBold: true), ],
], ).expanded,
).expanded, Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ LocaleKeys.actualCheckOut.tr().toText11(
LocaleKeys.actualCheckOut.tr().toText11( color: MyColors.grey67Color,
color: MyColors.grey67Color, ),
), "${getScheduleShiftsDetailsList!.sHTACTUALENDTIME}" != ""
"${getScheduleShiftsDetailsList!.sHTACTUALENDTIME}" != "" ? "${getScheduleShiftsDetailsList!.sHTACTUALENDTIME}".toText22(color: Colors.black, isBold: true)
? "${getScheduleShiftsDetailsList!.sHTACTUALENDTIME}".toText22(color: Colors.black, isBold: true) : "__".toText22(color: Colors.black, isBold: true),
: "__".toText22(color: Colors.black, isBold: true), ],
], ).expanded,
).expanded, ],
], ),
), 25.height,
25.height, const Divider(
const Divider( height: 1,
height: 1, thickness: 1,
thickness: 1, color: MyColors.lightGreyEFColor,
color: MyColors.lightGreyEFColor, ),
), 25.height,
25.height, Row(
Row( children: [
children: [ Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ LocaleKeys.approvedCheckIn.tr().toText11(
LocaleKeys.approvedCheckIn.tr().toText11( color: MyColors.grey67Color,
color: MyColors.grey67Color, ),
), "${getScheduleShiftsDetailsList!.aPPROVEDSTARTTIME}" != ""
"${getScheduleShiftsDetailsList!.aPPROVEDSTARTTIME}" != "" ? "${getScheduleShiftsDetailsList!.aPPROVEDSTARTTIME}".toText22(color: MyColors.greenColor, isBold: true)
? "${getScheduleShiftsDetailsList!.aPPROVEDSTARTTIME}".toText22(color: MyColors.greenColor, isBold: true) : "__".toText22(color: MyColors.greenColor, isBold: true),
: "__".toText22(color: MyColors.greenColor, isBold: true), ],
], ).expanded,
).expanded, Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ LocaleKeys.approvedCheckOut.tr().toText11(
LocaleKeys.approvedCheckOut.tr().toText11( color: MyColors.grey67Color,
color: MyColors.grey67Color, ),
), "${getScheduleShiftsDetailsList!.aPPROVEDENDTIME}" != ""
"${getScheduleShiftsDetailsList!.aPPROVEDENDTIME}" != "" ? "${getScheduleShiftsDetailsList!.aPPROVEDENDTIME}".toText22(color: MyColors.greenColor, isBold: true)
? "${getScheduleShiftsDetailsList!.aPPROVEDENDTIME}".toText22(color: MyColors.greenColor, isBold: true) : "__".toText22(color: MyColors.greenColor, isBold: true),
: "__".toText22(color: MyColors.greenColor, isBold: true), ],
], ).expanded,
).expanded, ],
], ),
), 25.height,
25.height, const Divider(
const Divider( height: 1,
height: 1, thickness: 1,
thickness: 1, color: MyColors.lightGreyEFColor,
color: MyColors.lightGreyEFColor, ),
), 25.height,
25.height, Row(
Row( children: [
children: [ Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ LocaleKeys.lateIn.tr().toText11(
LocaleKeys.lateIn.tr().toText11( color: MyColors.grey67Color,
color: MyColors.grey67Color, ),
), "${getDayHoursTypeDetailsList[index].lATEINHRS}".toText22(color: MyColors.redColor, isBold: true),
"${getDayHoursTypeDetailsList[index].lATEINHRS}".toText22(color: MyColors.redColor, isBold: true), ],
], ).expanded,
).expanded, Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ LocaleKeys.excess.tr().toText11(
LocaleKeys.excess.tr().toText11( color: MyColors.grey67Color,
color: MyColors.grey67Color, ),
), "${getDayHoursTypeDetailsList[index].eXCESSHRS}".toText22(color: MyColors.backgroundBlackColor, isBold: true),
"${getDayHoursTypeDetailsList[index].eXCESSHRS}".toText22(color: MyColors.backgroundBlackColor, isBold: true), ],
], ).expanded,
).expanded, ],
], ),
), 25.height,
25.height, const Divider(
const Divider( height: 1,
height: 1, thickness: 1,
thickness: 1, color: MyColors.lightGreyEFColor,
color: MyColors.lightGreyEFColor, ),
), 25.height,
25.height, Row(
Row( children: [
children: [ Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ LocaleKeys.shortage.tr().toText11(
LocaleKeys.shortage.tr().toText11( color: MyColors.grey67Color,
color: MyColors.grey67Color, ),
), "${getDayHoursTypeDetailsList[index].sHORTAGEHRS}".toText22(color: MyColors.backgroundBlackColor, isBold: true),
"${getDayHoursTypeDetailsList[index].sHORTAGEHRS}".toText22(color: MyColors.backgroundBlackColor, isBold: true), ],
], ).expanded,
).expanded, Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ LocaleKeys.earlyOut.tr().toText11(
LocaleKeys.earlyOut.tr().toText11( color: MyColors.grey67Color,
color: MyColors.grey67Color, ),
), "${getDayHoursTypeDetailsList[index].eARLYOUTHRS}".toText22(color: Colors.black, isBold: true),
"${getDayHoursTypeDetailsList[index].eARLYOUTHRS}".toText22(color: Colors.black, isBold: true), ],
], ).expanded,
).expanded, ],
], ),
), ],
], ),
), ),
), ],
], ),
), ],
], ),
), ),
), ),
), ),
), ],
], );
); },
}, );
); },
}, )
):null; : null;
} }
} }

@ -1,10 +1,10 @@
import 'dart:convert'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:audio_waveforms/audio_waveforms.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:just_audio/just_audio.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
@ -16,32 +16,43 @@ import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart'; import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_full_image_preview.dart'; import 'package:mohem_flutter_app/ui/chat/chat_full_image_preview.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/ui/chat/common.dart';
import 'package:open_file/open_file.dart'; import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
// todo: @aamir use extension methods, and use correct widgets.
class ChatBubble extends StatelessWidget { class ChatBubble extends StatelessWidget {
ChatBubble({Key? key, required this.dateTime, required this.cItem}) : super(key: key); ChatBubble({Key? key, required this.dateTime, required this.cItem}) : super(key: key);
final String dateTime; final String dateTime;
final SingleUserChatModel cItem; final SingleUserChatModel cItem;
bool isCurrentUser = false; bool isCurrentUser = false;
bool isSeen = false; bool isSeen = false;
bool isReplied = false; bool isReplied = false;
bool isVoice = false;
int? fileTypeID; int? fileTypeID;
String? fileTypeName; String? fileTypeName;
late ChatProviderModel data;
late ChatProviderModel provider;
String? fileTypeDescription; String? fileTypeDescription;
bool isDelivered = false; bool isDelivered = false;
String userName = ''; String userName = '';
late Offset screenOffset; late Offset screenOffset;
void makeAssign() { void makeAssign() {
isCurrentUser = cItem.currentUserId == AppState().chatDetails!.response!.id ? true : false; isCurrentUser = cItem.currentUserId == AppState().chatDetails!.response!.id ? true : false;
isSeen = cItem.isSeen == true ? true : false; isSeen = cItem.isSeen == true ? true : false;
isReplied = cItem.userChatReplyResponse != null ? true : false; isReplied = cItem.userChatReplyResponse != null ? true : false;
// isVoice = cItem.fileTypeId == 13 && cItem.voiceController != null ? true : false;
fileTypeID = cItem.fileTypeId; fileTypeID = cItem.fileTypeId;
fileTypeName = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeName : ""; fileTypeName = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeName : "";
fileTypeDescription = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeDescription : ""; fileTypeDescription = cItem.fileTypeResponse != null ? cItem.fileTypeResponse!.fileTypeDescription : "";
@ -49,12 +60,75 @@ class ChatBubble extends StatelessWidget {
userName = AppState().chatDetails!.response!.userName == cItem.currentUserName.toString() ? "You" : cItem.currentUserName.toString(); userName = AppState().chatDetails!.response!.userName == cItem.currentUserName.toString() ? "You" : cItem.currentUserName.toString();
} }
void playVoice(
BuildContext context, {
required SingleUserChatModel data,
}) async {
if (data.voice != null && data.voice!.existsSync()) {
if (Platform.isIOS) {
Duration? duration = await data.voiceController!.setAudioSource(MyCustomStream(data.voice!.readAsBytesSync()));
await data.voiceController!.seek(duration);
await data.voiceController!.setLoopMode(LoopMode.off);
await data.voiceController!.setVolume(1.0);
await data.voiceController!.load();
data.voiceController!.play();
} else {
await data.voiceController!.setFilePath(data!.voice!.path);
Duration? duration = await data.voiceController!.load();
await data.voiceController!.seek(duration);
await data.voiceController!.setLoopMode(LoopMode.off);
await data.voiceController!.play();
}
} else {
Utils.showLoading(context);
Uint8List encodedString = await ChatApiClient().downloadURL(fileName: data.contant!, fileTypeDescription: provider.getFileTypeDescription(data.fileTypeResponse!.fileTypeName ?? ""));
// try {
File sFile = await provider.downChatVoice(encodedString, data.fileTypeResponse!.fileTypeName ?? "", data);
if (sFile.path.isEmpty) {
logger.d("Path Is Emptyyyyyyy");
} else {
logger.d("Path Exsists");
}
data.voice = sFile;
if (Platform.isIOS) {
logger.d("isIOS");
Duration? duration = await data.voiceController!.setAudioSource(MyCustomStream(data.voice!.readAsBytesSync()));
await data.voiceController!.seek(duration);
await data.voiceController!.setLoopMode(LoopMode.off);
await data.voiceController!.setVolume(1.0);
await data.voiceController!.load();
Utils.hideLoading(context);
data.voiceController!.play();
} else {
Duration? duration = await data.voiceController!.setFilePath(sFile.path);
await data.voiceController!.setLoopMode(LoopMode.off);
await data.voiceController!.seek(duration);
Utils.hideLoading(context);
await data.voiceController!.play();
}
}
}
void pausePlaying(BuildContext context, {required SingleUserChatModel data}) async {
await data.voiceController!.pause();
}
void rePlay(BuildContext context, {required SingleUserChatModel data}) async {
if (data.voice != null && data.voice!.existsSync()) {
await data.voiceController!.seek(Duration.zero);
await data.voiceController!.play();
}
}
Stream<PositionData> get _positionDataStream => Rx.combineLatest3<Duration, Duration, Duration?, PositionData>(cItem.voiceController!.positionStream, cItem.voiceController!.bufferedPositionStream,
cItem.voiceController!.durationStream, (Duration position, Duration bufferedPosition, Duration? duration) => PositionData(position, bufferedPosition, duration ?? Duration.zero));
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Size windowSize = MediaQuery.of(context).size; Size windowSize = MediaQuery.of(context).size;
screenOffset = Offset(windowSize.width / 2, windowSize.height / 2); screenOffset = Offset(windowSize.width / 2, windowSize.height / 2);
makeAssign(); makeAssign();
data = Provider.of<ChatProviderModel>(context, listen: false); provider = Provider.of<ChatProviderModel>(context, listen: false);
return isCurrentUser ? currentUser(context) : receiptUser(context); return isCurrentUser ? currentUser(context) : receiptUser(context);
} }
@ -79,30 +153,32 @@ class ChatBubble extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), (userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5),
(cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "") Directionality(
.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4) textDirection: provider.getTextDirection(cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : ""),
.paddingOnly(right: 5, top: 5, bottom: 8, left: 5), child: (cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "")
.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4)
.paddingOnly(right: 5, top: 5, bottom: 8, left: 5),
),
], ],
).expanded, ).expanded,
if (cItem.userChatReplyResponse != null && cItem.userChatReplyResponse!.fileTypeId == 12 || if (cItem.userChatReplyResponse != null)
cItem.userChatReplyResponse!.fileTypeId == 3 || if (cItem.userChatReplyResponse!.fileTypeId == 12 || cItem.userChatReplyResponse!.fileTypeId == 3 || cItem.userChatReplyResponse!.fileTypeId == 4)
cItem.userChatReplyResponse!.fileTypeId == 4) ClipRRect(
ClipRRect( borderRadius: BorderRadius.circular(8.0),
borderRadius: BorderRadius.circular(8.0), child: SizedBox(
child: SizedBox( height: 32,
height: 32, width: 32,
width: 32, child: showImage(
child: showImage( isReplyPreview: false,
isReplyPreview: true,
fileName: cItem.userChatReplyResponse!.contant!, fileName: cItem.userChatReplyResponse!.contant!,
fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg") fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg")),
.paddingOnly(left: 10, right: 10, bottom: 16, top: 16), ).paddingOnly(left: 10, right: 10, bottom: 16, top: 16),
),
),
], ],
), ),
), ),
).paddingOnly(bottom: 7), ).paddingOnly(bottom: 7).onPress(() {
provider.scrollToMsg(cItem);
}),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3)
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(5.0), borderRadius: BorderRadius.circular(5.0),
@ -117,18 +193,21 @@ class ChatBubble extends StatelessWidget {
); );
}), }),
), ),
).paddingOnly(bottom: 4) ).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
currentWaveBubble(context, cItem)
else else
Row( Row(
children: [ children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8
// || fileTypeID == 2 // || fileTypeID == 2
) )
SvgPicture.asset(data.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10), SvgPicture.asset(provider.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10),
(cItem.contant ?? "").toText12().expanded, Directionality(textDirection: provider.getTextDirection(cItem.contant ?? ""), child: (cItem.contant ?? "").toText12().expanded),
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8
//|| fileTypeID == 2 //|| fileTypeID == 2
) const Icon(Icons.remove_red_eye, size: 16) )
const Icon(Icons.remove_red_eye, size: 16)
], ],
), ),
Align( Align(
@ -157,10 +236,7 @@ class ChatBubble extends StatelessWidget {
transform: GradientRotation(.83), transform: GradientRotation(.83),
begin: Alignment.topRight, begin: Alignment.topRight,
end: Alignment.bottomLeft, end: Alignment.bottomLeft,
colors: <Color>[ colors: <Color>[MyColors.gradiantEndColor, MyColors.gradiantStartColor],
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
), ),
), ),
child: Column( child: Column(
@ -181,29 +257,33 @@ class ChatBubble extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5), (userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5),
(cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "") Directionality(
.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4) textDirection: provider.getTextDirection(cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : ""),
.paddingOnly(right: 5, top: 5, bottom: 8, left: 5), child: (cItem.userChatReplyResponse != null ? cItem.userChatReplyResponse!.contant.toString() : "")
.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4)
.paddingOnly(right: 5, top: 5, bottom: 8, left: 5),
),
], ],
).expanded, ).expanded,
if (cItem.userChatReplyResponse != null && cItem.userChatReplyResponse!.fileTypeId == 12 || if (cItem.userChatReplyResponse != null)
cItem.userChatReplyResponse!.fileTypeId == 3 || if (cItem.userChatReplyResponse!.fileTypeId == 12 || cItem.userChatReplyResponse!.fileTypeId == 3 || cItem.userChatReplyResponse!.fileTypeId == 4)
cItem.userChatReplyResponse!.fileTypeId == 4) ClipRRect(
ClipRRect( borderRadius: BorderRadius.circular(8.0),
borderRadius: BorderRadius.circular(8.0), child: SizedBox(
child: SizedBox( height: 32,
height: 32, width: 32,
width: 32, child: showImage(
child: showImage( isReplyPreview: true,
isReplyPreview: true, fileName: cItem.userChatReplyResponse!.contant!,
fileName: cItem.userChatReplyResponse!.contant!, fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg"),
fileTypeDescription: cItem.userChatReplyResponse!.fileTypeResponse!.fileTypeDescription ?? "image/jpg"), ),
), ).paddingOnly(left: 10, right: 10, bottom: 16, top: 16)
).paddingOnly(left: 10, right: 10, bottom: 16, top: 16)
], ],
), ),
), ),
).paddingOnly(bottom: 7), ).paddingOnly(bottom: 7).onPress(() {
provider.scrollToMsg(cItem);
}),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3)
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(5.0), borderRadius: BorderRadius.circular(5.0),
@ -218,15 +298,17 @@ class ChatBubble extends StatelessWidget {
); );
}), }),
), ),
).paddingOnly(bottom: 4) ).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
recipetWaveBubble(context, cItem)
else else
Row( Row(
children: [ children: [
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8
// || fileTypeID == 2 // || fileTypeID == 2
) )
SvgPicture.asset(data.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10), SvgPicture.asset(provider.getType(fileTypeName ?? ""), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 0, right: 10),
(cItem.contant ?? "").toText12(color: Colors.white).expanded, Directionality(textDirection: provider.getTextDirection(cItem.contant ?? ""), child: (cItem.contant ?? "").toText12(color: Colors.white).expanded),
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8
//|| fileTypeID == 2 //|| fileTypeID == 2
) )
@ -244,9 +326,11 @@ class ChatBubble extends StatelessWidget {
).paddingOnly(right: MediaQuery.of(context).size.width * 0.3); ).paddingOnly(right: MediaQuery.of(context).size.width * 0.3);
} }
Widget showImage({required bool isReplyPreview, required String fileName, required String fileTypeDescription}) { Widget voiceMsg(BuildContext context) {
if (isReplyPreview) {} return Container();
}
Widget showImage({required bool isReplyPreview, required String fileName, required String fileTypeDescription}) {
if (cItem.isImageLoaded! && cItem.image != null) { if (cItem.isImageLoaded! && cItem.image != null) {
return Image.memory( return Image.memory(
cItem.image!, cItem.image!,
@ -283,64 +367,125 @@ class ChatBubble extends StatelessWidget {
); );
} }
} }
}
class WaveBubble extends StatelessWidget {
final PlayerController playerController;
final VoidCallback onTap;
final bool isPlaying;
const WaveBubble({
Key? key,
required this.playerController,
required this.onTap,
required this.isPlaying,
}) : super(key: key);
@override Widget currentWaveBubble(BuildContext context, SingleUserChatModel data) {
Widget build(BuildContext context) {
return Container( return Container(
margin: const EdgeInsets.all(10), margin: const EdgeInsets.all(0),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30), border: Border(
gradient: const LinearGradient( left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white),
transform: GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
), ),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
), ),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min,
children: [ children: [
IconButton( getPlayer(player: data.voiceController!, modelData: data),
onPressed: onTap, StreamBuilder<PositionData>(
icon: Icon(isPlaying ? Icons.stop : Icons.play_arrow), stream: _positionDataStream,
color: Colors.white, builder: (BuildContext context, AsyncSnapshot<PositionData> snapshot) {
splashColor: Colors.transparent, PositionData? positionData = snapshot.data;
highlightColor: Colors.transparent, return SeekBar(
duration: positionData?.duration ?? Duration.zero,
position: positionData?.position ?? Duration.zero,
bufferedPosition: positionData?.bufferedPosition ?? Duration.zero,
onChangeEnd: data.voiceController!.seek,
).expanded;
},
), ),
AudioFileWaveforms( ],
size: Size(MediaQuery.of(context).size.width / 2, 10), ),
playerController: playerController, ).circle(5);
padding: EdgeInsets.zero, }
margin: EdgeInsets.zero,
playerWaveStyle: const PlayerWaveStyle( Widget recipetWaveBubble(BuildContext context, SingleUserChatModel data) {
fixedWaveColor: Colors.white, return Container(
liveWaveColor:MyColors.lightGreenColor, margin: const EdgeInsets.all(0),
showTop: true, decoration: BoxDecoration(
showBottom: true, border: Border(
waveCap: StrokeCap.round, left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white),
seekLineThickness: 3, ),
visualizerHeight: 6, color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
backgroundColor: Colors.transparent ),
), child: Row(
mainAxisSize: MainAxisSize.max,
children: [
getPlayer(player: data.voiceController!, modelData: data),
StreamBuilder<PositionData>(
stream: _positionDataStream,
builder: (BuildContext context, AsyncSnapshot<PositionData> snapshot) {
PositionData? positionData = snapshot.data;
return SeekBar(
duration: positionData?.duration ?? Duration.zero,
position: positionData?.position ?? Duration.zero,
bufferedPosition: positionData?.bufferedPosition ?? Duration.zero,
onChangeEnd: data.voiceController!.seek,
).expanded;
},
), ),
], ],
), ),
).circle(5);
}
Widget getPlayer({required AudioPlayer player, required SingleUserChatModel modelData}) {
return StreamBuilder<PlayerState>(
stream: player!.playerStateStream,
builder: (BuildContext context, AsyncSnapshot<PlayerState> snapshot) {
PlayerState? playerState = snapshot.data;
ProcessingState? processingState = playerState?.processingState;
bool? playing = playerState?.playing;
if (processingState == ProcessingState.loading || processingState == ProcessingState.buffering) {
return Container(
margin: const EdgeInsets.all(8.0),
width: 30.0,
height: 30.0,
child: const CircularProgressIndicator(),
);
} else if (playing != true) {
return Icon(
Icons.play_arrow,
size: 30,
color: MyColors.lightGreenColor,
).onPress(() {
playVoice(context, data: modelData);
});
} else if (processingState != ProcessingState.completed) {
return const Icon(
Icons.pause,
size: 30,
color: MyColors.lightGreenColor,
).onPress(() {
pausePlaying(context, data: modelData);
});
} else {
return const Icon(
Icons.replay,
size: 30,
color: MyColors.lightGreenColor,
).onPress(() {
rePlay(context, data: modelData);
});
}
},
);
}
}
class MyCustomStream extends StreamAudioSource {
final Uint8List bytes;
MyCustomStream(this.bytes);
@override
Future<StreamAudioResponse> request([int? start, int? end]) async {
start ??= 0;
end ??= bytes.length;
return StreamAudioResponse(
sourceLength: bytes.length,
contentLength: end - start,
offset: start,
stream: Stream.value(bytes.sublist(start, end)),
contentType: 'audio/aac',
); );
} }
} }

@ -1,6 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'package:audio_waveforms/audio_waveforms.dart'; import 'package:audio_waveforms/audio_waveforms.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -18,7 +16,7 @@ import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.da
import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart'; import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart'; import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/ui/chat/common.dart';
import 'package:mohem_flutter_app/widgets/chat_app_bar_widge.dart'; import 'package:mohem_flutter_app/widgets/chat_app_bar_widge.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -44,6 +42,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
final RefreshController _rc = RefreshController(initialRefresh: false); final RefreshController _rc = RefreshController(initialRefresh: false);
late ChatProviderModel data; late ChatProviderModel data;
ChatDetailedScreenParams? params; ChatDetailedScreenParams? params;
var textDirection = TextDirection.RTL;
void getMoreChat() async { void getMoreChat() async {
if (params != null) { if (params != null) {
@ -80,7 +79,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
loadMore: false, loadMore: false,
isNewChat: params!.isNewChat!, isNewChat: params!.isNewChat!,
); );
data.initAudio(); data.initAudio(receiverId: params!.chatUser!.id!);
} }
return Scaffold( return Scaffold(
@ -89,7 +88,6 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
context, context,
title: params!.chatUser!.userName.toString().replaceAll(".", " ").capitalizeFirstofEach, title: params!.chatUser!.userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
showHomeButton: false, showHomeButton: false,
image: params!.chatUser!.image == null || params!.chatUser!.image.isEmpty ? null : params!.chatUser!.image,
showTyping: true, showTyping: true,
chatUser: params!.chatUser, chatUser: params!.chatUser,
actions: [ actions: [
@ -130,7 +128,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
reverse: true, reverse: true,
itemCount: m.userChatHistory.length, itemCount: m.userChatHistory.length,
padding: const EdgeInsets.all(21), padding: const EdgeInsets.all(21),
separatorBuilder: (cxt, index) => 8.height, separatorBuilder: (BuildContext cxt, int index) => 8.height,
itemBuilder: (BuildContext context, int i) { itemBuilder: (BuildContext context, int i) {
return SwipeTo( return SwipeTo(
iconColor: MyColors.lightGreenColor, iconColor: MyColors.lightGreenColor,
@ -144,15 +142,24 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
); );
}, },
).onPress(() async { ).onPress(() async {
if (m.userChatHistory[i].fileTypeResponse != null) { logger.w(m.userChatHistory[i].toJson());
m.getChatMedia(context, if (m.userChatHistory[i].fileTypeResponse != null && m.userChatHistory[i].fileTypeId != null) {
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!); if (m.userChatHistory[i].fileTypeId! == 1 ||
m.userChatHistory[i].fileTypeId! == 5 ||
m.userChatHistory[i].fileTypeId! == 7 ||
m.userChatHistory[i].fileTypeId! == 6 ||
m.userChatHistory[i].fileTypeId! == 8
// || m.userChatHistory[i].fileTypeId! == 2
) {
m.getChatMedia(context,
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!);
}
} }
}); });
}, },
), ),
).expanded, ).expanded,
if (m.isMsgReply) if (m.isReplyMsg)
SizedBox( SizedBox(
height: 82, height: 82,
child: Row( child: Row(
@ -174,7 +181,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
], ],
).expanded, ).expanded,
12.width, 12.width,
if (m.isMsgReply && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg, m), if (m.isReplyMsg && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg, m),
12.width, 12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe), const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
], ],
@ -183,12 +190,9 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
], ],
), ),
), ),
if (m.isFileSelected && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg") if (m.isAttachmentMsg && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21), SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21),
const Divider( const Divider(height: 1, color: MyColors.lightGreyEFColor),
height: 1,
color: MyColors.lightGreyEFColor,
),
if (m.isRecoding) if (m.isRecoding)
Column( Column(
children: <Widget>[ children: <Widget>[
@ -197,12 +201,10 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
Text(m.buildTimer()).paddingAll(10), Text(m.buildTimer()).paddingAll(10),
if (m.isRecoding && m.isPlaying) if (m.isRecoding && m.isPlaying)
WaveBubble( WaveBubble(
playerController: m.playerController, playerController: m.playerController,
onTap: () { isPlaying: m.playerController.playerState == PlayerState.playing,
m.playOrPause(); onTap: () {},
}, ).expanded
isPlaying: m.playerController.playerState == PlayerState.playing)
.expanded
else else
AudioWaveforms( AudioWaveforms(
waveStyle: const WaveStyle( waveStyle: const WaveStyle(
@ -234,22 +236,6 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
).paddingAll(10).onPress(() { ).paddingAll(10).onPress(() {
m.deleteRecoding(); m.deleteRecoding();
}), }),
if (m.isPause)
const Icon(
Icons.mic,
size: 26,
color: MyColors.lightGreenColor,
).paddingOnly(right: 15).onPress(() {
m.resumeRecoding();
}),
if (!m.isPause)
const Icon(
Icons.pause_circle_outline,
size: 26,
color: MyColors.lightGreenColor,
).paddingOnly(right: 15).onPress(() {
m.pauseRecoding();
}),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26) SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
.onPress( .onPress(
() => m.sendChatMessage(context, () => m.sendChatMessage(context,
@ -267,10 +253,14 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
Row( Row(
children: [ children: [
TextField( TextField(
textDirection: m.textDirection,
controller: m.message, controller: m.message,
decoration: InputDecoration( decoration: InputDecoration(
hintText: m.isFileSelected ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(), hintTextDirection: m.textDirection,
hintStyle: TextStyle(color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14), hintText: m.isAttachmentMsg
? m.selectedFile.path.split("/").last
: m.textDirection.name == "rtl" ? "اكتب هنا للرد" :LocaleKeys.typeheretoreply.tr(),
hintStyle: TextStyle(color: m.isAttachmentMsg ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14),
border: InputBorder.none, border: InputBorder.none,
focusedBorder: InputBorder.none, focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none, enabledBorder: InputBorder.none,
@ -288,7 +278,8 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
? SvgPicture.asset(m.getType(m.sFileType), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 21, right: 15) ? SvgPicture.asset(m.getType(m.sFileType), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 21, right: 15)
: null, : null,
), ),
onChanged: (val) { onChanged: (String val) {
m.inputBoxDirection(val);
m.userTypingInvoke(currentUser: AppState().chatDetails!.response!.id!, reciptUser: params!.chatUser!.id!); m.userTypingInvoke(currentUser: AppState().chatDetails!.response!.id!, reciptUser: params!.chatUser!.id!);
}, },
).expanded, ).expanded,
@ -306,11 +297,11 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
() => m.selectImageToUpload(context), () => m.selectImageToUpload(context),
), ),
).paddingOnly(right: 15), ).paddingOnly(right: 15),
Icon( const Icon(
Icons.mic, Icons.mic,
color: MyColors.lightGreenColor, color: MyColors.lightGreenColor,
).paddingOnly(right: 15).onPress(() { ).paddingOnly(right: 15).onPress(() {
m.startRecoding(); m.startRecoding(context);
}), }),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26) SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
.onPress( .onPress(

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart';
@ -8,6 +9,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_home_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_home_screen.dart';
import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart'; import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart';
import 'package:mohem_flutter_app/ui/chat/my_team_screen.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -81,6 +83,7 @@ class _ChatHomeState extends State<ChatHome> {
children: <Widget>[ children: <Widget>[
myTab(LocaleKeys.mychats.tr(), 0), myTab(LocaleKeys.mychats.tr(), 0),
myTab(LocaleKeys.favorite.tr(), 1), myTab(LocaleKeys.favorite.tr(), 1),
AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 2) : const SizedBox(),
], ],
), ),
), ),
@ -95,6 +98,7 @@ class _ChatHomeState extends State<ChatHome> {
children: <Widget>[ children: <Widget>[
ChatHomeScreen(), ChatHomeScreen(),
ChatFavoriteUsersScreen(), ChatFavoriteUsersScreen(),
AppState().getempStatusIsManager ? const MyTeamScreen() : const SizedBox(),
], ],
).expanded, ).expanded,
], ],

@ -179,6 +179,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
m.favoriteUser( m.favoriteUser(
userID: AppState().chatDetails!.response!.id!, userID: AppState().chatDetails!.response!.id!,
targetUserID: m.searchedChats![index].id!, targetUserID: m.searchedChats![index].id!,
fromSearch: false
); );
} else if (m.searchedChats![index].isFav == true) { } else if (m.searchedChats![index].isFav == true) {
m.unFavoriteUser( m.unFavoriteUser(
@ -189,6 +190,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
m.favoriteUser( m.favoriteUser(
userID: AppState().chatDetails!.response!.id!, userID: AppState().chatDetails!.response!.id!,
targetUserID: m.searchedChats![index].id!, targetUserID: m.searchedChats![index].id!,
fromSearch: false
); );
} }
}, },
@ -238,6 +240,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
), ),
), ),
onPressed: () async { onPressed: () async {
print(AppState().chatDetails!.response!.token);
showMyBottomSheet( showMyBottomSheet(
context, context,
callBackFunc: () {}, callBackFunc: () {},

@ -0,0 +1,189 @@
import 'dart:math';
import 'package:audio_waveforms/audio_waveforms.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
class SeekBar extends StatefulWidget {
final Duration duration;
final Duration position;
final Duration bufferedPosition;
final ValueChanged<Duration>? onChanged;
final ValueChanged<Duration>? onChangeEnd;
const SeekBar({
Key? key,
required this.duration,
required this.position,
required this.bufferedPosition,
this.onChanged,
this.onChangeEnd,
}) : super(key: key);
@override
SeekBarState createState() => SeekBarState();
}
class SeekBarState extends State<SeekBar> {
double? _dragValue;
late SliderThemeData _sliderThemeData;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_sliderThemeData = SliderTheme.of(context).copyWith(
// trackHeight: 2.0,
thumbColor: MyColors.lightGreenColor,
activeTrackColor: MyColors.lightGreenColor,
inactiveTrackColor: MyColors.grey57Color.withOpacity(0.4),
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
SliderTheme(
data: _sliderThemeData.copyWith(
thumbShape: HiddenThumbComponentShape(),
),
child: ExcludeSemantics(
child: Slider(
min: 0.0,
max: widget.duration.inMilliseconds.toDouble(),
value: min(widget.bufferedPosition.inMilliseconds.toDouble(), widget.duration.inMilliseconds.toDouble()),
onChanged: (value) {
setState(() {
_dragValue = value;
});
if (widget.onChanged != null) {
widget.onChanged!(Duration(milliseconds: value.round()));
}
},
onChangeEnd: (value) {
if (widget.onChangeEnd != null) {
widget.onChangeEnd!(Duration(milliseconds: value.round()));
}
_dragValue = null;
},
),
),
),
SliderTheme(
data: _sliderThemeData.copyWith(
inactiveTrackColor: Colors.transparent,
),
child: Slider(
min: 0.0,
max: widget.duration.inMilliseconds.toDouble(),
value: min(_dragValue ?? widget.position.inMilliseconds.toDouble(), widget.duration.inMilliseconds.toDouble()),
onChanged: (value) {
setState(() {
_dragValue = value;
});
if (widget.onChanged != null) {
widget.onChanged!(Duration(milliseconds: value.round()));
}
},
onChangeEnd: (value) {
if (widget.onChangeEnd != null) {
widget.onChangeEnd!(Duration(milliseconds: value.round()));
}
_dragValue = null;
},
),
),
],
);
}
}
class PositionData {
final Duration position;
final Duration bufferedPosition;
final Duration duration;
PositionData(this.position, this.bufferedPosition, this.duration);
}
class HiddenThumbComponentShape extends SliderComponentShape {
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) => Size.zero;
@override
void paint(
PaintingContext context,
Offset center, {
required Animation<double> activationAnimation,
required Animation<double> enableAnimation,
required bool isDiscrete,
required TextPainter labelPainter,
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required TextDirection textDirection,
required double value,
required double textScaleFactor,
required Size sizeWithOverflow,
}) {}
}
class WaveBubble extends StatelessWidget {
final PlayerController playerController;
final VoidCallback onTap;
final bool isPlaying;
const WaveBubble({
Key? key,
required this.playerController,
required this.onTap,
required this.isPlaying,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
gradient: const LinearGradient(
transform: GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: onTap,
icon: Icon(isPlaying ? Icons.stop : Icons.play_arrow),
color: Colors.white,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
AudioFileWaveforms(
size: Size(MediaQuery.of(context).size.width / 2, 10),
playerController: playerController,
padding: EdgeInsets.zero,
margin: EdgeInsets.zero,
enableSeekGesture: true,
density: 1,
playerWaveStyle: const PlayerWaveStyle(
fixedWaveColor: Colors.white,
liveWaveColor: MyColors.greenColor,
showTop: true,
showBottom: true,
waveCap: StrokeCap.round,
seekLineThickness: 2,
visualizerHeight: 4,
backgroundColor: Colors.transparent,
),
),
],
),
);
}
}

@ -0,0 +1,154 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
class MyTeamScreen extends StatefulWidget {
const MyTeamScreen({Key? key}) : super(key: key);
@override
State<MyTeamScreen> createState() => _MyTeamScreenState();
}
class _MyTeamScreenState extends State<MyTeamScreen> {
late ChatProviderModel provider;
@override
void initState() {
super.initState();
provider = Provider.of<ChatProviderModel>(context, listen: false);
loadMembers();
}
void loadMembers(){
provider.getTeamMembers();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyColors.white,
body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
if (m.isLoading) {
return ChatHomeShimmer(
isDetailedScreen: false,
);
} else {
return m.teamMembersList != null && m.teamMembersList.isNotEmpty
? ListView.separated(
itemCount: m.teamMembersList!.length,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(bottom: 80.0),
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 55,
child: Row(
children: [
Stack(
children: <Widget>[
if (m.teamMembersList![index].isImageLoading!)
const SizedBox(
height: 48,
width: 48,
).toShimmer().circle(30),
if (!m.teamMembersList![index].isImageLoading! && m.teamMembersList![index].userLocalDownlaodedImage == null)
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
if (!m.teamMembersList![index].isImageLoading! && m.teamMembersList![index].userLocalDownlaodedImage != null)
Container(
width: 48.0,
height: 48.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: FileImage(m.teamMembersList![index].userLocalDownlaodedImage!),
),
),
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: m.teamMembersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red,
),
).circle(10),
)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(m.teamMembersList[index].userName! ?? "").toText14(color: MyColors.darkTextColor).paddingOnly(left: 11, top: 13),
],
).expanded,
// SizedBox(
// width: 60,
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.end,
// mainAxisSize: MainAxisSize.max,
// children: <Widget>[
// Icon(
// m.teamMembersList![index].isFav! ? Icons.star : Icons.star_border,
// color: m.teamMembersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color,
// ).onPress(() {
// if (m.teamMembersList![index].isFav!) {
// m.unFavoriteUser(
// userID: AppState().chatDetails!.response!.id!,
// targetUserID: m.teamMembersList![index].id!,
// );
// }
// }).center,
// ],
// ),
// ),
],
),
).onPress(() {
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: ChatDetailedScreenParams(m.teamMembersList![index], true),
).then(
(Object? value) {
m.clearSelections();
},
);
});
},
separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 70),
).paddingAll(21)
: Column(
children: <Widget>[
Utils.getNoDataWidget(context).expanded,
],
);
}
},
),
);
}
}

@ -48,6 +48,9 @@ class _SuccessDialogState extends State<SuccessDialog> with TickerProviderStateM
width: size, width: size,
height: size, height: size,
child: Card( child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
child: Lottie.asset( child: Lottie.asset(
'assets/lottie/lt_success.json', 'assets/lottie/lt_success.json',
repeat: false, repeat: false,

@ -1,11 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
@ -41,7 +42,7 @@ class DashboardScreen extends StatefulWidget {
} }
} }
class _DashboardScreenState extends State<DashboardScreen> { class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingObserver {
late DashboardProviderModel data; late DashboardProviderModel data;
late MarathonProvider marathonProvider; late MarathonProvider marathonProvider;
late ChatProviderModel cProvider; late ChatProviderModel cProvider;
@ -53,18 +54,38 @@ class _DashboardScreenState extends State<DashboardScreen> {
@override @override
void initState() { void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState(); super.initState();
scheduleMicrotask(() { scheduleMicrotask(() {
data = Provider.of<DashboardProviderModel>(context, listen: false); data = Provider.of<DashboardProviderModel>(context, listen: false);
marathonProvider = Provider.of<MarathonProvider>(context, listen: false); marathonProvider = Provider.of<MarathonProvider>(context, listen: false);
cProvider = Provider.of<ChatProviderModel>(context, listen: false); cProvider = Provider.of<ChatProviderModel>(context, listen: false);
_bHubCon();
_onRefresh(); _onRefresh();
}); });
} }
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
checkSession();
}
}
void checkSession() async {
try {
Utils.showLoading(context);
await DashboardApiClient().getOpenMissingSwipes();
Utils.hideLoading(context);
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, null);
}
}
@override @override
void dispose() { void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose(); super.dispose();
chatHubConnection.stop(); chatHubConnection.stop();
} }
@ -80,7 +101,6 @@ class _DashboardScreenState extends State<DashboardScreen> {
void _onRefresh() async { void _onRefresh() async {
data.initProvider(); data.initProvider();
_bHubCon();
// data.getITGNotification().then((value) { // data.getITGNotification().then((value) {
// print("--------------------detail_1-----------------"); // print("--------------------detail_1-----------------");
// print(value!.result!.data!.notificationMasterId); // print(value!.result!.data!.notificationMasterId);
@ -323,12 +343,104 @@ class _DashboardScreenState extends State<DashboardScreen> {
], ],
), ),
], ],
).paddingOnly(left: 21, right: 21, top: 7), ).paddingOnly(left: 21, right: 21, top: 7, bottom: 21),
context.watch<MarathonProvider>().isLoading Column(
? const MarathonBannerShimmer().paddingAll(20) mainAxisSize: MainAxisSize.min,
: MarathonBanner(isMarathonUpcoming: context.watch<MarathonProvider>().isUpComingMarathon).paddingAll(20), crossAxisAlignment: CrossAxisAlignment.start,
ServicesWidget(), children: [
8.height, Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
LocaleKeys.offers.tr().toText12(),
Row(
children: [
LocaleKeys.discounts.tr().toText24(isBold: true),
6.width,
Container(
padding: const EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
color: MyColors.yellowColor,
borderRadius: BorderRadius.circular(10),
),
child: LocaleKeys.newString.tr().toText10(isBold: true)),
],
),
],
),
),
LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true).onPress(() {
Navigator.pushNamed(context, AppRoutes.offersAndDiscounts);
})
],
).paddingOnly(left: 21, right: 21),
Consumer<DashboardProviderModel>(
builder: (BuildContext context, DashboardProviderModel model, Widget? child) {
return SizedBox(
height: 103 + 33,
child: ListView.separated(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, top: 13),
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext cxt, int index) {
return model.isOffersLoading
? const OffersShimmerWidget()
: InkWell(
onTap: () {
navigateToDetails(data.getOffersList[index]);
},
child: SizedBox(
width: 73,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 73,
height: 73,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
border: Border.all(color: MyColors.lightGreyE3Color, width: 1),
),
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(50),
),
child: Hero(
tag: "ItemImage" + data.getOffersList[index].offersDiscountId.toString()!,
transitionOnUserGestures: true,
child: Image.network(
data.getOffersList[index].bannerImage!,
fit: BoxFit.contain,
),
),
),
),
4.height,
Expanded(
child: AppState().isArabic(context)
? data.getOffersList[index].titleAr!.toText12(isCenter: true, maxLine: 1)
: data.getOffersList[index].titleEn!.toText12(isCenter: true, maxLine: 1),
),
],
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => 8.width,
itemCount: 9),
);
},
),
],
),
Container( Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.only(top: 31), padding: const EdgeInsets.only(top: 31),
@ -339,101 +451,12 @@ class _DashboardScreenState extends State<DashboardScreen> {
), ),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( ServicesWidget(),
crossAxisAlignment: CrossAxisAlignment.center, context.watch<MarathonProvider>().isLoading ? const MarathonBannerShimmer().paddingAll(20) : const MarathonBanner().paddingOnly(left: 21, right: 21, bottom: 21, top: 8),
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
LocaleKeys.offers.tr().toText12(),
Row(
children: [
LocaleKeys.discounts.tr().toText24(isBold: true),
6.width,
Container(
padding: const EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
color: MyColors.yellowColor,
borderRadius: BorderRadius.circular(10),
),
child: LocaleKeys.newString.tr().toText10(isBold: true)),
],
),
],
),
),
LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true).onPress(() {
Navigator.pushNamed(context, AppRoutes.offersAndDiscounts);
})
],
).paddingOnly(left: 21, right: 21),
Consumer<DashboardProviderModel>(
builder: (BuildContext context, DashboardProviderModel model, Widget? child) {
return SizedBox(
height: 103 + 33,
child: ListView.separated(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, top: 13),
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext cxt, int index) {
return model.isOffersLoading
? const OffersShimmerWidget()
: InkWell(
onTap: () {
navigateToDetails(data.getOffersList[index]);
},
child: SizedBox(
width: 73,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 73,
height: 73,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
border: Border.all(color: MyColors.lightGreyE3Color, width: 1),
),
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(50),
),
child: Hero(
tag: "ItemImage" + data.getOffersList[index].offersDiscountId.toString()!,
transitionOnUserGestures: true,
child: Image.network(
data.getOffersList[index].bannerImage ?? "",
fit: BoxFit.contain,
),
),
),
),
4.height,
Expanded(
child: AppState().isArabic(context)
? data.getOffersList[index].titleAr!.toText12(isCenter: true, maxLine: 1)
: data.getOffersList[index].titleEn!.toText12(isCenter: true, maxLine: 1),
),
],
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => 8.width,
itemCount: 6),
);
},
),
], ],
), ),
) ),
], ],
), ),
), ),
@ -460,7 +483,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
"assets/icons/create_req.svg", "assets/icons/create_req.svg",
color: currentIndex == 1 ? MyColors.grey3AColor : MyColors.grey98Color, color: currentIndex == 1 ? MyColors.grey3AColor : MyColors.grey98Color,
).paddingAll(4), ).paddingAll(4),
label: LocaleKeys.createRequest.tr(), label: LocaleKeys.mowadhafhiRequest.tr(),
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
icon: Stack( icon: Stack(

@ -50,23 +50,23 @@ class _TodayAttendanceScreenState extends State<TodayAttendanceScreen2> {
icon: const Icon(Icons.arrow_back_ios, color: Colors.white), icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
), ),
actions: [ // actions: [
IconButton( // IconButton(
onPressed: () { // onPressed: () {
data.fetchAttendanceTracking(context); // data.fetchAttendanceTracking(context);
}, // },
icon: const Icon( // icon: const Icon(
Icons.ac_unit, // Icons.ac_unit,
color: Colors.white, // color: Colors.white,
), // ),
) // )
], // ],
), ),
backgroundColor: MyColors.backgroundBlackColor, backgroundColor: MyColors.backgroundBlackColor,
body: Consumer<DashboardProviderModel>( body: Consumer<DashboardProviderModel>(
builder: (context, model, child) { builder: (context, model, child) {
return (model.isAttendanceTrackingLoading return (model.isAttendanceTrackingLoading
? Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: Column( : Column(
children: [ children: [
Container( Container(

@ -150,13 +150,9 @@ class _AppDrawerState extends State<AppDrawer> {
Widget menuItem(String icon, String title, String routeName, {Color? color, bool closeDrawer = true, VoidCallback? onPress}) { Widget menuItem(String icon, String title, String routeName, {Color? color, bool closeDrawer = true, VoidCallback? onPress}) {
return Row( return Row(
children: [ children: [
SvgPicture.asset( SvgPicture.asset(icon, height: 20, width: 20),
icon,
height: 20,
width: 20,
),
9.width, 9.width,
title.toText14(color: color).expanded title.toText14(color: color, textAlign: AppState().isArabic(context) ? TextAlign.right : null).expanded,
], ],
).paddingOnly(left: 21, top: 10, bottom: 10, right: 21).onPress(closeDrawer ).paddingOnly(left: 21, top: 10, bottom: 10, right: 21).onPress(closeDrawer
? () async { ? () async {

@ -1,60 +0,0 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class DrawerItem extends StatefulWidget {
final String title;
final String subTitle;
final IconData icon;
final Color color;
final dynamic assetLink;
const DrawerItem(this.title, {required this.icon, required this.color, this.subTitle = '', this.assetLink});
@override
_DrawerItemState createState() => _DrawerItemState();
}
class _DrawerItemState extends State<DrawerItem> {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 0, bottom: 5, left: 0, right: 0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
if (widget.assetLink != null)
Container(
height: 20,
width: 20,
child: Image.asset(widget.assetLink),
),
if (widget.assetLink == null)
Icon(
widget.icon,
color: widget.color,
size: 25,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width * 0.45,
child: Text(widget.title,
style: TextStyle(
color: widget.color ?? Color(0xFF2E303A),
fontSize: 14,
fontFamily: 'Poppins',
fontWeight: FontWeight.w600,
letterSpacing: -0.84,
)),
),
],
),
),
],
));
}
}

@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart'; import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/date_uitl.dart'; import 'package:mohem_flutter_app/classes/date_uitl.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
@ -141,12 +142,13 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
empID: selectedID); empID: selectedID);
Utils.hideLoading(context); Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
var res = await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submit.pTRANSACTIONID!, "", "add_leave_balance", selectedEmployeeID: selectedID)); arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submit.pTRANSACTIONID!, "", "add_leave_balance", selectedEmployeeID: selectedID));
if (res != null && res == true) {
Utils.showLoading(context); if (!AppState().cancelRequestTrancsection) {
return;
} }
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submit.pTRANSACTIONID!); await LeaveBalanceApiClient().cancelHrTransaction(submit.pTRANSACTIONID!);
Utils.hideLoading(context); Utils.hideLoading(context);
} catch (ex) { } catch (ex) {

@ -72,7 +72,7 @@ class _LeaveBalanceState extends State<LeaveBalance> {
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.all(21), padding: const EdgeInsets.all(21),
children: [ children: [
BalancesDashboardWidget(LocaleKeys.currentLeaveBalance.tr(), true, selectedEmp: employeeId), BalancesDashboardWidget(LocaleKeys.currentLeaveBalance.tr(), true, selectedEmp: employeeId, showLoading: false),
12.height, 12.height,
ListView.separated( ListView.separated(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),

@ -100,16 +100,16 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
passwordConstraintsUI(LocaleKeys.doNotUseRecentPassword.tr(), true), passwordConstraintsUI(LocaleKeys.doNotUseRecentPassword.tr(), true),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneLowercase.tr(), checkRegEx(r'[a-z]')), passwordConstraintsUI(LocaleKeys.atLeastOneLowercase.tr(), checkRegEx(r'[a-z]')),
8.height, // 8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneUppercase.tr(), checkRegEx(r'[A-Z]')), // passwordConstraintsUI(LocaleKeys.atLeastOneUppercase.tr(), checkRegEx(r'[A-Z]')),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneNumeric.tr(), checkRegEx(r'[0-9]')), passwordConstraintsUI(LocaleKeys.atLeastOneNumeric.tr(), checkRegEx(r'[0-9]')),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.minimum8Characters.tr(), password.text.length >= 8), passwordConstraintsUI(LocaleKeys.minimum8Characters.tr(), password.text.length >= 8),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.doNotAddRepeatingLetters.tr(), checkRepeatedChars(password.text)), passwordConstraintsUI(LocaleKeys.doNotAddRepeatingLetters.tr(), checkRepeatedChars(password.text)),
8.height, // 8.height,
passwordConstraintsUI(LocaleKeys.itShouldContainSpecialCharacter.tr(), checkRegEx(r'[!@#$%^&*(),.?":{}|<>]')), // passwordConstraintsUI(LocaleKeys.itShouldContainSpecialCharacter.tr(), checkRegEx(r'[!@#$%^&*(),.?":{}|<>]')),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.confirmPasswordMustMatch.tr(), password.text.isNotEmpty && password.text == confirmPassword.text), passwordConstraintsUI(LocaleKeys.confirmPasswordMustMatch.tr(), password.text.isNotEmpty && password.text == confirmPassword.text),
], ],
@ -131,14 +131,14 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
return false; return false;
} }
bool hasUppercase = password.contains(RegExp(r'[A-Z]')); // bool hasUppercase = password.contains(RegExp(r'[A-Z]'));
bool hasDigits = password.contains(RegExp(r'[0-9]')); bool hasDigits = password.contains(RegExp(r'[0-9]'));
bool hasLowercase = password.contains(RegExp(r'[a-z]')); bool hasLowercase = password.contains(RegExp(r'[a-z]'));
bool hasSpecialCharacters = password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]')); // bool hasSpecialCharacters = password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'));
bool hasMinLength = password.length >= minLength; bool hasMinLength = password.length >= minLength;
bool isMatched = password == confirmPassword.text; bool isMatched = password == confirmPassword.text;
return hasDigits && hasUppercase && hasLowercase && hasSpecialCharacters && hasMinLength && isMatched && checkRepeatedChars(password); return hasDigits && hasLowercase && hasMinLength && isMatched && checkRepeatedChars(password);
} }
bool checkRepeatedChars(String password) { bool checkRepeatedChars(String password) {

@ -12,12 +12,15 @@ import 'package:mohem_flutter_app/api/login_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/notifications.dart';
import 'package:mohem_flutter_app/classes/push-notification-handler.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart';
import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart';
import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart';
@ -25,7 +28,9 @@ import 'package:mohem_flutter_app/models/member_login_list_model.dart';
import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/input_widget.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:safe_device/safe_device.dart'; import 'package:safe_device/safe_device.dart';
import 'package:wifi_iot/wifi_iot.dart';
class LoginScreen extends StatefulWidget { class LoginScreen extends StatefulWidget {
LoginScreen({Key? key}) : super(key: key); LoginScreen({Key? key}) : super(key: key);
@ -93,8 +98,11 @@ class _LoginScreenState extends State<LoginScreen> {
await Firebase.initializeApp(); await Firebase.initializeApp();
_firebaseMessaging = FirebaseMessaging.instance; _firebaseMessaging = FirebaseMessaging.instance;
firebaseToken = await _firebaseMessaging.getToken(); firebaseToken = await _firebaseMessaging.getToken();
AppNotifications().initNotification(firebaseToken);
loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios");
if (loginInfo == null) { if (loginInfo == null) {
await checkPrefs();
_autoLogin = false;
Utils.hideLoading(context); Utils.hideLoading(context);
return; return;
} else { } else {
@ -105,7 +113,7 @@ class _LoginScreenState extends State<LoginScreen> {
} }
} catch (ex) { } catch (ex) {
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, (errorMsg) {}); Utils.handleException(ex, context, null);
} }
} }
@ -152,17 +160,21 @@ class _LoginScreenState extends State<LoginScreen> {
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (isAppOpenBySystem == null) { if (isAppOpenBySystem == null) {
isAppOpenBySystem = (ModalRoute.of(context)!.settings.arguments ?? true) as bool; isAppOpenBySystem = (ModalRoute.of(context)!.settings.arguments ?? true) as bool;
if (!kReleaseMode) { if (!kReleaseMode) {
// username.text = "15444"; // Maha User // username.text = "15444"; // Maha User
// username.text = "15153"; // Tamer User username.text = "15153"; // Tamer User
// password.text = "Abcd@1234"; password.text = "Abcd@12345";
// username.text = "206535"; // Hashim User // username.text = "206535"; // Hashim User
// password.text = "Namira786"; // password.text = "Namira786";
// 13777
// Ab12345cd
} }
if (isAppOpenBySystem!) checkFirebaseToken(); if (isAppOpenBySystem!) checkFirebaseToken();
} }
@ -219,6 +231,14 @@ class _LoginScreenState extends State<LoginScreen> {
Navigator.pushNamed(context, AppRoutes.forgotPassword); Navigator.pushNamed(context, AppRoutes.forgotPassword);
}), }),
), ),
20.height,
// DefaultButton(
// "Connect HMG Network",
// () async {
// SystemChannels.textInput.invokeMethod('TextInput.hide');
// connectWithHmgNetwork();
// },
// ),
], ],
), ),
) )
@ -234,4 +254,30 @@ class _LoginScreenState extends State<LoginScreen> {
), ),
); );
} }
void connectWithHmgNetwork() async {
try {
bool isConnected = await WiFiForIoTPlugin.connect("MOHEMM-CONNECT", password: "0987654321", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false);
if (isConnected) {
await WiFiForIoTPlugin.forceWifiUsage(true);
// if (Platform.isIOS) {
// await closeWifiRequest();
// await Future.delayed(Duration(seconds: 6));
// } else {
// await WiFiForIoTPlugin.forceWifiUsage(true);
// }
}
} catch (e) {
print("----------------o----");
print(e);
}
}
Future<bool> closeWifiRequest() async {
if (Platform.isAndroid) {
await WiFiForIoTPlugin.forceWifiUsage(false);
}
return await WiFiForIoTPlugin.disconnect();
}
} }

@ -94,16 +94,16 @@ class _NewPasswordScreenState extends State<NewPasswordScreen> {
passwordConstraintsUI(LocaleKeys.doNotUseRecentPassword.tr(), true), passwordConstraintsUI(LocaleKeys.doNotUseRecentPassword.tr(), true),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneLowercase.tr(), checkRegEx(r'[a-z]')), passwordConstraintsUI(LocaleKeys.atLeastOneLowercase.tr(), checkRegEx(r'[a-z]')),
8.height, // 8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneUppercase.tr(), checkRegEx(r'[A-Z]')), // passwordConstraintsUI(LocaleKeys.atLeastOneUppercase.tr(), checkRegEx(r'[A-Z]')),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneNumeric.tr(), checkRegEx(r'[0-9]')), passwordConstraintsUI(LocaleKeys.atLeastOneNumeric.tr(), checkRegEx(r'[0-9]')),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.minimum8Characters.tr(), password.text.length >= 8), passwordConstraintsUI(LocaleKeys.minimum8Characters.tr(), password.text.length >= 8),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.doNotAddRepeatingLetters.tr(), checkRepeatedChars(password.text)), passwordConstraintsUI(LocaleKeys.doNotAddRepeatingLetters.tr(), checkRepeatedChars(password.text)),
8.height, // 8.height,
passwordConstraintsUI(LocaleKeys.itShouldContainSpecialCharacter.tr(), checkRegEx(r'[!@#$%^&*(),.?":{}|<>]')), // passwordConstraintsUI(LocaleKeys.itShouldContainSpecialCharacter.tr(), checkRegEx(r'[!@#$%^&*(),.?":{}|<>]')),
8.height, 8.height,
passwordConstraintsUI(LocaleKeys.confirmPasswordMustMatch.tr(), password.text.isNotEmpty && password.text == confirmPassword.text), passwordConstraintsUI(LocaleKeys.confirmPasswordMustMatch.tr(), password.text.isNotEmpty && password.text == confirmPassword.text),
], ],
@ -143,14 +143,14 @@ class _NewPasswordScreenState extends State<NewPasswordScreen> {
return false; return false;
} }
bool hasUppercase = password.contains(RegExp(r'[A-Z]')); // bool hasUppercase = password.contains(RegExp(r'[A-Z]'));
bool hasDigits = password.contains(RegExp(r'[0-9]')); bool hasDigits = password.contains(RegExp(r'[0-9]'));
bool hasLowercase = password.contains(RegExp(r'[a-z]')); bool hasLowercase = password.contains(RegExp(r'[a-z]'));
bool hasSpecialCharacters = password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]')); // bool hasSpecialCharacters = password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'));
bool hasMinLength = password.length >= minLength; bool hasMinLength = password.length >= minLength;
bool isMatched = password == confirmPassword.text; bool isMatched = password == confirmPassword.text;
return hasDigits && hasUppercase && hasLowercase && hasSpecialCharacters && hasMinLength && isMatched && checkRepeatedChars(password); return hasDigits && hasLowercase && hasMinLength && isMatched && checkRepeatedChars(password);
} }
bool checkRepeatedChars(String password) { bool checkRepeatedChars(String password) {

@ -23,12 +23,14 @@ class MarathonIntroScreen extends StatelessWidget {
ListView( ListView(
padding: const EdgeInsets.all(21), padding: const EdgeInsets.all(21),
children: <Widget>[ children: <Widget>[
MarathonDetailsCard(provider: provider), MarathonDetailsCard(marathonDetailModel: provider.isUpComingMarathon ? provider.marathonDetailModel : provider.demoMarathonDetailModel),
10.height, 20.height,
MarathonTimerCard( provider.isUpComingMarathon
provider: provider, ? MarathonTimerCard(
timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch, provider: provider,
), timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch,
)
: const SizedBox(),
], ],
).expanded, ).expanded,
1.divider, 1.divider,

@ -2,8 +2,8 @@ import 'dart:async';
import 'package:appinio_swiper/appinio_swiper.dart'; import 'package:appinio_swiper/appinio_swiper.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/marathon/demo_marathon_repo.dart';
import 'package:mohem_flutter_app/api/marathon/marathon_api_client.dart'; import 'package:mohem_flutter_app/api/marathon/marathon_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/consts.dart';
@ -17,11 +17,12 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
import 'package:video_player/video_player.dart'; import 'package:video_player/video_player.dart';
class MarathonProvider extends ChangeNotifier { class MarathonProvider extends ChangeNotifier {
//****************VARIABLES********** //************************************************ VARIABLES **********************************************************
final AppinioSwiperController swiperController = AppinioSwiperController(); final AppinioSwiperController swiperController = AppinioSwiperController();
MarathonDetailModel marathonDetailModel = MarathonDetailModel(); MarathonDetailModel marathonDetailModel = MarathonDetailModel();
MarathonDetailModel demoMarathonDetailModel = MarathonDetailModel();
List<CardContent> cardContentList = <CardContent>[]; List<CardContent> cardContentList = <CardContent>[];
QuestionModel currentQuestion = QuestionModel(); QuestionModel currentQuestion = QuestionModel();
List<QuestionCardStatus> answerStatusesList = <QuestionCardStatus>[]; List<QuestionCardStatus> answerStatusesList = <QuestionCardStatus>[];
@ -31,12 +32,12 @@ class MarathonProvider extends ChangeNotifier {
String? selectedOptionId; String? selectedOptionId;
int? totalQualifiers; int? totalQualifiers;
//TODO: THIS BUG NEEDS TO BE FIXED. NOT DONE YET
String? gapTimeImage; String? gapTimeImage;
String? gapTimeText; String? gapTimeText;
int? gapTimeType; int? gapTimeType;
bool iAmWinner = false; bool iAmWinner = false;
bool isGettingQualifiers = false;
bool isPrivilegedWithMarathon = false; bool isPrivilegedWithMarathon = false;
bool _isLoading = false; bool _isLoading = false;
@ -54,6 +55,7 @@ class MarathonProvider extends ChangeNotifier {
set isUpComingMarathon(bool value) { set isUpComingMarathon(bool value) {
_isUpComingMarathon = value; _isUpComingMarathon = value;
notifyListeners(); notifyListeners();
} }
@ -66,6 +68,33 @@ class MarathonProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
bool _canPlayDemo = true;
bool get canPlayDemo => _canPlayDemo;
set canPlayDemo(bool value) {
_canPlayDemo = value;
notifyListeners();
}
bool _isButtonEnabled = false;
bool get isButtonEnabled => _isButtonEnabled;
set isButtonEnabled(bool value) {
_isButtonEnabled = value;
notifyListeners();
}
bool _isUserWaiting = false;
bool get isUserWaiting => _isUserWaiting;
set isUserWaiting(bool value) {
_isUserWaiting = value;
notifyListeners();
}
bool _isMarathonCompleted = false; bool _isMarathonCompleted = false;
bool get isMarathonCompleted => _isMarathonCompleted; bool get isMarathonCompleted => _isMarathonCompleted;
@ -119,7 +148,9 @@ class MarathonProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
//****************TIMERS********** // 9c47d281-c5b5-4b5d-a90a-08dacb8cbdb6
// MarathonI
//************************************************ TIMERS **********************************************************
int sponsorsSecondsCounter = 0; int sponsorsSecondsCounter = 0;
int totalSponsorVideoSeconds = 0; int totalSponsorVideoSeconds = 0;
@ -144,7 +175,13 @@ class MarathonProvider extends ChangeNotifier {
); );
} }
int totalSecondsToWaitForMarathon = 20; int totalSecondsToWaitForMarathon = 30;
set updateTotalSecondsToWaitForMarathon(int value) {
totalSecondsToWaitForMarathon = value;
notifyListeners();
}
Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
void startTimerToWaitForMarathon() { void startTimerToWaitForMarathon() {
@ -153,7 +190,13 @@ class MarathonProvider extends ChangeNotifier {
oneSec, oneSec,
(Timer timer) async { (Timer timer) async {
if (totalSecondsToWaitForMarathon == 0) { if (totalSecondsToWaitForMarathon == 0) {
callNextQuestionApi(); if (isUserWaiting) {
MarathonApiClient().joinMarathonAsParticipant().whenComplete(() async {
await callNextQuestionApi();
});
} else {
isButtonEnabled = false;
}
timer.cancel(); timer.cancel();
return; return;
} else { } else {
@ -173,23 +216,33 @@ class MarathonProvider extends ChangeNotifier {
timerForQuestion = Timer.periodic( timerForQuestion = Timer.periodic(
oneSec, oneSec,
(Timer timer) async { (Timer timer) async {
// This 2 is just to show the color of answer tile for 2 seconds and then update card status // This 2 is just to show the color of answer tile for 1 and then update card status
if (totalCurrentQuestionTime - currentGapTime == 1) { if (totalCurrentQuestionTime - currentGapTime == 1) {
getCorrectAnswerAndUpdateAnswerColor(); getCorrectAnswerAndUpdateAnswerColor();
} }
if (totalCurrentQuestionTime == currentGapTime) { if (totalCurrentQuestionTime - currentGapTime == -2) {
totalCurrentQuestionTime--;
updateCardStatusToAnswer(); updateCardStatusToAnswer();
scheduleMicrotask(() async { // scheduleMicrotask(() async {
await callSubmitOptionApi().then((bool value) async { // if (AppState().getIsDemoMarathon || isUserOutOfGame) {
if (value) { // await callNextQuestionApi();
await callNextQuestionApi(); // } else {
} // await callSubmitOptionApi().then((bool value) async {
}); // updateIsUserOutOfGame = !value;
}); // await callNextQuestionApi();
// });
// }
// });
if (currentQuestionNumber == (AppState().getIsDemoMarathon ? demoMarathonDetailModel.totalQuestions! : marathonDetailModel.totalQuestions!)) {
isGettingQualifiers = true;
updateQuestionCardStatus(QuestionCardStatus.findingWinner);
timer.cancel();
cancelTimer();
notifyListeners();
}
totalCurrentQuestionTime--;
} }
if (totalCurrentQuestionTime == 0) { if (totalCurrentQuestionTime == 0) {
@ -197,16 +250,10 @@ class MarathonProvider extends ChangeNotifier {
gapTimeText = currentQuestion.gapText; gapTimeText = currentQuestion.gapText;
gapTimeType = currentQuestion.gapType; gapTimeType = currentQuestion.gapType;
updateCardData(); updateCardData();
if (currentQuestionNumber - 1 == marathonDetailModel.totalQuestions!) {
callGetQualifiersApi();
updateQuestionCardStatus(QuestionCardStatus.findingWinner);
timer.cancel();
cancelTimer();
notifyListeners();
}
return; return;
} else { } else {
if (totalCurrentQuestionTime != currentGapTime) { if (totalCurrentQuestionTime - currentGapTime != -2) {
totalCurrentQuestionTime--; totalCurrentQuestionTime--;
} }
} }
@ -224,10 +271,13 @@ class MarathonProvider extends ChangeNotifier {
timerForWinnerSelection = Timer.periodic( timerForWinnerSelection = Timer.periodic(
oneSec, oneSec,
(Timer timer) async { (Timer timer) async {
if (totalSecondsToWaitForWinner == 0) { if (totalSecondsToWaitForWinner == 1) {
await callGetSelectedWinnersApi().whenComplete(() => updateQuestionCardStatus(QuestionCardStatus.winnerFound));
timer.cancel(); timer.cancel();
updateQuestionCardStatus(QuestionCardStatus.winnerFound);
return; return;
} else if (totalSecondsToWaitForWinner == 15) {
totalSecondsToWaitForWinner--;
await callGetQualifiersApi();
} else { } else {
totalSecondsToWaitForWinner--; totalSecondsToWaitForWinner--;
} }
@ -237,18 +287,26 @@ class MarathonProvider extends ChangeNotifier {
); );
} }
//****************FUNCTIONS********* //************************************************ FUNCTIONS **********************************************************
Future<bool> callSubmitOptionApi() async { Future<bool> callSubmitOptionApi() async {
return await MarathonApiClient().submitSelectedOption(marathonId: marathonDetailModel.id!, questionId: currentQuestion.id, selectedAnswerId: selectedOptionId); return await MarathonApiClient().submitSelectedOption(marathonId: marathonDetailModel.id!, questionId: currentQuestion.id, selectedAnswerId: selectedOptionId);
} }
Future<void> callGetQualifiersApi() async { Future<void> callGetQualifiersApi() async {
totalQualifiers = await MarathonApiClient().getQualifiers(marathonId: marathonDetailModel.id!); if (AppState().getIsDemoMarathon) {
totalQualifiers = isUserOutOfGame ? 0 : 1;
} else {
totalQualifiers = await MarathonApiClient().getQualifiers(marathonId: marathonDetailModel.id!);
}
isGettingQualifiers = false;
notifyListeners(); notifyListeners();
} }
Future<void> callGetSelectedWinnersApi() async { Future<void> callGetSelectedWinnersApi() async {
if (AppState().getIsDemoMarathon) {
return;
}
selectedWinners = await MarathonApiClient().getSelectedWinner(marathonId: marathonDetailModel.id!); selectedWinners = await MarathonApiClient().getSelectedWinner(marathonId: marathonDetailModel.id!);
if (selectedWinners != null) { if (selectedWinners != null) {
selectedWinners!.removeWhere((WinnerModel element) { selectedWinners!.removeWhere((WinnerModel element) {
@ -265,10 +323,14 @@ class MarathonProvider extends ChangeNotifier {
} }
Future<void> callNextQuestionApi() async { Future<void> callNextQuestionApi() async {
if (currentQuestionNumber < marathonDetailModel.totalQuestions!) { if (currentQuestionNumber < (AppState().getIsDemoMarathon ? demoMarathonDetailModel.totalQuestions! : marathonDetailModel.totalQuestions!)) {
if (currentQuestionNumber == 0) { if (currentQuestionNumber == 0) {
Utils.showLoading(AppRoutes.navigatorKey.currentContext!); if (!AppState().getIsDemoMarathon) {
currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!))!; Utils.showLoading(AppRoutes.navigatorKey.currentContext!);
}
currentQuestion = AppState().getIsDemoMarathon
? await DemoMarathonRepo().getDemoNextQuestion(currentQuestionNumber: currentQuestionNumber)
: (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!));
gapTimeImage = currentQuestion.gapImage; gapTimeImage = currentQuestion.gapImage;
gapTimeText = currentQuestion.gapText; gapTimeText = currentQuestion.gapText;
gapTimeType = currentQuestion.gapType; gapTimeType = currentQuestion.gapType;
@ -277,10 +339,11 @@ class MarathonProvider extends ChangeNotifier {
} }
startTimerForQuestion(); startTimerForQuestion();
updateCardData(); updateCardData();
Navigator.pushReplacementNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.marathonScreen); Navigator.pushReplacementNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.marathonScreen);
} else { } else {
currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: currentQuestion.id, marathonId: marathonDetailModel.id!))!; currentQuestion = AppState().getIsDemoMarathon
? await DemoMarathonRepo().getDemoNextQuestion(currentQuestionNumber: currentQuestionNumber)
: (await MarathonApiClient().getNextQuestion(questionId: currentQuestion.id, marathonId: marathonDetailModel.id!));
} }
notifyListeners(); notifyListeners();
} }
@ -302,12 +365,21 @@ class MarathonProvider extends ChangeNotifier {
} }
void populateQuestionStatusesList() { void populateQuestionStatusesList() {
if (marathonDetailModel.totalQuestions != null) { answerStatusesList.clear();
for (int i = 0; i < marathonDetailModel.totalQuestions!; i++) { if (demoMarathonDetailModel.totalQuestions != null) {
for (int i = 0; i < demoMarathonDetailModel.totalQuestions!; i++) {
answerStatusesList.add(QuestionCardStatus.question); answerStatusesList.add(QuestionCardStatus.question);
} }
notifyListeners(); notifyListeners();
} }
if (isUpComingMarathon) {
if (marathonDetailModel.totalQuestions != null) {
for (int i = 0; i < marathonDetailModel.totalQuestions!; i++) {
answerStatusesList.add(QuestionCardStatus.question);
}
notifyListeners();
}
}
} }
void updateAnswerStatusesList(QuestionCardStatus status) { void updateAnswerStatusesList(QuestionCardStatus status) {
@ -325,13 +397,16 @@ class MarathonProvider extends ChangeNotifier {
currentQuestion.questionOptions![i].optionStatus = QuestionsOptionStatus.unSelected; currentQuestion.questionOptions![i].optionStatus = QuestionsOptionStatus.unSelected;
} }
currentQuestion.questionOptions![index].optionStatus = status; currentQuestion.questionOptions![index].optionStatus = status;
selectedOptionId = currentQuestion.questionOptions![index].id;
selectedOptionIndex = index; selectedOptionIndex = index;
notifyListeners(); notifyListeners();
} }
void updateQuestionCardStatus(QuestionCardStatus status) { void updateQuestionCardStatus(QuestionCardStatus status) {
if (status == QuestionCardStatus.wrongAnswer || status == QuestionCardStatus.skippedAnswer) { if (status == QuestionCardStatus.wrongAnswer || status == QuestionCardStatus.skippedAnswer) {
updateIsUserOutOfGame = true; if (AppState().getIsDemoMarathon) {
updateIsUserOutOfGame = true;
}
} }
questionCardStatus = status; questionCardStatus = status;
notifyListeners(); notifyListeners();
@ -339,10 +414,31 @@ class MarathonProvider extends ChangeNotifier {
void getCorrectAnswerAndUpdateAnswerColor() { void getCorrectAnswerAndUpdateAnswerColor() {
if (selectedOptionIndex != null) { if (selectedOptionIndex != null) {
if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { scheduleMicrotask(() async {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!); if (AppState().getIsDemoMarathon) {
} else { if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!); updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!);
} else {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!);
}
} else {
await callSubmitOptionApi().then((bool value) async {
updateIsUserOutOfGame = !value;
if (value) {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!);
} else {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!);
}
});
}
});
} else {
if (!AppState().getIsDemoMarathon) {
scheduleMicrotask(() async {
await callSubmitOptionApi().then((bool value) async {
updateIsUserOutOfGame = !value;
});
});
} }
} }
} }
@ -352,7 +448,16 @@ class MarathonProvider extends ChangeNotifier {
return; return;
} }
if (selectedOptionIndex != null) { scheduleMicrotask(() async {
await callNextQuestionApi();
});
if (selectedOptionIndex == null) {
updateQuestionCardStatus(QuestionCardStatus.skippedAnswer);
updateAnswerStatusesList(QuestionCardStatus.skippedAnswer);
return;
}
if (AppState().getIsDemoMarathon) {
if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) {
updateQuestionCardStatus(QuestionCardStatus.correctAnswer); updateQuestionCardStatus(QuestionCardStatus.correctAnswer);
updateAnswerStatusesList(QuestionCardStatus.correctAnswer); updateAnswerStatusesList(QuestionCardStatus.correctAnswer);
@ -360,27 +465,43 @@ class MarathonProvider extends ChangeNotifier {
updateQuestionCardStatus(QuestionCardStatus.wrongAnswer); updateQuestionCardStatus(QuestionCardStatus.wrongAnswer);
updateAnswerStatusesList(QuestionCardStatus.wrongAnswer); updateAnswerStatusesList(QuestionCardStatus.wrongAnswer);
} }
} else { return;
updateQuestionCardStatus(QuestionCardStatus.skippedAnswer);
updateAnswerStatusesList(QuestionCardStatus.skippedAnswer);
} }
if (!isUserOutOfGame) {
updateQuestionCardStatus(QuestionCardStatus.correctAnswer);
updateAnswerStatusesList(QuestionCardStatus.correctAnswer);
return;
}
updateQuestionCardStatus(QuestionCardStatus.wrongAnswer);
updateAnswerStatusesList(QuestionCardStatus.wrongAnswer);
} }
void resetValues() async { void resetValues() async {
_currentQuestionNumber = 0; _currentQuestionNumber = 0;
cardContentList.clear(); cardContentList.clear();
itsMarathonTime = false;
timerForWinnerSelection.cancel(); timerForWinnerSelection.cancel();
timerForSponsorVideo.cancel(); timerForSponsorVideo.cancel();
timerToWaitForMarathon.cancel(); timerToWaitForMarathon.cancel();
timerForQuestion.cancel(); timerForQuestion.cancel();
_isMarathonCompleted = false; _isMarathonCompleted = false;
isUserOutOfGame = false; isUserOutOfGame = false;
isButtonEnabled = false;
isUserWaiting = false;
canPlayDemo = true;
totalCurrentQuestionTime = 0; totalCurrentQuestionTime = 0;
sponsorsSecondsCounter = 0; sponsorsSecondsCounter = 0;
totalSponsorVideoSeconds = 0; totalSponsorVideoSeconds = 0;
totalSecondsToWaitForMarathon = 20; totalSecondsToWaitForWinner = 30;
totalSecondsToWaitForMarathon = 30;
AppState().setIsDemoMarathon = false;
currentGapTime = 0; currentGapTime = 0;
currentQuestion = QuestionModel(); currentQuestion = QuestionModel();
if (answerStatusesList.isNotEmpty) {
for (int i = 0; i < answerStatusesList.length; i++) {
answerStatusesList[i] = QuestionCardStatus.question;
}
}
notifyListeners(); notifyListeners();
} }
@ -390,7 +511,6 @@ class MarathonProvider extends ChangeNotifier {
} }
bool checkIfPrivilegedForMarathon() { bool checkIfPrivilegedForMarathon() {
return true;
for (PrivilegeListModel element in AppState().privilegeListModel!) { for (PrivilegeListModel element in AppState().privilegeListModel!) {
if (element.serviceName == "Marathon") { if (element.serviceName == "Marathon") {
if (element.previlege != null) { if (element.previlege != null) {
@ -405,17 +525,23 @@ class MarathonProvider extends ChangeNotifier {
isLoading = true; isLoading = true;
notifyListeners(); notifyListeners();
isPrivilegedWithMarathon = checkIfPrivilegedForMarathon(); isPrivilegedWithMarathon = checkIfPrivilegedForMarathon();
demoMarathonDetailModel = await DemoMarathonRepo().getDemoMarathonDetails();
if (isPrivilegedWithMarathon) { if (isPrivilegedWithMarathon) {
await MarathonApiClient().getMarathonToken().whenComplete(() async { marathonDetailModel = await MarathonApiClient().getMarathonDetails();
marathonDetailModel = await MarathonApiClient().getMarathonDetails(); updateTotalSecondsToWaitForMarathon = marathonDetailModel.marathonBufferTime ?? 30;
if (marathonDetailModel.id == null) { if (marathonDetailModel.id == null) {
isUpComingMarathon = false; isUpComingMarathon = false;
isLoading = false; isLoading = false;
notifyListeners();
return;
}
populateQuestionStatusesList(); populateQuestionStatusesList();
}); notifyListeners();
return;
}
isUpComingMarathon = true;
if (DateTime.parse(marathonDetailModel.startTime!).isAfter(DateTime.now())) {
itsMarathonTime = false;
}
populateQuestionStatusesList();
} }
isLoading = false; isLoading = false;
notifyListeners(); notifyListeners();
@ -423,18 +549,15 @@ class MarathonProvider extends ChangeNotifier {
Future<void> onJoinMarathonPressed(BuildContext context) async { Future<void> onJoinMarathonPressed(BuildContext context) async {
try { try {
Utils.showLoading(context); isUserWaiting = true;
resetValues(); Navigator.pushReplacementNamed(context, AppRoutes.marathonWaitingScreen);
int? remainingTime = await MarathonApiClient().joinMarathonAsParticipant();
if (remainingTime != null) {
totalSecondsToWaitForMarathon = remainingTime;
notifyListeners();
startTimerToWaitForMarathon();
Navigator.pushReplacementNamed(context, AppRoutes.marathonWaitingScreen);
}
} catch (e) { } catch (e) {
Utils.hideLoading(context);
Utils.confirmDialog(context, e.toString()); Utils.confirmDialog(context, e.toString());
} }
} }
Future<void> onJoinDemoMarathonPressed(BuildContext context) async {
AppState().setIsDemoMarathon = true;
await callNextQuestionApi();
}
} }

@ -36,102 +36,188 @@ class MarathonScreen extends StatelessWidget {
} }
return gapText.toText18(color: MyColors.darkTextColor, isCentered: true); return gapText.toText18(color: MyColors.darkTextColor, isCentered: true);
} }
if (gapType == 2) { if (gapType == 0) {
if (gapImage == null) { if (gapImage == null) {
return Image.asset(MyLottieConsts.congratsGif, height: 200); return Image.asset(MyLottieConsts.congratsGif, height: 200);
} }
return Image.network(gapImage, height: 200); return Image.network(ApiConsts.marathonBaseUrlServices + gapImage, height: 200);
} }
return Image.asset(MyLottieConsts.congratsGif, height: 200); return Image.asset(MyLottieConsts.congratsGif, height: 200);
} }
Widget getDemoWinnerWidget(BuildContext context, {required MarathonProvider provider}) {
return provider.isUserOutOfGame
? Column(
children: <Widget>[
Lottie.asset(MyLottieConsts.noWinnerLottie),
Center(
child: LocaleKeys.noWinner.tr().toText18(color: MyColors.grey3AColor, isCentered: true),
),
],
)
: Stack(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 50,
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: SvgPicture.asset("assets/images/winner_ribbon.svg", height: 50),
),
Align(
alignment: Alignment.center,
child: LocaleKeys.winner.tr().toText32(color: MyColors.white, isBold: true, isCentered: true).paddingOnly(top: 07),
)
],
),
),
16.height,
Column(
children: <Widget>[
(AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn)!.toText22(
color: MyColors.grey3AColor,
isCentered: true,
),
8.height,
AppState().memberInformationList!.eMPLOYEENUMBER!.toText22(color: MyColors.grey57Color),
],
),
60.height,
if (provider.demoMarathonDetailModel.sponsors != null && provider.demoMarathonDetailModel.sponsors!.isNotEmpty) ...<Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
"${LocaleKeys.sponsoredBy.tr()} ".toText14(color: MyColors.grey77Color),
(AppState().isArabic(context) ? provider.demoMarathonDetailModel.sponsors!.first.nameAr ?? "" : provider.demoMarathonDetailModel.sponsors!.first.nameEn ?? "").toText14(
color: MyColors.darkTextColor,
isBold: true,
),
],
),
5.height,
Image.network(
ApiConsts.marathonBaseUrlServices + provider.demoMarathonDetailModel.sponsors!.first.logo!,
height: 50,
width: 150,
fit: BoxFit.contain,
errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
return Image.asset("assets/images/logos/main_mohemm_logo.png", height: 50, width: 150);
},
)
],
],
),
Lottie.asset(MyLottieConsts.celebrate1Lottie),
],
);
}
Widget getWinnerWidget(BuildContext context, {required MarathonProvider provider}) { Widget getWinnerWidget(BuildContext context, {required MarathonProvider provider}) {
return Container( return Container(
width: double.infinity, width: double.infinity,
decoration: MyDecorations.shadowDecoration, decoration: MyDecorations.shadowDecoration,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20), padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: Stack( child: (AppState().getIsDemoMarathon)
children: <Widget>[ ? getDemoWinnerWidget(context, provider: provider)
Column( : provider.selectedWinners == null || (provider.selectedWinners!.isEmpty && !provider.iAmWinner)
mainAxisAlignment: MainAxisAlignment.center, ? Column(
children: <Widget>[
SizedBox(
height: 50,
child: Stack(
children: <Widget>[ children: <Widget>[
Align( Lottie.asset(MyLottieConsts.noWinnerLottie),
alignment: Alignment.center, Center(
child: SvgPicture.asset("assets/images/winner_ribbon.svg", height: 50), child: LocaleKeys.noWinner.tr().toText18(color: MyColors.grey3AColor, isCentered: true),
), ),
Align(
alignment: Alignment.center,
child: LocaleKeys.winners.tr().toText32(color: MyColors.white, isBold: true, isCentered: true).paddingOnly(top: 07),
)
], ],
), )
), : Stack(
16.height, children: <Widget>[
provider.iAmWinner Column(
? Column( mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
(AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn)!.toText22(
color: MyColors.grey3AColor,
isCentered: true,
),
8.height,
AppState().memberInformationList!.eMPLOYEENUMBER!.toText22(color: MyColors.grey57Color),
],
)
: const SizedBox(),
36.height,
if (provider.selectedWinners != null) ...<Widget>[
ListView.separated(
shrinkWrap: true,
itemCount: provider.selectedWinners!.length,
separatorBuilder: (BuildContext context, int index) {
return const Divider();
},
itemBuilder: (BuildContext context, int index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
(AppState().isArabic(context) ? provider.selectedWinners![index].nameEn : provider.selectedWinners![index].nameEn)!.toText16( SizedBox(
color: MyColors.grey3AColor, height: 50,
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: SvgPicture.asset("assets/images/winner_ribbon.svg", height: 50),
),
Align(
alignment: Alignment.center,
child: ((provider.selectedWinners!.length == 1 && !provider.iAmWinner) || (provider.selectedWinners!.isEmpty && provider.iAmWinner)
? LocaleKeys.winner.tr()
: LocaleKeys.winners.tr())
.toText32(color: MyColors.white, isBold: true, isCentered: true)
.paddingOnly(top: 07),
)
],
),
), ),
provider.selectedWinners!.first.employeeId!.toText16(color: MyColors.grey57Color), 16.height,
provider.iAmWinner
? Column(
children: <Widget>[
(AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn)!.toText22(
color: MyColors.grey3AColor,
isCentered: true,
),
8.height,
AppState().memberInformationList!.eMPLOYEENUMBER!.toText22(color: MyColors.grey57Color),
],
)
: const SizedBox(),
36.height,
if (provider.selectedWinners != null) ...<Widget>[
ListView.separated(
shrinkWrap: true,
itemCount: provider.selectedWinners!.length,
separatorBuilder: (BuildContext context, int index) {
return const Divider();
},
itemBuilder: (BuildContext context, int index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(AppState().isArabic(context) ? provider.selectedWinners![index].nameEn : provider.selectedWinners![index].nameEn)!.toText16(
color: MyColors.grey3AColor,
),
provider.selectedWinners!.first.employeeId!.toText16(color: MyColors.grey57Color),
],
);
},
),
],
60.height,
if (provider.marathonDetailModel.sponsors != null && provider.marathonDetailModel.sponsors!.isNotEmpty) ...<Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
"${LocaleKeys.sponsoredBy.tr()} ".toText14(color: MyColors.grey77Color),
(AppState().isArabic(context) ? provider.marathonDetailModel.sponsors!.first.nameAr ?? "" : provider.marathonDetailModel.sponsors!.first.nameEn ?? "").toText14(
color: MyColors.darkTextColor,
isBold: true,
),
],
),
5.height,
Image.network(
ApiConsts.marathonBaseUrlServices + provider.marathonDetailModel.sponsors!.first.logo!,
height: 50,
width: 150,
fit: BoxFit.contain,
errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
return Image.asset("assets/images/logos/main_mohemm_logo.png", height: 50, width: 150);
},
)
],
], ],
);
},
),
],
60.height,
if (provider.marathonDetailModel.sponsors != null && provider.marathonDetailModel.sponsors!.isNotEmpty) ...<Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
"${LocaleKeys.sponsoredBy.tr()} ".toText14(color: MyColors.grey77Color),
(AppState().isArabic(context) ? provider.marathonDetailModel.sponsors!.first.nameAr ?? "" : provider.marathonDetailModel.sponsors!.first.nameEn ?? "").toText14(
color: MyColors.darkTextColor,
isBold: true,
), ),
Lottie.asset(MyLottieConsts.celebrate1Lottie),
], ],
), ),
5.height,
Image.network(
ApiConsts.marathonBaseUrlServices + provider.marathonDetailModel.sponsors!.first.image!,
height: 50,
width: 150,
fit: BoxFit.contain,
errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
return const Center();
},
)
],
],
),
Lottie.asset(MyLottieConsts.celebrate1Lottie),
],
),
); );
} }
@ -166,6 +252,7 @@ class MarathonScreen extends StatelessWidget {
onHomeTapped: () { onHomeTapped: () {
if (provider.questionCardStatus == QuestionCardStatus.winnerFound) { if (provider.questionCardStatus == QuestionCardStatus.winnerFound) {
provider.resetValues(); provider.resetValues();
provider.getMarathonDetailsFromApi();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
} else { } else {
showDialog( showDialog(
@ -174,6 +261,7 @@ class MarathonScreen extends StatelessWidget {
message: LocaleKeys.youWantToLeaveMarathon.tr(), message: LocaleKeys.youWantToLeaveMarathon.tr(),
onTap: () { onTap: () {
provider.resetValues(); provider.resetValues();
provider.getMarathonDetailsFromApi();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
}, },
), ),
@ -183,6 +271,7 @@ class MarathonScreen extends StatelessWidget {
onBackTapped: () { onBackTapped: () {
if (provider.questionCardStatus == QuestionCardStatus.winnerFound) { if (provider.questionCardStatus == QuestionCardStatus.winnerFound) {
provider.resetValues(); provider.resetValues();
provider.getMarathonDetailsFromApi();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
} else { } else {
showDialog( showDialog(
@ -201,8 +290,8 @@ class MarathonScreen extends StatelessWidget {
body: Column( body: Column(
children: <Widget>[ children: <Widget>[
ListView( ListView(
children: [ children: <Widget>[
20.height, 10.height,
if (provider.questionCardStatus == QuestionCardStatus.findingWinner) ...<Widget>[ if (provider.questionCardStatus == QuestionCardStatus.findingWinner) ...<Widget>[
QualifiersContainer(provider: provider).paddingOnly(left: 21, right: 21), QualifiersContainer(provider: provider).paddingOnly(left: 21, right: 21),
] else if (provider.questionCardStatus == QuestionCardStatus.winnerFound) ] else if (provider.questionCardStatus == QuestionCardStatus.winnerFound)
@ -237,7 +326,7 @@ class MarathonScreen extends StatelessWidget {
subTitle: LocaleKeys.youMissedTheQuestion.tr().toText18(color: MyColors.darkTextColor, isCentered: true), subTitle: LocaleKeys.youMissedTheQuestion.tr().toText18(color: MyColors.darkTextColor, isCentered: true),
), ),
onFindingWinner: (BuildContext context) => CustomStatusWidget( onFindingWinner: (BuildContext context) => CustomStatusWidget(
asset: Lottie.asset(MyLottieConsts.winnerLottie, height: 168), asset: Lottie.asset(MyLottieConsts.winnerLottie, height: 168, reverse: false),
title: LocaleKeys.fingersCrossed.tr().toText22(color: MyColors.greenColor), title: LocaleKeys.fingersCrossed.tr().toText22(color: MyColors.greenColor),
subTitle: LocaleKeys.winnerSelectedRandomly.tr().toText18(color: MyColors.darkTextColor, isCentered: true), subTitle: LocaleKeys.winnerSelectedRandomly.tr().toText18(color: MyColors.darkTextColor, isCentered: true),
), ),
@ -248,6 +337,7 @@ class MarathonScreen extends StatelessWidget {
provider.questionCardStatus == QuestionCardStatus.winnerFound provider.questionCardStatus == QuestionCardStatus.winnerFound
? DefaultButton(LocaleKeys.ok.tr(), () { ? DefaultButton(LocaleKeys.ok.tr(), () {
provider.resetValues(); provider.resetValues();
provider.getMarathonDetailsFromApi();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
}).insideContainer }).insideContainer
: const SizedBox() : const SizedBox()

@ -15,16 +15,16 @@ import 'package:video_player/video_player.dart';
class SponsorVideoScreen extends StatelessWidget { class SponsorVideoScreen extends StatelessWidget {
const SponsorVideoScreen({Key? key}) : super(key: key); const SponsorVideoScreen({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MarathonProvider provider = context.watch<MarathonProvider>(); MarathonProvider provider = context.read<MarathonProvider>();
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
provider.videoController.dispose(); provider.timerForSponsorVideo.cancel();
provider.videoController.pause();
provider.disposeVideoPlayer();
provider.sponsorsSecondsCounter = 0; provider.sponsorsSecondsCounter = 0;
provider.totalSponsorVideoSeconds = 0; provider.totalSponsorVideoSeconds = 0;
provider.timerForSponsorVideo.cancel();
return Future<bool>.value(true); return Future<bool>.value(true);
}, },
child: Scaffold( child: Scaffold(
@ -49,47 +49,56 @@ class SponsorVideoScreen extends StatelessWidget {
borderRadius: provider.totalSponsorVideoSeconds == 0 ? null : BorderRadius.circular(15), borderRadius: provider.totalSponsorVideoSeconds == 0 ? null : BorderRadius.circular(15),
), ),
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8),
child: provider.totalSponsorVideoSeconds == 0 child: Consumer<MarathonProvider>(
? InkWell( builder: (BuildContext context, MarathonProvider provider, Widget? child) {
onTap: () { return provider.totalSponsorVideoSeconds == 0
provider.videoController.dispose(); ? InkWell(
provider.sponsorsSecondsCounter = 0; onTap: () {
provider.totalSponsorVideoSeconds = 0; Navigator.pushReplacementNamed(context, AppRoutes.marathonIntroScreen);
provider.timerForSponsorVideo.cancel(); provider.videoController.pause();
Navigator.pushReplacementNamed(context, AppRoutes.marathonIntroScreen); provider.disposeVideoPlayer();
}, provider.sponsorsSecondsCounter = 0;
child: const Icon(Icons.close, size: 12), provider.totalSponsorVideoSeconds = 0;
) provider.timerForSponsorVideo.cancel();
: Directionality( },
textDirection: ui.TextDirection.ltr, child: const Icon(Icons.close, size: 12),
child: ("${LocaleKeys.ourSponsor.tr()} ${provider.totalSponsorVideoSeconds < 10 ? "0" : ""}${provider.totalSponsorVideoSeconds}").toText12(color: MyColors.darkTextColor), )
), : Directionality(
textDirection: ui.TextDirection.ltr,
child: ("${LocaleKeys.ourSponsor.tr()} ${provider.totalSponsorVideoSeconds < 10 ? "0" : ""}${provider.totalSponsorVideoSeconds}").toText12(color: MyColors.darkTextColor),
);
},
),
), ),
).paddingOnly(top: 20, right: 18), ).paddingOnly(top: 20, right: 18),
Consumer<MarathonProvider>(
//TODO: WE WILL INCREASE THIS 2 BEFORE GOING LIVE builder: (BuildContext context, MarathonProvider provider, Widget? child) {
provider.sponsorsSecondsCounter >= 2 //TODO: WE WILL INCREASE THIS 2 BEFORE GOING LIVE
? Align( return provider.sponsorsSecondsCounter >= 2
alignment: Alignment.topLeft, ? Align(
child: InkWell( alignment: Alignment.topLeft,
onTap: () { child: InkWell(
provider.videoController.dispose(); onTap: () {
provider.sponsorsSecondsCounter = 0; Navigator.pushReplacementNamed(context, AppRoutes.marathonIntroScreen);
provider.totalSponsorVideoSeconds = 0; provider.videoController.pause();
provider.timerForSponsorVideo.cancel(); provider.disposeVideoPlayer();
Navigator.pushReplacementNamed(context, AppRoutes.marathonIntroScreen); provider.sponsorsSecondsCounter = 0;
}, provider.totalSponsorVideoSeconds = 0;
child: Container( provider.timerForSponsorVideo.cancel();
decoration: BoxDecoration(color: MyColors.white, borderRadius: BorderRadius.circular(15)), },
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 6), child: Container(
child: Directionality( decoration: BoxDecoration(color: MyColors.white, borderRadius: BorderRadius.circular(15)),
textDirection: ui.TextDirection.ltr, padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 6),
child: LocaleKeys.skip.tr().toText11(color: MyColors.darkTextColor), child: Directionality(
textDirection: ui.TextDirection.ltr,
child: LocaleKeys.skip.tr().toText11(color: MyColors.darkTextColor),
),
),
), ),
), ).paddingOnly(top: 20, left: 18)
), : const SizedBox();
).paddingOnly(top: 20, left: 18) },
: const SizedBox(), ),
], ],
), ),
), ),

@ -80,24 +80,24 @@ class MarathonWaitingScreen extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
LocaleKeys.startingIn.tr().toText16(), LocaleKeys.startingIn.tr().toText16(),
provider.totalSecondsToWaitForMarathon.toString().toText18(color: provider.totalSecondsToWaitForMarathon < 5 ? MyColors.redColor : MyColors.black), (provider.totalSecondsToWaitForMarathon < 10 ? "0${provider.totalSecondsToWaitForMarathon.toString()}" : provider.totalSecondsToWaitForMarathon.toString()).toText18(color: provider.totalSecondsToWaitForMarathon < 5 ? MyColors.redColor : MyColors.black),
],
),
),
Align(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
InkWell(
onTap: () {
provider.callNextQuestionApi();
provider.timerToWaitForMarathon.cancel();
},
child: "Join Now".toText16(),
).paddingOnly(bottom: 20),
], ],
), ),
), ),
// Align(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.end,
// children: <Widget>[
// InkWell(
// onTap: () {
// provider.callNextQuestionApi();
// provider.timerToWaitForMarathon.cancel();
// },
// child: "Join Now".toText16(),
// ).paddingOnly(bottom: 20),
// ],
// ),
// ),
], ],
), ),
).expanded, ).expanded,

@ -0,0 +1,212 @@
import 'dart:async';
import 'dart:ui' as ui;
import 'package:auto_size_text/auto_size_text.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_countdown_timer/current_remaining_time.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
class CountdownTimerForDetailScreen extends StatelessWidget {
final int timeToMarathon;
final MarathonProvider provider;
CountdownTimerForDetailScreen({
Key? key,
required this.provider,
required this.timeToMarathon,
}) : super(key: key);
final TextStyle styleTextHome = TextStyle(
color: MyColors.white.withOpacity(0.45),
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w800,
letterSpacing: -0.4,
);
final TextStyle styleDigitHome = TextStyle(
height: 22 / 27,
color: MyColors.white,
fontSize: isTablet ? 30 : 15,
fontStyle: FontStyle.italic,
letterSpacing: -1.44,
fontWeight: FontWeight.bold,
);
final TextStyle styleTextMarathon = const TextStyle(
fontSize: 10,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w600,
color: MyColors.grey57Color,
letterSpacing: -0.4,
);
final TextStyle styleDigitMarathon = const TextStyle(
height: 23 / 24,
color: MyColors.darkTextColor,
fontSize: 34,
letterSpacing: -1.44,
fontWeight: FontWeight.bold,
);
Widget buildSeparator() {
return AutoSizeText(
" : ",
maxFontSize: 24,
minFontSize: 20,
style: styleDigitMarathon,
);
}
Widget getTimeDigit(String text) {
return AutoSizeText(
text,
maxFontSize: 24,
minFontSize: 20,
style: styleDigitMarathon,
);
}
Widget getTimeText(String text) {
return AutoSizeText(
text,
minFontSize: 7,
maxFontSize: 8,
style: styleTextMarathon,
);
}
Widget buildEmptyWidget() {
return Directionality(
textDirection: ui.TextDirection.ltr,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
children: <Widget>[
getTimeDigit("00"),
getTimeText(LocaleKeys.days.tr()),
],
),
buildSeparator(),
Column(
children: <Widget>[
getTimeDigit("00"),
getTimeText(LocaleKeys.hours.tr()),
],
),
buildSeparator(),
Column(
children: <Widget>[
getTimeDigit("00"),
getTimeText(LocaleKeys.minutes.tr()),
],
),
buildSeparator(),
Column(
children: <Widget>[
getTimeDigit("00"),
getTimeText(LocaleKeys.seconds.tr()),
],
),
],
),
);
}
Widget buildCountdownTimer(CurrentRemainingTime? time) {
if (provider.marathonDetailModel.startTime != null) {
int remainingTimeInMinutes = DateTime.parse(provider.marathonDetailModel.startTime!).difference(DateTime.now()).inMinutes;
if (remainingTimeInMinutes <= 30) {
scheduleMicrotask(() {
provider.canPlayDemo = false;
});
}
}
if (time == null) {
if (!provider.itsMarathonTime) {
scheduleMicrotask(() {
provider.itsMarathonTime = true;
provider.isButtonEnabled = true;
provider.startTimerToWaitForMarathon();
});
}
return provider.itsMarathonTime
? Directionality(
textDirection: ui.TextDirection.ltr,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
children: <Widget>[
getTimeDigit(provider.totalSecondsToWaitForMarathon.toString()),
getTimeText(LocaleKeys.seconds.tr()),
],
),
],
),
)
: buildEmptyWidget();
}
return Directionality(
textDirection: ui.TextDirection.ltr,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
children: <Widget>[
time.days == null ? getTimeDigit("00") : getTimeDigit(time.days! < 10 ? "0${time.days.toString()}" : time.days.toString()),
getTimeText(LocaleKeys.days.tr()),
],
),
buildSeparator(),
Column(
children: <Widget>[
time.hours == null ? getTimeDigit("00") : getTimeDigit(time.hours! < 10 ? "0${time.hours.toString()}" : time.hours.toString()),
getTimeText(LocaleKeys.hours.tr()),
],
),
buildSeparator(),
Column(
children: <Widget>[
time.min == null ? getTimeDigit("00") : getTimeDigit(time.min! < 10 ? "0${time.min.toString()}" : time.min.toString()),
getTimeText(LocaleKeys.minutes.tr()),
],
),
buildSeparator(),
Column(
children: <Widget>[
time.sec == null ? getTimeDigit("00") : getTimeDigit(time.sec! < 10 ? "0${time.sec.toString()}" : time.sec.toString()),
getTimeText(LocaleKeys.seconds.tr()),
],
),
],
),
);
}
@override
Widget build(BuildContext context) {
return CountdownTimer(
// endTime: dummyTime,
endTime: timeToMarathon,
onEnd: null,
widgetBuilder: (BuildContext context, CurrentRemainingTime? time) {
return buildCountdownTimer(time);
},
);
}
}

@ -1,4 +1,3 @@
import 'dart:async';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
@ -11,16 +10,14 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
class BuildCountdownTimer extends StatelessWidget { class CountdownTimerForMainScreen extends StatelessWidget {
final int timeToMarathon; final int timeToMarathon;
final MarathonProvider provider; final MarathonProvider provider;
final int screenFlag;
BuildCountdownTimer({ CountdownTimerForMainScreen({
Key? key, Key? key,
required this.provider, required this.provider,
required this.timeToMarathon, required this.timeToMarathon,
required this.screenFlag,
}) : super(key: key); }) : super(key: key);
final TextStyle styleTextHome = TextStyle( final TextStyle styleTextHome = TextStyle(
@ -60,7 +57,7 @@ class BuildCountdownTimer extends StatelessWidget {
" : ", " : ",
maxFontSize: 24, maxFontSize: 24,
minFontSize: 20, minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, style: styleDigitHome,
); );
} }
@ -69,7 +66,7 @@ class BuildCountdownTimer extends StatelessWidget {
text, text,
maxFontSize: 24, maxFontSize: 24,
minFontSize: 20, minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, style: styleDigitHome,
); );
} }
@ -78,7 +75,7 @@ class BuildCountdownTimer extends StatelessWidget {
text, text,
minFontSize: 7, minFontSize: 7,
maxFontSize: 8, maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon, style: styleTextHome,
); );
} }
@ -124,14 +121,9 @@ class BuildCountdownTimer extends StatelessWidget {
Widget buildCountdownTimer(CurrentRemainingTime? time) { Widget buildCountdownTimer(CurrentRemainingTime? time) {
if (time == null) { if (time == null) {
if (!provider.itsMarathonTime) {
scheduleMicrotask(() {
provider.itsMarathonTime = true;
});
}
return buildEmptyWidget(); return buildEmptyWidget();
} }
return Directionality( return Directionality(
textDirection: ui.TextDirection.ltr, textDirection: ui.TextDirection.ltr,
child: Row( child: Row(

@ -1,3 +1,4 @@
import 'dart:developer';
import 'dart:math' as math; import 'dart:math' as math;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -10,17 +11,19 @@ import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/countdown_timer.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/countdown_timer_main_screen.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MarathonBanner extends StatelessWidget { // It is used to pass a dummy time to test Marathon
final bool isMarathonUpcoming; int dummyTime = DateTime.now().millisecondsSinceEpoch + 8690;
const MarathonBanner({Key? key, required this.isMarathonUpcoming}) : super(key: key); class MarathonBanner extends StatelessWidget {
const MarathonBanner({Key? key}) : super(key: key);
Widget getUnPrivilegedMarathon(BuildContext context) { Widget getUnPrivilegedMarathon(BuildContext context) {
return Container( return Container(
@ -180,13 +183,174 @@ class MarathonBanner extends StatelessWidget {
); );
} }
Widget getNoUpcomingMarathonWidget(BuildContext context) {
return Container(
decoration: MyDecorations.shadowDecoration,
height: isTablet ? MediaQuery.of(context).size.height * 0.17 : MediaQuery.of(context).size.height * 0.11,
clipBehavior: Clip.antiAlias,
child: Stack(
children: <Widget>[
Transform(
alignment: Alignment.center,
transform: Matrix4.rotationY(
AppState().isArabic(context) ? math.pi : 0,
),
child: SvgPicture.asset(
"assets/images/marathon_banner_bg.svg",
fit: BoxFit.fill,
width: double.infinity,
),
),
AppState().isArabic(context)
? Positioned(
right: -15,
top: -10,
child: Transform.rotate(
angle: 10,
child: Container(
width: isTablet ? 70 : 65,
height: isTablet ? 40 : 32,
color: MyColors.darkDigitColor,
),
),
)
: Positioned(
left: -20,
top: -10,
child: Transform.rotate(
angle: 15,
child: Container(
width: isTablet ? 70 : 65,
height: isTablet ? 40 : 32,
color: MyColors.darkDigitColor,
),
),
),
SizedBox(
width: double.infinity,
height: double.infinity,
child: Row(
children: <Widget>[
const Expanded(
flex: 3,
child: SizedBox(
width: double.infinity,
height: double.infinity,
),
),
Expanded(
flex: AppState().isArabic(context) ? 4 : 5,
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
AppState().isArabic(context) ? 0.height : 5.height,
Text(
LocaleKeys.noUpcoming.tr(),
style: TextStyle(
fontSize: isTablet ? 20 : 11,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w600,
color: MyColors.white.withOpacity(0.83),
letterSpacing: -0.4,
),
),
Text(
LocaleKeys.brainMarathon.tr(),
style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: isTablet ? 30 : 19,
fontWeight: FontWeight.bold,
color: MyColors.white.withOpacity(0.83),
height: 32 / 22,
),
),
Text(
LocaleKeys.youCanPlayDemo.tr(),
style: TextStyle(
fontSize: isTablet ? 20 : 11,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w600,
color: MyColors.white.withOpacity(0.83),
letterSpacing: -0.4,
),
),
],
).paddingOnly(
left: AppState().isArabic(context) ? 12 : 3,
right: AppState().isArabic(context) ? 3 : 12,
)
],
),
),
),
],
),
),
AppState().isArabic(context)
? Align(
alignment: Alignment.topRight,
child: SizedBox(
height: isTablet ? 30 : 20,
width: isTablet ? 45 : 35,
child: Transform.rotate(
angle: math.pi / 4.5,
child: Text(
LocaleKeys.brainMarathon.tr(),
textAlign: TextAlign.center,
maxLines: 2,
style: TextStyle(
color: MyColors.white,
fontWeight: FontWeight.bold,
fontSize: isTablet ? 8 : 6,
height: 1.2,
),
),
),
),
).paddingOnly(top: 5)
: Align(
alignment: Alignment.topLeft,
child: SizedBox(
height: isTablet ? 30 : 20,
width: isTablet ? 45 : 35,
child: Transform.rotate(
angle: -math.pi / 4.5,
child: Text(
LocaleKeys.brainMarathon.tr(),
textAlign: TextAlign.center,
maxLines: 2,
style: TextStyle(
color: MyColors.kWhiteColor,
fontWeight: FontWeight.bold,
fontSize: isTablet ? 8 : 6,
height: 1.2,
),
),
),
),
).paddingOnly(top: 5),
],
),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.marathonIntroScreen);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MarathonProvider provider = context.read<MarathonProvider>(); MarathonProvider provider = context.read<MarathonProvider>();
return provider.isPrivilegedWithMarathon return !provider.isPrivilegedWithMarathon
? getUnPrivilegedMarathon(context) ? getUnPrivilegedMarathon(context)
: provider.marathonDetailModel.startTime != null : provider.isUpComingMarathon
? Container( ? Container(
decoration: MyDecorations.shadowDecoration, decoration: MyDecorations.shadowDecoration,
height: isTablet ? MediaQuery.of(context).size.height * 0.17 : MediaQuery.of(context).size.height * 0.11, height: isTablet ? MediaQuery.of(context).size.height * 0.17 : MediaQuery.of(context).size.height * 0.11,
@ -265,21 +429,23 @@ class MarathonBanner extends StatelessWidget {
letterSpacing: -0.4, letterSpacing: -0.4,
), ),
), ),
Text( Flexible(
AppState().isArabic(context) ? provider.marathonDetailModel.titleAr ?? "" : provider.marathonDetailModel.titleEn ?? "", child: Text(
style: TextStyle( (AppState().isArabic(context) ? provider.marathonDetailModel.titleAr ?? "" : provider.marathonDetailModel.titleEn ?? "").trimString(15),
fontStyle: FontStyle.italic, overflow: TextOverflow.ellipsis,
fontSize: isTablet ? 30 : 19, style: TextStyle(
fontWeight: FontWeight.bold, fontStyle: FontStyle.italic,
color: MyColors.white.withOpacity(0.83), fontSize: isTablet ? 30 : 19,
height: 32 / 22, fontWeight: FontWeight.bold,
color: MyColors.white.withOpacity(0.83),
height: 32 / 22,
),
), ),
), ),
isTablet ? 10.height : 3.height, isTablet ? 10.height : 3.height,
BuildCountdownTimer( CountdownTimerForMainScreen(
timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch, timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch,
provider: provider, provider: provider,
screenFlag: 0,
), ),
], ],
).paddingOnly( ).paddingOnly(
@ -357,7 +523,7 @@ class MarathonBanner extends StatelessWidget {
).onPress(() async { ).onPress(() async {
int remainingTimeInMinutes = DateTime.parse(provider.marathonDetailModel.startTime!).difference(DateTime.now()).inMinutes; int remainingTimeInMinutes = DateTime.parse(provider.marathonDetailModel.startTime!).difference(DateTime.now()).inMinutes;
if (remainingTimeInMinutes > 2) { if (remainingTimeInMinutes > 5 && provider.marathonDetailModel.sponsors != null && provider.marathonDetailModel.sponsors!.isNotEmpty) {
Utils.showLoading(context); Utils.showLoading(context);
try { try {
await provider.initializeVideoPlayer().then((_) { await provider.initializeVideoPlayer().then((_) {
@ -367,7 +533,7 @@ class MarathonBanner extends StatelessWidget {
}); });
} catch (e) { } catch (e) {
if (kDebugMode) { if (kDebugMode) {
print("Error in VideoPlayer: ${e.toString()}"); log("Error in VideoPlayer: ${e.toString()}");
} }
Utils.hideLoading(context); Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.marathonIntroScreen); Navigator.pushNamed(context, AppRoutes.marathonIntroScreen);
@ -376,8 +542,7 @@ class MarathonBanner extends StatelessWidget {
Navigator.pushNamed(context, AppRoutes.marathonIntroScreen); Navigator.pushNamed(context, AppRoutes.marathonIntroScreen);
} }
}), }),
// );
) )
: const SizedBox(); : getNoUpcomingMarathonWidget(context);
} }
} }

@ -6,72 +6,96 @@ import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/marathon/marathon_model.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
import 'package:provider/provider.dart';
class MarathonDetailsCard extends StatelessWidget { class MarathonDetailsCard extends StatelessWidget {
final MarathonProvider provider; final MarathonDetailModel marathonDetailModel;
const MarathonDetailsCard({Key? key, required this.provider}) : super(key: key); const MarathonDetailsCard({Key? key, required this.marathonDetailModel}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
width: double.infinity, width: double.infinity,
decoration: MyDecorations.shadowDecoration, decoration: MyDecorations.shadowDecoration,
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 14), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 14),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Column( context.read<MarathonProvider>().isUpComingMarathon
crossAxisAlignment: CrossAxisAlignment.start, ? const SizedBox()
children: <Widget>[ : Row(
LocaleKeys.contestTopicAbout.tr().toText16(color: MyColors.grey77Color), mainAxisAlignment: MainAxisAlignment.end,
"${AppState().isArabic(context) ? provider.marathonDetailModel.titleAr : provider.marathonDetailModel.titleEn}".toText20(color: MyColors.textMixColor, isBold: true), children: [
Row( Container(
children: <Widget>[ decoration: BoxDecoration(color: MyColors.yellowColorII, borderRadius: BorderRadius.circular(100)),
Flexible( child: LocaleKeys.demo.tr().toText10(color: MyColors.white).paddingAll(4),
child: "${AppState().isArabic(context) ? provider.marathonDetailModel.descAr : provider.marathonDetailModel.descEn}".toText14(color: MyColors.grey77Color), ),
)
],
),
if (provider.marathonDetailModel.sponsors != null) ...<Widget>[
5.height,
provider.marathonDetailModel.sponsors?.first.sponsorPrizes != null
? Row(
children: <Widget>[
"${LocaleKeys.prize.tr()} ".toText16(color: MyColors.grey77Color, isBold: true),
"${AppState().isArabic(context) ? provider.marathonDetailModel.sponsors?.first.sponsorPrizes?.first.marathonPrizeAr : provider.marathonDetailModel.sponsors?.first.sponsorPrizes?.first.marathonPrizeAr}"
.toText16(color: MyColors.greenColor, isBold: true),
],
)
: const SizedBox(),
Row(
children: <Widget>[
"${LocaleKeys.sponsoredBy.tr()} ".toText16(color: MyColors.grey77Color),
"${AppState().isArabic(context) ? provider.marathonDetailModel.sponsors?.first.nameAr : provider.marathonDetailModel.sponsors?.first.nameEn}"
.toText16(color: MyColors.darkTextColor, isBold: true),
],
),
10.height,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.network(
ApiConsts.marathonBaseUrlServices + provider.marathonDetailModel.sponsors!.first.image!,
height: 50,
width: 150,
fit: BoxFit.contain,
errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
return const Center();
},
)
], ],
), ),
] 7.height,
LocaleKeys.contestTopicAbout.tr().toText16(color: MyColors.grey77Color),
"${AppState().isArabic(context) ? marathonDetailModel.titleAr : marathonDetailModel.titleEn}".toText20(color: MyColors.textMixColor, isBold: true),
Row(
children: <Widget>[
Flexible(
child: "${AppState().isArabic(context) ? marathonDetailModel.descAr : marathonDetailModel.descEn}".toText14(color: MyColors.grey77Color),
)
], ],
), ),
if (marathonDetailModel.sponsors != null && marathonDetailModel.sponsors!.isNotEmpty) ...<Widget>[
5.height,
marathonDetailModel.sponsors!.first.sponsorPrizes != null
? Row(
children: <Widget>[
"${LocaleKeys.prize.tr()} ".toText16(color: MyColors.grey77Color, isBold: true),
Expanded(
child: SizedBox(
height: 30,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: marathonDetailModel.sponsors!.first.sponsorPrizes!.length,
itemBuilder: (BuildContext context, int index) {
SponsorPrizes prizes = marathonDetailModel.sponsors!.first.sponsorPrizes![index];
return Container(
decoration: BoxDecoration(color: MyColors.backgroundColor, borderRadius: BorderRadius.circular(100), border: Border.all(color: MyColors.grey57Color.withOpacity(0.1))),
child: "${AppState().isArabic(context) ? prizes.marathonPrizeAr : prizes.marathonPrizeEn}"
.toText16(color: MyColors.greenColor, isBold: true)
.paddingOnly(left: 5, right: 5),
).paddingOnly(left: 5);
}),
),
)
],
)
: const SizedBox(),
Row(
children: <Widget>[
"${LocaleKeys.sponsoredBy.tr()} ".toText16(color: MyColors.grey77Color),
"${AppState().isArabic(context) ? marathonDetailModel.sponsors?.first.nameAr : marathonDetailModel.sponsors?.first.nameEn}".toText16(color: MyColors.darkTextColor, isBold: true),
],
),
10.height,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.network(
ApiConsts.marathonBaseUrlServices + marathonDetailModel.sponsors!.first.logo!,
height: 50,
width: 150,
fit: BoxFit.contain,
errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
return Image.asset("assets/images/logos/main_mohemm_logo.png", height: 50, width: 150);
},
)
],
),
]
], ],
), ),
); );

@ -41,9 +41,15 @@ class MarathonFooter extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DefaultButton( return provider.isUpComingMarathon && !provider.canPlayDemo
LocaleKeys.joinMarathon.tr(), ? DefaultButton(
!provider.itsMarathonTime ? () => provider.onJoinMarathonPressed(context) : null, LocaleKeys.joinMarathon.tr(),
).insideContainer; provider.isButtonEnabled ? () => provider.onJoinMarathonPressed(context) : null,
).insideContainer
: DefaultButton(
LocaleKeys.joinDemoMarathon.tr(),
() => provider.onJoinDemoMarathonPressed(context),
color: MyColors.yellowColorII,
).insideContainer;
} }
} }

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -14,37 +15,67 @@ class MarathonProgressContainer extends StatelessWidget {
const MarathonProgressContainer({Key? key, required this.provider}) : super(key: key); const MarathonProgressContainer({Key? key, required this.provider}) : super(key: key);
Widget getDemoMarathonerText() {
if (provider.isUserOutOfGame) {
return "0 ${LocaleKeys.marathoner.tr()}".toText14();
}
return "1 ${LocaleKeys.marathoner.tr()}".toText14();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
width: double.infinity, width: double.infinity,
decoration: MyDecorations.shadowDecoration, decoration: MyDecorations.shadowDecoration,
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 13), padding: EdgeInsets.fromLTRB(13, AppState().getIsDemoMarathon ? 5 : 18, 13, 18),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
AppState().getIsDemoMarathon
? Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
decoration: BoxDecoration(color: MyColors.yellowColorII, borderRadius: BorderRadius.circular(100)),
child: LocaleKeys.demo.tr().toText10(color: MyColors.white).paddingAll(4),
),
],
)
: const SizedBox(),
5.height,
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
Container( Container(
decoration: BoxDecoration(color: MyColors.greenColor, borderRadius: BorderRadius.circular(5)), decoration: BoxDecoration(color: MyColors.greenColor, borderRadius: BorderRadius.circular(5)),
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8),
child: "${provider.currentQuestionNumber.toString()} / ${provider.marathonDetailModel.totalQuestions.toString()} ${LocaleKeys.question.tr()}".toText12(color: MyColors.white), child:
"${provider.currentQuestionNumber.toString()} / ${AppState().getIsDemoMarathon ? provider.demoMarathonDetailModel.totalQuestions.toString() : provider.marathonDetailModel.totalQuestions.toString()} ${LocaleKeys.question.tr()}"
.toText12(color: MyColors.white),
), ),
"${provider.totalMarathoners} ${LocaleKeys.marathoners.tr()}".toText14(), AppState().getIsDemoMarathon
? getDemoMarathonerText()
: "${provider.totalMarathoners} ${provider.totalMarathoners == 1 ? LocaleKeys.marathoner.tr() : LocaleKeys.marathoners.tr()}".toText14(),
provider.questionCardStatus == QuestionCardStatus.question provider.questionCardStatus == QuestionCardStatus.question
? "00:${(provider.totalCurrentQuestionTime - provider.currentGapTime) < 10 ? "0${provider.totalCurrentQuestionTime - provider.currentGapTime}" : provider.totalCurrentQuestionTime - provider.currentGapTime}" ? "00:${provider.totalCurrentQuestionTime - provider.currentGapTime < 0 ? "00" : (provider.totalCurrentQuestionTime - provider.currentGapTime) < 10 ? "0${provider.totalCurrentQuestionTime - provider.currentGapTime}" : provider.totalCurrentQuestionTime - provider.currentGapTime}"
.toText18(color: provider.totalCurrentQuestionTime - provider.currentGapTime < 5 ? MyColors.redColor : MyColors.black) .toText18(color: provider.totalCurrentQuestionTime - provider.currentGapTime < 5 ? MyColors.redColor : MyColors.black)
: const SizedBox(), : const SizedBox(),
], ],
), ),
12.height, 12.height,
stepper(provider.currentQuestionNumber, provider.answerStatusesList, provider.marathonDetailModel.totalQuestions!, provider.isUserOutOfGame), stepper(
provider.currentQuestionNumber,
provider.answerStatusesList,
AppState().getIsDemoMarathon ? provider.demoMarathonDetailModel.totalQuestions! : provider.marathonDetailModel.totalQuestions!,
provider.isUserOutOfGame,
),
8.height, 8.height,
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
"${provider.currentQuestionNumber == 1 ? 0 : (((provider.currentQuestionNumber - 1) / provider.marathonDetailModel.totalQuestions!) * 100).toInt()}% ${LocaleKeys.completed.tr()}" "${provider.currentQuestionNumber == 1 ? 0 : (((provider.currentQuestionNumber - 1) / (AppState().getIsDemoMarathon ? provider.demoMarathonDetailModel.totalQuestions! : provider.marathonDetailModel.totalQuestions!)) * 100).toInt()}% ${LocaleKeys.completed.tr()}"
.toText14(), .toText14(),
provider.isUserOutOfGame ? LocaleKeys.youAreOutOfContest.tr().toText13(color: MyColors.redColor) : const SizedBox(),
], ],
), ),
], ],
@ -93,21 +124,28 @@ class MarathonProgressContainer extends StatelessWidget {
Widget roundContainer(Color color, bool isNeedLeftBorder) { Widget roundContainer(Color color, bool isNeedLeftBorder) {
if (isNeedLeftBorder) { if (isNeedLeftBorder) {
return Row( return Row(
children: [ children: <Widget>[
Divider(thickness: 6, color: color).expanded, Divider(
thickness: 6,
color: color,
).expanded,
Container( Container(
margin: EdgeInsets.zero,
padding: EdgeInsets.zero,
width: 10, width: 10,
height: 10, height: 10,
decoration: BoxDecoration(shape: BoxShape.circle, color: color), decoration: BoxDecoration(shape: BoxShape.circle, color: color, border: Border.all(color: color, width: 2)),
), ),
], ],
).expanded; ).expanded;
} }
return Container( return Container(
margin: EdgeInsets.zero,
padding: EdgeInsets.zero,
width: 10, width: 10,
height: 10, height: 10,
decoration: BoxDecoration(shape: BoxShape.circle, color: color), decoration: BoxDecoration(shape: BoxShape.circle, color: color, border: Border.all(color: color, width: 2)),
); );
} }
} }

@ -1,7 +1,9 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/classes/lottie_consts.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
@ -20,7 +22,6 @@ class _QualifiersContainerState extends State<QualifiersContainer> {
@override @override
void initState() { void initState() {
widget.provider.startTimerForWinnerSelection(); widget.provider.startTimerForWinnerSelection();
widget.provider.callGetSelectedWinnersApi();
super.initState(); super.initState();
} }
@ -42,14 +43,23 @@ class _QualifiersContainerState extends State<QualifiersContainer> {
], ],
), ),
10.height, 10.height,
Row( widget.provider.isGettingQualifiers
crossAxisAlignment: CrossAxisAlignment.end, ? Container(
children: <Widget>[ alignment: Alignment.centerLeft,
widget.provider.totalQualifiers != null ? widget.provider.totalQualifiers.toString().toText30(color: MyColors.greenColor, isBold: true) : const SizedBox(), child: Lottie.asset(
2.width, MyLottieConsts.loadingLottie,
LocaleKeys.qualifiers.tr().toText16(color: MyColors.greenColor), width: 60,
], fit: BoxFit.fill,
), ),
)
: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
widget.provider.totalQualifiers != null ? widget.provider.totalQualifiers.toString().toText30(color: MyColors.greenColor, isBold: true) : const SizedBox(),
2.width,
(widget.provider.totalQualifiers == 1 ? LocaleKeys.qualifier.tr() : LocaleKeys.qualifiers.tr()).toText16(color: MyColors.greenColor),
],
),
], ],
), ),
); );

@ -9,7 +9,8 @@ import 'package:mohem_flutter_app/classes/lottie_consts.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/countdown_timer.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/countdown_timer_detail_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/marathon_banner.dart';
class MarathonTimerCard extends StatelessWidget { class MarathonTimerCard extends StatelessWidget {
@ -43,7 +44,11 @@ class MarathonTimerCard extends StatelessWidget {
], ],
), ),
Lottie.asset(MyLottieConsts.hourGlassLottie, height: 200), Lottie.asset(MyLottieConsts.hourGlassLottie, height: 200),
BuildCountdownTimer(timeToMarathon: timeToMarathon, provider: provider, screenFlag: 1), CountdownTimerForDetailScreen(
// timeToMarathon: dummyTime,
timeToMarathon: timeToMarathon,
provider: provider,
),
], ],
), ),
); );

@ -65,7 +65,6 @@ class CardContent extends StatelessWidget {
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Container( Container(
height: 78,
width: double.infinity, width: double.infinity,
decoration: const BoxDecoration( decoration: const BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
@ -84,9 +83,9 @@ class CardContent extends StatelessWidget {
), ),
child: Center( child: Center(
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 13), padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 15),
child: Text( child: Text(
AppState().isArabic(context) ? provider.currentQuestion.titleAr ?? "" : provider.currentQuestion.titleEn ?? "", AppState().isArabic(context) ? "${provider.currentQuestion.titleAr}" ?? "" : provider.currentQuestion.titleEn ?? "",
style: const TextStyle( style: const TextStyle(
color: MyColors.white, color: MyColors.white,
fontSize: 16, fontSize: 16,
@ -110,7 +109,7 @@ class AnswerContent extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
MarathonProvider provider = context.watch<MarathonProvider>(); MarathonProvider provider = context.watch<MarathonProvider>();
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: 31, horizontal: 13), padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 13),
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: MyColors.kWhiteColor, color: MyColors.kWhiteColor,
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
@ -126,7 +125,11 @@ class AnswerContent extends StatelessWidget {
return AnswerTileForText( return AnswerTileForText(
index: index, index: index,
onAnswerTapped: () { onAnswerTapped: () {
provider.updateCurrentQuestionOptionStatus(QuestionsOptionStatus.selected, index); if (provider.totalCurrentQuestionTime - provider.currentGapTime <= 1) {
null;
} else {
provider.updateCurrentQuestionOptionStatus(QuestionsOptionStatus.selected, index);
}
}, },
); );
}, },
@ -169,7 +172,7 @@ class AnswerTileForText extends StatelessWidget {
child: Center( child: Center(
child: (AppState().isArabic(context) ? provider.currentQuestion.questionOptions![index].titleAr! : provider.currentQuestion.questionOptions![index].titleEn!) child: (AppState().isArabic(context) ? provider.currentQuestion.questionOptions![index].titleAr! : provider.currentQuestion.questionOptions![index].titleEn!)
.toText16(color: provider.isUserOutOfGame ? MyColors.darkTextColor : getAnswerTextColor(provider.currentQuestion.questionOptions![index].optionStatus!)) .toText16(color: provider.isUserOutOfGame ? MyColors.darkTextColor : getAnswerTextColor(provider.currentQuestion.questionOptions![index].optionStatus!))
.paddingOnly(top: 17, bottom: 17), .paddingOnly(top: 13, bottom: 13),
), ),
), ),
); );

@ -1,93 +0,0 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:lottie/lottie.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/classes/lottie_consts.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
class WinnerScreen extends StatelessWidget {
const WinnerScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyColors.backgroundColor,
appBar: AppBarWidget(context, title: LocaleKeys.brainMarathon.tr()),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
60.height,
Container(
width: double.infinity,
decoration: MyDecorations.shadowDecoration,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: Column(
children: <Widget>[
SizedBox(
height: 200,
child: Stack(
children: <Widget>[
Lottie.asset(
MyLottieConsts.celebrate1Lottie,
height: 200,
),
Lottie.asset(
MyLottieConsts.celebrate2Lottie,
height: 200,
),
],
),
),
26.height,
SizedBox(
height: 50,
child: Stack(
children: [
Align(
alignment: Alignment.center,
child: SvgPicture.asset(
"assets/images/winner_ribbon.svg",
height: 50,
),
),
Align(
alignment: Alignment.center,
child: "WINNER".toText32(color: MyColors.white, isBold: true).paddingOnly(top: 07),
)
],
),
),
12.height,
"Muhammad Shrouff".toText22(color: MyColors.grey3AColor),
"837436".toText22(color: MyColors.grey57Color),
80.height,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
LocaleKeys.sponsoredBy.tr().toText14(color: MyColors.grey77Color),
" Extra".toText14(color: MyColors.darkTextColor, isBold: true),
],
),
5.height,
Image.asset(
"assets/images/logos/main_mohemm_logo.png",
height: 40,
fit: BoxFit.fill,
width: 150,
)
],
),
).paddingOnly(left: 21, right: 21),
10.height,
],
),
),
);
}
}

@ -1,8 +1,6 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart'; import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/my_attendance_api_client.dart'; import 'package:mohem_flutter_app/api/my_attendance_api_client.dart';
@ -58,6 +56,7 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
AppState().cancelRequestTrancsection = true;
} }
void getApproverList() async { void getApproverList() async {
@ -138,9 +137,9 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
params!.transactionId, params!.transactionId,
); );
} else {} } else {}
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.showToast(LocaleKeys.yourRequestHasBeenSubmittedForApprovals.tr(), longDuration: true); Utils.showToast(LocaleKeys.yourRequestHasBeenSubmittedForApprovals.tr(), longDuration: true);
AppState().cancelRequestTrancsection = false;
Navigator.of(context).popUntil((route) => route.settings.name == AppRoutes.dashboard); Navigator.of(context).popUntil((route) => route.settings.name == AppRoutes.dashboard);
Navigator.pushNamed(context, AppRoutes.workList); Navigator.pushNamed(context, AppRoutes.workList);
} catch (ex) { } catch (ex) {
@ -262,7 +261,7 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
title.toText16().expanded, title.toText16().expanded,
6.width, 6.width,
SimpleButton(LocaleKeys.add.tr(), () async { SimpleButton(LocaleKeys.add.tr(), () async {
ImageOptions.showImageOptionsNew(context, false, (String image, File file) { ImageOptions.showImageOptionsNew(context, true, (String image, File file) {
setState(() { setState(() {
attachmentFiles.add(file); attachmentFiles.add(file);
attachments.add(image); attachments.add(image);

@ -5,6 +5,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart'; import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/my_attendance_api_client.dart'; import 'package:mohem_flutter_app/api/my_attendance_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -95,6 +96,9 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
Utils.hideLoading(context); Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit')); arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit'));
if (!AppState().cancelRequestTrancsection) {
return;
}
Utils.showLoading(context); Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!); await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!);
Utils.hideLoading(context); Utils.hideLoading(context);
@ -189,7 +193,8 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
// Utils.hideLoading(context); // Utils.hideLoading(context);
} }
} else if (values.isNotEmpty) { } else if (values.isNotEmpty) {
ESERVICESDV defaultValue = await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values, empID: dynamicParams!.selectedEmp); ESERVICESDV defaultValue =
await MyAttendanceApiClient().getDefaultValue(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values, empID: dynamicParams!.selectedEmp);
int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId); int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId);
getEitDffStructureList![index].eSERVICESDV = defaultValue; getEitDffStructureList![index].eSERVICESDV = defaultValue;
} }

@ -1,11 +1,16 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/profile_api_client.dart'; import 'package:mohem_flutter_app/api/profile_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/dyanmic_forms/validate_eit_transaction_model.dart'; import 'package:mohem_flutter_app/models/dyanmic_forms/validate_eit_transaction_model.dart';
@ -17,11 +22,16 @@ import 'package:mohem_flutter_app/models/profile/get_contact_details_list.dart';
import 'package:mohem_flutter_app/models/profile/submit_contact_transaction_list_model.dart'; import 'package:mohem_flutter_app/models/profile/submit_contact_transaction_list_model.dart';
import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart'; import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
import 'package:easy_localization/src/public_ext.dart';
class FamilyMemberScreenParams {
String? actionType;
int relationID;
int? flag;
FamilyMemberScreenParams(this.relationID, {this.actionType, this.flag});
}
class AddUpdateFamilyMember extends StatefulWidget { class AddUpdateFamilyMember extends StatefulWidget {
const AddUpdateFamilyMember({Key? key}) : super(key: key); const AddUpdateFamilyMember({Key? key}) : super(key: key);
@ -36,10 +46,12 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
List<GetContactDffStructureList?> getContactDffStructureList = []; List<GetContactDffStructureList?> getContactDffStructureList = [];
List<GetContactDetailsList?> getContactDetailsList = []; List<GetContactDetailsList?> getContactDetailsList = [];
SubmitContactTransactionList? submitContactTransactionList; SubmitContactTransactionList? submitContactTransactionList;
dynamic args;
//dynamic args;
FamilyMemberScreenParams? params;
String? date = "MM/DD/YYYY"; String? date = "MM/DD/YYYY";
var dateTime = DateTime.now().timeZoneOffset; Duration dateTime = DateTime.now().timeZoneOffset;
var dateTime1 = DateTime.now().timeZoneName; String dateTime1 = DateTime.now().timeZoneName;
GetApprovesList? getApprovesList; GetApprovesList? getApprovesList;
@ -52,9 +64,9 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
getBasicDetDffStructureList = await ProfileApiClient().getBasicDetDffStructure(); getBasicDetDffStructureList = await ProfileApiClient().getBasicDetDffStructure();
getContactColsStructureList = await ProfileApiClient().getContactColsStructureList(args['actionType']); getContactColsStructureList = await ProfileApiClient().getContactColsStructureList(params!.actionType.toString());
getContactDffStructureList = await ProfileApiClient().getContactDffStructureList(); getContactDffStructureList = await ProfileApiClient().getContactDffStructureList();
if (args['actionType'] == "ADD") { if (params!.actionType == "ADD") {
getBasicDetDffStructureList?.forEach((element) { getBasicDetDffStructureList?.forEach((element) {
element?.getContactDetailsList = new GetContactDetailsList(); element?.getContactDetailsList = new GetContactDetailsList();
}); });
@ -64,8 +76,8 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
getContactDffStructureList?.forEach((element) { getContactDffStructureList?.forEach((element) {
element?.getContactDetailsList = new GetContactDetailsList(); element?.getContactDetailsList = new GetContactDetailsList();
}); });
} else if (args['actionType'] == "UPDATE") { } else if (params!.actionType == "UPDATE") {
getContactDetailsList = await ProfileApiClient().getContactDetailsList(args['relationID']); getContactDetailsList = await ProfileApiClient().getContactDetailsList(params!.relationID);
getBasicDetDffStructureList?.forEach((element) { getBasicDetDffStructureList?.forEach((element) {
element?.getContactDetailsList = getContactDetailsList?.singleWhere((userDetail) => userDetail?.aPPLICATIONCOLUMNNAME == element?.aPPLICATIONCOLUMNNAME); element?.getContactDetailsList = getContactDetailsList?.singleWhere((userDetail) => userDetail?.aPPLICATIONCOLUMNNAME == element?.aPPLICATIONCOLUMNNAME);
@ -88,8 +100,8 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (args == null) { if (params == null) {
args = ModalRoute.of(context)!.settings.arguments; params = ModalRoute.of(context)!.settings.arguments as FamilyMemberScreenParams;
callAddAndUpdateFamilyMember(); callAddAndUpdateFamilyMember();
} }
return Scaffold( return Scaffold(
@ -98,45 +110,48 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
title: LocaleKeys.profile_familyDetails.tr(), title: LocaleKeys.profile_familyDetails.tr(),
), ),
backgroundColor: MyColors.backgroundColor, backgroundColor: MyColors.backgroundColor,
body: args['flag'] == 1 body: params!.flag == 1
? Column( ? Column(
children: [ children: [
ListView(physics: const BouncingScrollPhysics(), padding: const EdgeInsets.all(21), children: [ ListView(
ListView.separated( physics: const BouncingScrollPhysics(),
physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.all(21),
shrinkWrap: true, children: [
itemBuilder: (BuildContext cxt, int parentIndex) { ListView.separated(
return parseDynamicFormatTypeCols(getContactColsStructureList![parentIndex], parentIndex); physics: const NeverScrollableScrollPhysics(),
}, shrinkWrap: true,
separatorBuilder: (cxt, index) => 0.height, itemBuilder: (BuildContext cxt, int parentIndex) {
itemCount: getContactColsStructureList!.length), return parseDynamicFormatTypeCols(getContactColsStructureList![parentIndex], parentIndex);
12.height, },
ListView.separated( separatorBuilder: (BuildContext cxt, int index) => 0.height,
physics: const NeverScrollableScrollPhysics(), itemCount: getContactColsStructureList!.length),
shrinkWrap: true, 12.height,
itemBuilder: (BuildContext cxt, int parentIndex) { ListView.separated(
return parseDynamicFormatTypeBasicDetDff(getBasicDetDffStructureList![parentIndex], parentIndex); physics: const NeverScrollableScrollPhysics(),
}, shrinkWrap: true,
separatorBuilder: (cxt, index) => 0.height, itemBuilder: (BuildContext cxt, int parentIndex) {
itemCount: getBasicDetDffStructureList!.length), return parseDynamicFormatTypeBasicDetDff(getBasicDetDffStructureList![parentIndex], parentIndex);
ListView.separated( },
physics: const NeverScrollableScrollPhysics(), separatorBuilder: (BuildContext cxt, int index) => 0.height,
shrinkWrap: true, itemCount: getBasicDetDffStructureList!.length),
itemBuilder: (BuildContext cxt, int parentIndex) { ListView.separated(
return parseDynamicFormatTypeContactDff(getContactDffStructureList![parentIndex], parentIndex); physics: const NeverScrollableScrollPhysics(),
}, shrinkWrap: true,
separatorBuilder: (cxt, index) => 0.height, itemBuilder: (BuildContext cxt, int parentIndex) {
itemCount: getContactDffStructureList!.length), return parseDynamicFormatTypeContactDff(getContactDffStructureList![parentIndex], parentIndex);
]).expanded, },
separatorBuilder: (BuildContext cxt, int index) => 0.height,
itemCount: getContactDffStructureList!.length),
],
).expanded,
DefaultButton(LocaleKeys.next.tr(), () async { DefaultButton(LocaleKeys.next.tr(), () async {
submitUpdateForm(); submitUpdateForm();
}).insideContainer, }).insideContainer,
], ],
) )
: args['flag'] == 2 : params!.flag == 2
? Column( ? Column(
children: [ children: [
// getContactDetailsList!.isEmpty
ListView(physics: const BouncingScrollPhysics(), padding: const EdgeInsets.all(21), children: [ ListView(physics: const BouncingScrollPhysics(), padding: const EdgeInsets.all(21), children: [
ListView.separated( ListView.separated(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@ -144,7 +159,7 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
itemBuilder: (BuildContext cxt, int parentIndex) { itemBuilder: (BuildContext cxt, int parentIndex) {
return parseDynamicFormatTypeCols(getContactColsStructureList![parentIndex], parentIndex); return parseDynamicFormatTypeCols(getContactColsStructureList![parentIndex], parentIndex);
}, },
separatorBuilder: (cxt, index) => 0.height, separatorBuilder: (BuildContext cxt, int index) => 0.height,
itemCount: getContactColsStructureList!.length), itemCount: getContactColsStructureList!.length),
12.height, 12.height,
ListView.separated( ListView.separated(
@ -153,7 +168,7 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
itemBuilder: (BuildContext cxt, int parentIndex) { itemBuilder: (BuildContext cxt, int parentIndex) {
return parseDynamicFormatTypeBasicDetDff(getBasicDetDffStructureList![parentIndex], parentIndex); return parseDynamicFormatTypeBasicDetDff(getBasicDetDffStructureList![parentIndex], parentIndex);
}, },
separatorBuilder: (cxt, index) => 0.height, separatorBuilder: (BuildContext cxt, int index) => 0.height,
itemCount: getBasicDetDffStructureList!.length), itemCount: getBasicDetDffStructureList!.length),
ListView.separated( ListView.separated(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@ -161,7 +176,7 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
itemBuilder: (BuildContext cxt, int parentIndex) { itemBuilder: (BuildContext cxt, int parentIndex) {
return parseDynamicFormatTypeContactDff(getContactDffStructureList![parentIndex], parentIndex); return parseDynamicFormatTypeContactDff(getContactDffStructureList![parentIndex], parentIndex);
}, },
separatorBuilder: (cxt, index) => 0.height, separatorBuilder: (BuildContext cxt, int index) => 0.height,
itemCount: getContactDffStructureList!.length), itemCount: getContactDffStructureList!.length),
]).expanded, ]).expanded,
DefaultButton(LocaleKeys.next.tr(), () async { DefaultButton(LocaleKeys.next.tr(), () async {
@ -181,27 +196,27 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
if (model.dATATYPE == "VARCHAR2") { if (model.dATATYPE == "VARCHAR2") {
if (model!.objectValuesList?.isNotEmpty ?? false) { if (model!.objectValuesList?.isNotEmpty ?? false) {
return PopupMenuButton( return PopupMenuButton(
child: DynamicTextFieldWidget( child: DynamicTextFieldWidget(
(model!.sEGMENTPROMPT ?? "") + (model!.rEQUIREDFLAG == "Y" ? "*" : ""), (model!.sEGMENTPROMPT ?? "") + (model!.rEQUIREDFLAG == "Y" ? "*" : ""),
model!.getContactDetailsList!.sEGMENTVALUEDSP ?? "", model!.getContactDetailsList!.sEGMENTVALUEDSP ?? "",
isEnable: false, isEnable: false,
isPopup: true, isPopup: true,
).paddingOnly(bottom: 12), ).paddingOnly(bottom: 12),
itemBuilder: (_) => <PopupMenuItem<int>>[ itemBuilder: (_) => <PopupMenuItem<int>>[
for (int i = 0; i < getContactColsStructureList[index]!.objectValuesList!.length; i++) for (int i = 0; i < getContactColsStructureList[index]!.objectValuesList!.length; i++)
PopupMenuItem<int>(child: Text(getContactColsStructureList[index]!.objectValuesList![i].mEANING.toString()), value: i), PopupMenuItem<int>(child: Text(getContactColsStructureList[index]!.objectValuesList![i].mEANING.toString()), value: i),
], ],
onSelected: (int popupIndex) { onSelected: (int popupIndex) {
model.getContactDetailsList!.sEGMENTVALUEDSP = getContactColsStructureList[index]!.objectValuesList![popupIndex].mEANING.toString(); model.getContactDetailsList!.sEGMENTVALUEDSP = getContactColsStructureList[index]!.objectValuesList![popupIndex].mEANING.toString();
model.getContactDetailsList!.vARCHAR2VALUE = getContactColsStructureList[index]!.objectValuesList![popupIndex].cODE.toString(); model.getContactDetailsList!.vARCHAR2VALUE = getContactColsStructureList[index]!.objectValuesList![popupIndex].cODE.toString();
setState(() {}); setState(() {});
}); },
);
} else { } else {
return DynamicTextFieldWidget( return DynamicTextFieldWidget(
(model!.sEGMENTPROMPT ?? "") + (model!.rEQUIREDFLAG == "Y" ? "*" : ""), (model!.sEGMENTPROMPT ?? "") + (model!.rEQUIREDFLAG == "Y" ? "*" : ""),
(model!.getContactDetailsList!.sEGMENTVALUEDSP ?? ""), (model!.getContactDetailsList!.sEGMENTVALUEDSP ?? ""),
//isInputTypeNum: true, onChange: (String text) {
onChange: (text) {
model!.getContactDetailsList!.sEGMENTVALUEDSP = text; model!.getContactDetailsList!.sEGMENTVALUEDSP = text;
}, },
).paddingOnly(bottom: 12); ).paddingOnly(bottom: 12);
@ -211,7 +226,7 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
(model!.sEGMENTPROMPT ?? "") + (model!.rEQUIREDFLAG == "Y" ? "*" : ""), (model!.sEGMENTPROMPT ?? "") + (model!.rEQUIREDFLAG == "Y" ? "*" : ""),
(model!.getContactDetailsList!.sEGMENTVALUEDSP ?? ""), (model!.getContactDetailsList!.sEGMENTVALUEDSP ?? ""),
isInputTypeNum: true, isInputTypeNum: true,
onChange: (text) { onChange: (String text) {
model!.getContactDetailsList!.sEGMENTVALUEDSP = text; model!.getContactDetailsList!.sEGMENTVALUEDSP = text;
}, },
).paddingOnly(bottom: 12); ).paddingOnly(bottom: 12);
@ -223,13 +238,8 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
isEnable: false, isEnable: false,
onTap: () async { onTap: () async {
DateTime dateValue = await _selectDate(context); DateTime dateValue = await _selectDate(context);
//date = DateFormat('yyyy/MM/dd').format(dateValue);
//date = "2022-10-23T09:17:38.653+03:00";
date = (DateFormat('yyyy-MM-dd').format(dateValue)); date = (DateFormat('yyyy-MM-dd').format(dateValue));
model!.getContactDetailsList!.sEGMENTVALUEDSP = date; model!.getContactDetailsList!.sEGMENTVALUEDSP = date;
print(dateTime);
print(dateTime1);
print(date);
setState(() {}); setState(() {});
}, },
).paddingOnly(bottom: 12); ).paddingOnly(bottom: 12);
@ -245,28 +255,28 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
if (model!.fORMATTYPE == "C") { if (model!.fORMATTYPE == "C") {
if (model!.eSERVICESVS?.isNotEmpty ?? false) { if (model!.eSERVICESVS?.isNotEmpty ?? false) {
return PopupMenuButton( return PopupMenuButton(
child: DynamicTextFieldWidget( child: DynamicTextFieldWidget(
(model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""), (model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""),
model.getContactDetailsList!.sEGMENTVALUEDSP ?? "", model.getContactDetailsList!.sEGMENTVALUEDSP ?? "",
isEnable: false, isEnable: false,
isPopup: true, isPopup: true,
).paddingOnly(bottom: 12), ).paddingOnly(bottom: 12),
itemBuilder: (_) => <PopupMenuItem<int>>[ itemBuilder: (_) => <PopupMenuItem<int>>[
for (int i = 0; i < getBasicDetDffStructureList[index]!.eSERVICESVS!.length; i++) for (int i = 0; i < getBasicDetDffStructureList[index]!.eSERVICESVS!.length; i++)
PopupMenuItem<int>(child: Text(getBasicDetDffStructureList[index]!.eSERVICESVS![i].vALUECOLUMNNAME.toString()), value: i), PopupMenuItem<int>(child: Text(getBasicDetDffStructureList[index]!.eSERVICESVS![i].vALUECOLUMNNAME.toString()), value: i),
], ],
onSelected: (int popupIndex) { onSelected: (int popupIndex) {
model.getContactDetailsList!.sEGMENTVALUEDSP = getBasicDetDffStructureList[index]!.eSERVICESVS![popupIndex].vALUECOLUMNNAME.toString(); model.getContactDetailsList!.sEGMENTVALUEDSP = getBasicDetDffStructureList[index]!.eSERVICESVS![popupIndex].vALUECOLUMNNAME.toString();
model.getContactDetailsList!.vARCHAR2VALUE = getBasicDetDffStructureList[index]!.eSERVICESVS![popupIndex].iDCOLUMNNAME.toString(); model.getContactDetailsList!.vARCHAR2VALUE = getBasicDetDffStructureList[index]!.eSERVICESVS![popupIndex].iDCOLUMNNAME.toString();
setState(() {}); setState(() {});
}); },
);
} else { } else {
return DynamicTextFieldWidget( return DynamicTextFieldWidget(
(model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""), (model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""),
model.getContactDetailsList!.sEGMENTVALUEDSP ?? "", model.getContactDetailsList!.sEGMENTVALUEDSP ?? "",
// isInputTypeNum: true, onChange: (String text) {
onChange: (text) {
model.getContactDetailsList!.sEGMENTVALUEDSP = text; model.getContactDetailsList!.sEGMENTVALUEDSP = text;
}, },
).paddingOnly(bottom: 12); ).paddingOnly(bottom: 12);
@ -276,7 +286,7 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
(model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""), (model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""),
model.getContactDetailsList!.sEGMENTVALUEDSP ?? "", model.getContactDetailsList!.sEGMENTVALUEDSP ?? "",
isInputTypeNum: true, isInputTypeNum: true,
onChange: (text) { onChange: (String text) {
model.getContactDetailsList!.sEGMENTVALUEDSP = text; model.getContactDetailsList!.sEGMENTVALUEDSP = text;
}, },
).paddingOnly(bottom: 12); ).paddingOnly(bottom: 12);
@ -289,8 +299,6 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
onTap: () async { onTap: () async {
DateTime dateValue = await _selectDate(context); DateTime dateValue = await _selectDate(context);
date = (DateFormat('yyyy-MM-dd').format(dateValue)); date = (DateFormat('yyyy-MM-dd').format(dateValue));
// date = (DateFormat('yyyy-MM-dd').format(dateValue) +"T"+ dateTime.toString() + dateTime1.toString());
// date = DateFormat('yyyy/MM/dd').format(dateValue);
model!.getContactDetailsList!.sEGMENTVALUEDSP = date; model!.getContactDetailsList!.sEGMENTVALUEDSP = date;
setState(() {}); setState(() {});
}, },
@ -307,27 +315,27 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
if (model!.fORMATTYPE == "C") { if (model!.fORMATTYPE == "C") {
if (model.eSERVICESVS?.isNotEmpty ?? false) { if (model.eSERVICESVS?.isNotEmpty ?? false) {
return PopupMenuButton( return PopupMenuButton(
child: DynamicTextFieldWidget( child: DynamicTextFieldWidget(
(model!.sEGMENTPROMPT ?? "") + (model!.rEQUIREDFLAG == "Y" ? "*" : ""), (model!.sEGMENTPROMPT ?? "") + (model!.rEQUIREDFLAG == "Y" ? "*" : ""),
model!.getContactDetailsList!.sEGMENTVALUEDSP ?? "", model!.getContactDetailsList!.sEGMENTVALUEDSP ?? "",
isEnable: false, isEnable: false,
isPopup: true, isPopup: true,
).paddingOnly(bottom: 12), ).paddingOnly(bottom: 12),
itemBuilder: (_) => <PopupMenuItem<int>>[ itemBuilder: (_) => <PopupMenuItem<int>>[
for (int i = 0; i < getContactDffStructureList[index]!.eSERVICESVS!.length; i++) for (int i = 0; i < getContactDffStructureList[index]!.eSERVICESVS!.length; i++)
PopupMenuItem<int>(child: Text(getContactDffStructureList[index]!.eSERVICESVS![i].vALUECOLUMNNAME.toString()), value: i), PopupMenuItem<int>(child: Text(getContactDffStructureList[index]!.eSERVICESVS![i].vALUECOLUMNNAME.toString()), value: i),
], ],
onSelected: (int popupIndex) { onSelected: (int popupIndex) {
model.getContactDetailsList!.sEGMENTVALUEDSP = getContactDffStructureList[index]!.eSERVICESVS![popupIndex].vALUECOLUMNNAME.toString(); model.getContactDetailsList!.sEGMENTVALUEDSP = getContactDffStructureList[index]!.eSERVICESVS![popupIndex].vALUECOLUMNNAME.toString();
model.getContactDetailsList!.vARCHAR2VALUE = getContactDffStructureList[index]!.eSERVICESVS![popupIndex].iDCOLUMNNAME.toString(); model.getContactDetailsList!.vARCHAR2VALUE = getContactDffStructureList[index]!.eSERVICESVS![popupIndex].iDCOLUMNNAME.toString();
setState(() {}); setState(() {});
}); },
);
} else { } else {
return DynamicTextFieldWidget( return DynamicTextFieldWidget(
(model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""), (model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""),
model.getContactDetailsList!.sEGMENTVALUEDSP ?? "", model.getContactDetailsList!.sEGMENTVALUEDSP ?? "",
// isInputTypeNum: true, onChange: (String text) {
onChange: (text) {
model.getContactDetailsList!.sEGMENTVALUEDSP = text; model.getContactDetailsList!.sEGMENTVALUEDSP = text;
}, },
).paddingOnly(bottom: 12); ).paddingOnly(bottom: 12);
@ -337,7 +345,7 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
(model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""), (model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""),
model.getContactDetailsList!.sEGMENTVALUEDSP ?? "", model.getContactDetailsList!.sEGMENTVALUEDSP ?? "",
isInputTypeNum: true, isInputTypeNum: true,
onChange: (text) { onChange: (String text) {
model.getContactDetailsList!.sEGMENTVALUEDSP = text; model.getContactDetailsList!.sEGMENTVALUEDSP = text;
}, },
).paddingOnly(bottom: 12); ).paddingOnly(bottom: 12);
@ -349,9 +357,7 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
isEnable: false, isEnable: false,
onTap: () async { onTap: () async {
DateTime dateValue = await _selectDate(context); DateTime dateValue = await _selectDate(context);
// date = "2022-10-23T09:17:38.653+03:00";
date = (DateFormat('yyyy-MM-dd').format(dateValue)); date = (DateFormat('yyyy-MM-dd').format(dateValue));
// date = DateFormat('yyyy/MM/dd').format(dateValue);
model!.getContactDetailsList!.sEGMENTVALUEDSP = date; model!.getContactDetailsList!.sEGMENTVALUEDSP = date;
setState(() {}); setState(() {});
}, },
@ -367,13 +373,13 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
if (!Platform.isIOS) { if (!Platform.isIOS) {
await showCupertinoModalPopup( await showCupertinoModalPopup(
context: context, context: context,
builder: (cxt) => Container( builder: (BuildContext cxt) => Container(
height: 250, height: 250,
color: Colors.white, color: Colors.white,
child: CupertinoDatePicker( child: CupertinoDatePicker(
backgroundColor: Colors.white, backgroundColor: Colors.white,
mode: CupertinoDatePickerMode.date, mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (value) { onDateTimeChanged: (DateTime value) {
if (value != null && value != selectedDate) { if (value != null && value != selectedDate) {
time = value; time = value;
} }
@ -392,7 +398,6 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
} }
void submitUpdateForm() async { void submitUpdateForm() async {
print("submit");
try { try {
List<Map<String, dynamic>> values1 = getBasicDetDffStructureList!.map((e) { List<Map<String, dynamic>> values1 = getBasicDetDffStructureList!.map((e) {
String? dateVal = ''; String? dateVal = '';
@ -441,12 +446,10 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
return ValidateEitTransactionModel(dATEVALUE: dateVal, nAME: e.aPPLICATIONCOLUMNNAME, nUMBERVALUE: numberVal, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: varChar).toJson(); return ValidateEitTransactionModel(dATEVALUE: dateVal, nAME: e.aPPLICATIONCOLUMNNAME, nUMBERVALUE: numberVal, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: varChar).toJson();
}).toList(); }).toList();
List<Map<String, dynamic>> values3 = getContactColsStructureList!.map((e) { List<Map<String, dynamic>> values3 = getContactColsStructureList!.map((e) {
// String tempVar = e!.getContactDetailsList!.sEGMENTVALUEDSP ?? "";
String? dateVal = ''; String? dateVal = '';
dynamic? varChar1 = ''; String? varChar1 = '';
int? numberVal; int? numberVal;
print("e.dATATYPE:${e?.dATATYPE}");
if (e!.dATATYPE == 'VARCHAR2') { if (e!.dATATYPE == 'VARCHAR2') {
dateVal = null; dateVal = null;
numberVal = null; numberVal = null;
@ -468,15 +471,18 @@ class _AddUpdateFamilyMemberState extends State<AddUpdateFamilyMember> {
}).toList(); }).toList();
List<Map<String, dynamic>> valuesFinal = [...values1, ...values2, ...values3]; List<Map<String, dynamic>> valuesFinal = [...values1, ...values2, ...values3];
Utils.showLoading(context); Utils.showLoading(context);
submitContactTransactionList = await ProfileApiClient().submitContactTransactionAddAndUpdate(args['actionType'], args['relationID'] ?? null, valuesFinal); submitContactTransactionList = await ProfileApiClient().submitContactTransactionAddAndUpdate(params!.actionType!, params!.relationID, valuesFinal);
var transactionId = submitContactTransactionList!.pTRANSACTIONID; Utils.hideLoading(context);
var itemKey = submitContactTransactionList!.pITEMKEY; await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.profile_familyDetails.tr(), submitContactTransactionList!.pTRANSACTIONID!, submitContactTransactionList!.pITEMKEY!, 'family_member'));
if (!AppState().cancelRequestTrancsection) {
return;
}
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitContactTransactionList!.pTRANSACTIONID!);
Utils.hideLoading(context); Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.profile_familyDetails.tr(), transactionId!.toInt(), itemKey.toString(), 'family_member'));
setState(() {}); setState(() {});
} catch (ex) { } catch (ex) {
print(ex);
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, null); Utils.handleException(ex, context, null);
} }

@ -1,6 +1,11 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/profile_api_client.dart'; import 'package:mohem_flutter_app/api/profile_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
@ -10,13 +15,12 @@ import 'package:mohem_flutter_app/models/get_approves_list_model.dart';
import 'package:mohem_flutter_app/models/profile/submit_contact_transaction_list_model.dart'; import 'package:mohem_flutter_app/models/profile/submit_contact_transaction_list_model.dart';
import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart'; import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
class DeleteFamilyMember extends StatefulWidget { class DeleteFamilyMember extends StatefulWidget {
int relationId; int relationId;
DeleteFamilyMember(@required this.relationId, {Key? key}) : super(key: key); DeleteFamilyMember(@required this.relationId, {Key? key}) : super(key: key);
@override @override
@ -26,9 +30,11 @@ class DeleteFamilyMember extends StatefulWidget {
class _DeleteFamilyMemberState extends State<DeleteFamilyMember> { class _DeleteFamilyMemberState extends State<DeleteFamilyMember> {
String pFunctionName = "HR_PERINFO_SS"; String pFunctionName = "HR_PERINFO_SS";
String actionType = "DELETE"; String actionType = "DELETE";
// int? contactRelationId; // int? contactRelationId;
String? date = "MM/DD/YYYY"; String? date = "MM/DD/YYYY";
String? datePar; String? datePar;
// String? itemKey; // String? itemKey;
SubmitContactTransactionList? submitContactTransactionList; SubmitContactTransactionList? submitContactTransactionList;
@ -44,12 +50,16 @@ class _DeleteFamilyMemberState extends State<DeleteFamilyMember> {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
submitContactTransactionList = await ProfileApiClient().submetConatctTransaction(pFunctionName.toString(), actionType.toString(), widget.relationId!.toInt(), datePar.toString()); submitContactTransactionList = await ProfileApiClient().submetConatctTransaction(pFunctionName.toString(), actionType.toString(), widget.relationId!.toInt(), datePar.toString());
var transactionId = submitContactTransactionList!.pTRANSACTIONID;
var itemKey = submitContactTransactionList!.pITEMKEY;
Utils.hideLoading(context); Utils.hideLoading(context);
// getApprovesList = await ProfileApiClient().getApproves(transactionId!.toInt(), itemKey.toString() );
Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.profile_familyDetails.tr(), transactionId!.toInt(), itemKey.toString(), 'family_member')); arguments: RequestSubmitScreenParams(LocaleKeys.profile_familyDetails.tr(), submitContactTransactionList!.pTRANSACTIONID!, submitContactTransactionList!.pITEMKEY!, 'family_member'));
if (!AppState().cancelRequestTrancsection) {
return;
}
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitContactTransactionList!.pTRANSACTIONID!);
Utils.hideLoading(context);
setState(() {}); setState(() {});
} catch (ex) { } catch (ex) {
@ -73,7 +83,8 @@ class _DeleteFamilyMemberState extends State<DeleteFamilyMember> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
DynamicTextFieldWidget( DynamicTextFieldWidget(
LocaleKeys.endDate.tr(), date.toString(), LocaleKeys.endDate.tr(),
date.toString(),
isEnable: false, isEnable: false,
onTap: () async { onTap: () async {
DateTime dateValue = await _selectDate(context); DateTime dateValue = await _selectDate(context);
@ -85,10 +96,9 @@ class _DeleteFamilyMemberState extends State<DeleteFamilyMember> {
], ],
), ),
), ),
DefaultButton( DefaultButton(LocaleKeys.next.tr(), () async {
LocaleKeys.next.tr(), () async { deleteFamilyMember(datePar);
deleteFamilyMember(datePar);} }).insideContainer,
).insideContainer,
], ],
)); ));
} }
@ -145,8 +155,7 @@ class _DeleteFamilyMemberState extends State<DeleteFamilyMember> {
), ),
); );
} else { } else {
DateTime? picked = DateTime? picked = await showDatePicker(context: context, initialDate: selectedDate, initialEntryMode: DatePickerEntryMode.calendarOnly, firstDate: DateTime(2015, 8), lastDate: DateTime(2101));
await showDatePicker(context: context, initialDate: selectedDate, initialEntryMode: DatePickerEntryMode.calendarOnly, firstDate: DateTime(2015, 8), lastDate: DateTime(2101));
if (picked != null && picked != selectedDate) { if (picked != null && picked != selectedDate) {
time = picked; time = picked;
} }

@ -3,8 +3,10 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/my_attendance_api_client.dart'; import 'package:mohem_flutter_app/api/my_attendance_api_client.dart';
import 'package:mohem_flutter_app/api/profile_api_client.dart'; import 'package:mohem_flutter_app/api/profile_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -296,8 +298,16 @@ class _DynamicInputScreenState extends State<DynamicInputScreenAddress> {
); );
Utils.hideLoading(context); Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(dynamicParams!.title, submitPhoneNumbers.pTRANSACTIONID!, submitPhoneNumbers.pITEMKEY!, 'address')); arguments: RequestSubmitScreenParams(dynamicParams!.title, submitPhoneNumbers.pTRANSACTIONID!, submitPhoneNumbers.pITEMKEY!, 'address'));
if (!AppState().cancelRequestTrancsection) {
return;
}
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitPhoneNumbers.pTRANSACTIONID!);
Utils.hideLoading(context);
} catch (ex) { } catch (ex) {
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, null); Utils.handleException(ex, context, null);

@ -3,8 +3,10 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/my_attendance_api_client.dart'; import 'package:mohem_flutter_app/api/my_attendance_api_client.dart';
import 'package:mohem_flutter_app/api/profile_api_client.dart'; import 'package:mohem_flutter_app/api/profile_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -378,7 +380,6 @@ class _DynamicInputScreenState extends State<DynamicInputScreenProfile> {
values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_ACTION", nUMBERVALUE: null, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: "NEW_ROW").toJson()); values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_ACTION", nUMBERVALUE: null, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: "NEW_ROW").toJson());
values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_EXTRA_INFO_ID", nUMBERVALUE: -1, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson()); values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_EXTRA_INFO_ID", nUMBERVALUE: -1, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson());
//values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_OBJECT_VERSION_NUMBER", nUMBERVALUE: 0, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson());
List<Map<String, dynamic>> valuesCols = getBasicDetColsStructureList!.map((e) { List<Map<String, dynamic>> valuesCols = getBasicDetColsStructureList!.map((e) {
if (e.dATATYPE == 'NUMBER') { if (e.dATATYPE == 'NUMBER') {
numberValue = e.userBasicDetail!.nUMBERVALUE ?? 0; numberValue = e.userBasicDetail!.nUMBERVALUE ?? 0;
@ -392,11 +393,18 @@ class _DynamicInputScreenState extends State<DynamicInputScreenProfile> {
SubmitBasicDetailsTransactionList submitBasicDetails = SubmitBasicDetailsTransactionList submitBasicDetails =
await ProfileApiClient().submitBasicDetailsTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, transactionValues, dynamicParams!.correctOrNew); await ProfileApiClient().submitBasicDetailsTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, transactionValues, dynamicParams!.correctOrNew);
print(submitBasicDetails);
Utils.hideLoading(context); Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(dynamicParams!.title, submitBasicDetails.pTRANSACTIONID!, submitBasicDetails.pITEMKEY!, 'basicDetails')); arguments: RequestSubmitScreenParams(dynamicParams!.title, submitBasicDetails.pTRANSACTIONID!, submitBasicDetails.pITEMKEY!, 'basicDetails'));
if (!AppState().cancelRequestTrancsection) {
return;
}
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitBasicDetails.pTRANSACTIONID!);
Utils.hideLoading(context);
} catch (ex) { } catch (ex) {
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, null); Utils.handleException(ex, context, null);

@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart'; import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart';
import 'package:mohem_flutter_app/models/get_employee_contacts.model.dart'; import 'package:mohem_flutter_app/models/get_employee_contacts.model.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/profile/add_update_family_member.dart';
import 'package:mohem_flutter_app/ui/profile/profile_screen.dart'; import 'package:mohem_flutter_app/ui/profile/profile_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart';
@ -140,7 +141,7 @@ class _FamilyMembersState extends State<FamilyMembers> {
LocaleKeys.addNewFamilyMember.tr(), LocaleKeys.addNewFamilyMember.tr(),
menuEntries.updateButton == 'Y' menuEntries.updateButton == 'Y'
? () async { ? () async {
Navigator.pushNamed(context, AppRoutes.addUpdateFamilyMember, arguments: {"relationID": relationId, "flag": 1, "actionType": "ADD"}); Navigator.pushNamed(context, AppRoutes.addUpdateFamilyMember, arguments: FamilyMemberScreenParams( relationId, flag: 1, actionType: "ADD"));
// ProfileScreen(); // ProfileScreen();
} }
: null) : null)
@ -166,7 +167,7 @@ class _FamilyMembersState extends State<FamilyMembers> {
Navigator.pushNamed( Navigator.pushNamed(
context, context,
AppRoutes.addUpdateFamilyMember, AppRoutes.addUpdateFamilyMember,
arguments: {"relationID": relationId, "flag": 2, "actionType": "UPDATE"}, arguments:FamilyMemberScreenParams(relationId, flag: 2, actionType: "UPDATE"),
); );
}, },
); );
@ -202,7 +203,7 @@ class _FamilyMembersState extends State<FamilyMembers> {
LocaleKeys.ok.tr(), LocaleKeys.ok.tr(),
), ),
onPressed: () { onPressed: () {
Navigator.pushNamed(context, AppRoutes.deleteFamilyMember, arguments: relationId); Navigator.pushNamed(context, AppRoutes.deleteFamilyMember, arguments: FamilyMemberScreenParams(relationId));
// continueDynamicForms(); // continueDynamicForms();
}, },
); );

@ -1,6 +1,8 @@
import 'package:easy_localization/src/public_ext.dart'; import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/profile_api_client.dart'; import 'package:mohem_flutter_app/api/profile_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
@ -117,8 +119,14 @@ class _PhoneNumbersState extends State<PhoneNumbers> {
setUpdateStatus(); setUpdateStatus();
submitPhoneNumbers = await ProfileApiClient().submitPhoneNumbers(widget.getEmployeePhonesList); submitPhoneNumbers = await ProfileApiClient().submitPhoneNumbers(widget.getEmployeePhonesList);
Utils.hideLoading(context); Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.profile_contactDetails.tr(), submitPhoneNumbers.pTRANSACTIONID!, submitPhoneNumbers.pITEMKEY!, 'phone_numbers')); arguments: RequestSubmitScreenParams(LocaleKeys.profile_contactDetails.tr(), submitPhoneNumbers.pTRANSACTIONID!, submitPhoneNumbers.pITEMKEY!, 'phone_numbers'));
if (!AppState().cancelRequestTrancsection) {
return;
}
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitPhoneNumbers.pTRANSACTIONID!);
Utils.hideLoading(context);
} }
void setUpdateStatus() { void setUpdateStatus() {

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart'; import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/my_attendance_api_client.dart'; import 'package:mohem_flutter_app/api/my_attendance_api_client.dart';
import 'package:mohem_flutter_app/api/termination_dff_api_client.dart'; import 'package:mohem_flutter_app/api/termination_dff_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -135,6 +136,9 @@ class _EndEmploymentScreenState extends State<EndEmploymentScreen> {
Utils.hideLoading(context); Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitTermTransaction.pTRANSACTIONID!, submitTermTransaction.pITEMKEY!, "endEmployment")); arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitTermTransaction.pTRANSACTIONID!, submitTermTransaction.pITEMKEY!, "endEmployment"));
if (!AppState().cancelRequestTrancsection) {
return;
}
Utils.showLoading(context); Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitTermTransaction.pTRANSACTIONID!); await LeaveBalanceApiClient().cancelHrTransaction(submitTermTransaction.pTRANSACTIONID!);
Utils.hideLoading(context); Utils.hideLoading(context);

@ -1,6 +1,8 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/my_attendance_api_client.dart'; import 'package:mohem_flutter_app/api/my_attendance_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -30,6 +32,7 @@ class _UpdateContinueSheetState extends State<UpdateContinueSheet> {
double itemHeight = 0; double itemHeight = 0;
double itemWidth = 0; double itemWidth = 0;
List<Map<String, dynamic>> validatedValues = []; List<Map<String, dynamic>> validatedValues = [];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var size = MediaQuery.of(context).size; var size = MediaQuery.of(context).size;
@ -57,11 +60,7 @@ class _UpdateContinueSheetState extends State<UpdateContinueSheet> {
index, index,
dataList[index].segmentPrompt, dataList[index].segmentPrompt,
dataList[index].segmentValueDsp, dataList[index].segmentValueDsp,
isNeedToShowEmptyDivider: (dataList.length == index + 1) isNeedToShowEmptyDivider: (dataList.length == index + 1) ? (isOdd ? true : false) : false,
? isOdd
? true
: false
: false,
), ),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
@ -95,7 +94,6 @@ class _UpdateContinueSheetState extends State<UpdateContinueSheet> {
} }
void performNextAction() async { void performNextAction() async {
//Resubmit EIT Transaction
try { try {
Utils.showLoading(context); Utils.showLoading(context);
List<Map<String, dynamic>> values = []; List<Map<String, dynamic>> values = [];
@ -114,7 +112,6 @@ class _UpdateContinueSheetState extends State<UpdateContinueSheet> {
} }
} }
} }
ResubmitEITRequestResponse resubmitEITRequestResponse = await MyAttendanceApiClient().reSubmitEitTransaction(widget.workListData!.iTEMKEY!, widget.workListData!.nOTIFICATIONID, values); ResubmitEITRequestResponse resubmitEITRequestResponse = await MyAttendanceApiClient().reSubmitEitTransaction(widget.workListData!.iTEMKEY!, widget.workListData!.nOTIFICATIONID, values);
Utils.hideLoading(context); Utils.hideLoading(context);
await Navigator.pushNamed( await Navigator.pushNamed(
@ -122,6 +119,12 @@ class _UpdateContinueSheetState extends State<UpdateContinueSheet> {
AppRoutes.requestSubmitScreen, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), resubmitEITRequestResponse.pTRANSACTIONID!, widget.workListData!.iTEMKEY!, 'eit'), arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), resubmitEITRequestResponse.pTRANSACTIONID!, widget.workListData!.iTEMKEY!, 'eit'),
); );
if (!AppState().cancelRequestTrancsection) {
return;
}
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(resubmitEITRequestResponse.pTRANSACTIONID!);
Utils.hideLoading(context);
} catch (ex) { } catch (ex) {
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, null); Utils.handleException(ex, context, null);

@ -81,7 +81,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
value: 0, name: 'COC', fullName: LocaleKeys.itemCreation.tr(), active: false, color: [Color(0xff787299), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'COC', disable: true) value: 0, name: 'COC', fullName: LocaleKeys.itemCreation.tr(), active: false, color: [Color(0xff787299), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'COC', disable: true)
]; ];
int workListItemIndex = 0; int? workListItemIndex;
List<WorkListResponseModel>? workList; List<WorkListResponseModel>? workList;
int pageNumber = 1; int pageNumber = 1;
@ -99,7 +99,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
super.initState(); super.initState();
providerData = Provider.of<DashboardProviderModel>(context, listen: false); providerData = Provider.of<DashboardProviderModel>(context, listen: false);
calculateCounter(); calculateCounter();
getWorkList(); if (workListItemIndex != null) getWorkList();
} }
void calculateCounter() { void calculateCounter() {
@ -115,11 +115,17 @@ class _WorkListScreenState extends State<WorkListScreen> {
} }
} }
}); });
workListItemTypes.removeWhere((element) => element.value < 1);
if (workListItemTypes.isNotEmpty) {
workListItemIndex = workListItemIndex ?? 0;
} else {
workListItemIndex = null;
}
} }
void verifyWorkListCounter() { void verifyWorkListCounter() {
workListItemTypes.forEach((workListElement) { workListItemTypes.forEach((workListElement) {
if (workListElement.key == "ITG" && workListItemTypes[workListItemIndex].key == "ITG") { if (workListElement.key == "ITG" && workListItemTypes[workListItemIndex!].key == "ITG") {
workListElement.value = providerData.itgFormsModel?.totalCount ?? 0; workListElement.value = providerData.itgFormsModel?.totalCount ?? 0;
if ((AppState().requestAllList?.length ?? 0) != workListElement.value) { if ((AppState().requestAllList?.length ?? 0) != workListElement.value) {
workListElement.value = AppState().requestAllList?.length ?? 0; workListElement.value = AppState().requestAllList?.length ?? 0;
@ -132,7 +138,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
workListElement.value = providerData.cocFinalCount; workListElement.value = providerData.cocFinalCount;
} else { } else {
providerData.getOpenNotificationsList?.forEach((element) { providerData.getOpenNotificationsList?.forEach((element) {
if ((element.itemType == workListItemTypes[workListItemIndex].key) && element.itemType == workListElement.key) { if ((element.itemType == workListItemTypes[workListItemIndex!].key) && element.itemType == workListElement.key) {
if ((AppState().workList?.length ?? 0) != (element.openNtfNumber ?? 0)) { if ((AppState().workList?.length ?? 0) != (element.openNtfNumber ?? 0)) {
workListElement.value = AppState().workList?.length ?? 0; workListElement.value = AppState().workList?.length ?? 0;
providerData.workListCounter = providerData.workListCounter - ((element.openNtfNumber ?? 0) - (AppState().workList?.length ?? 0)); providerData.workListCounter = providerData.workListCounter - ((element.openNtfNumber ?? 0) - (AppState().workList?.length ?? 0));
@ -141,17 +147,6 @@ class _WorkListScreenState extends State<WorkListScreen> {
} }
} }
}); });
// var tempList = providerData.getOpenNotificationsList?.where((notificationElement) {
// return (notificationElement.itemType == workListItemTypes[workListItemIndex].key) && notificationElement.itemType == workListElement.key;
// }).toList();
// if (tempList!.isNotEmpty) {
// if ((AppState().workList?.length ?? 0) != (tempList.first.openNtfNumber ?? 0)) {
// workListElement.value = AppState().workList?.length ?? 0;
// providerData.workListCounter = providerData.workListCounter - ((tempList.first.openNtfNumber ?? 0) - (AppState().workList?.length ?? 0));
// providerData.notify();
// }
// }
} }
}); });
} }
@ -162,7 +157,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
Future<void> getWorkList({bool showLoading = true}) async { Future<void> getWorkList({bool showLoading = true}) async {
try { try {
if (showLoading) Utils.showLoading(context); if (showLoading) Utils.showLoading(context);
if (workListItemTypes[workListItemIndex].key == "ITG") { if (workListItemTypes[workListItemIndex!].key == "ITG") {
itgFormsModel = await WorkListApiClient().getITGTaskCountRequestType(); itgFormsModel = await WorkListApiClient().getITGTaskCountRequestType();
List<RequestDetails> requestAllList = []; List<RequestDetails> requestAllList = [];
for (int i = 0; i < (itgFormsModel?.requestType!.length ?? 0); i++) { for (int i = 0; i < (itgFormsModel?.requestType!.length ?? 0); i++) {
@ -178,7 +173,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
} }
} else { } else {
itgRequestTypeIndex = null; itgRequestTypeIndex = null;
workList = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex].key, pNotificationType.toString()); workList = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex!].key, pNotificationType.toString());
AppState().setWorkList = workList; AppState().setWorkList = workList;
} }
if (showLoading) Utils.hideLoading(context); if (showLoading) Utils.hideLoading(context);
@ -216,127 +211,129 @@ class _WorkListScreenState extends State<WorkListScreen> {
return Scaffold( return Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
appBar: AppBarWidget(context, title: LocaleKeys.workList.tr(), showWorkListSettingButton: true), appBar: AppBarWidget(context, title: LocaleKeys.workList.tr(), showWorkListSettingButton: true),
body: SizedBox( body: workListItemIndex == null
width: double.infinity, ? Utils.getNoDataWidget(context)
height: double.infinity, : SizedBox(
child: Column( width: double.infinity,
crossAxisAlignment: CrossAxisAlignment.start, height: double.infinity,
children: [ child: Column(
SizedBox( crossAxisAlignment: CrossAxisAlignment.start,
height: 40, children: [
child: ListView.separated( SizedBox(
controller: _controller, height: 40,
itemBuilder: (context, index) { child: ListView.separated(
return Container( controller: _controller,
padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8), itemBuilder: (context, index) {
alignment: Alignment.center, return Container(
decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: workListItemIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor), padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8),
child: ("${workListItemTypes[index].name} ${workListItemTypes[index].value > 0 ? "(${workListItemTypes[index].value})" : ""}") alignment: Alignment.center,
.toText12(color: workListItemIndex == index ? MyColors.white : MyColors.black), decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: workListItemIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
).onPress(() { child: ("${workListItemTypes[index].name} ${workListItemTypes[index].value > 0 ? "(${workListItemTypes[index].value})" : ""}")
if (pNotificationType != 1) { .toText12(color: workListItemIndex == index ? MyColors.white : MyColors.black),
pNotificationType = 1; ).onPress(() {
} if (pNotificationType != 1) {
if (workListItemIndex != index && !workListItemTypes[index].disable) { pNotificationType = 1;
workListItemIndex = index; }
if (workListItemTypes[index].value == 0) { if (workListItemIndex != index && !workListItemTypes[index].disable) {
workList = []; workListItemIndex = index;
itgRequestTypeIndex = null; if (workListItemTypes[index].value == 0) {
} else { workList = [];
workList = null; itgRequestTypeIndex = null;
} } else {
setState(() {}); workList = null;
if (workListItemTypes[index].value > 0) { }
getWorkList(); setState(() {});
} if (workListItemTypes[index].value > 0) {
} getWorkList();
}); }
}, }
separatorBuilder: (context, index) => 8.width, });
shrinkWrap: true, },
itemCount: workListItemTypes.length, separatorBuilder: (context, index) => 8.width,
scrollDirection: Axis.horizontal, shrinkWrap: true,
padding: const EdgeInsets.only(left: 21, right: 21), itemCount: workListItemTypes.length,
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(left: 21, right: 21),
),
).paddingOnly(top: 21, bottom: 21),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
workListItemTypes[workListItemIndex!].fullName.toSectionHeading().paddingOnly(left: 21, right: 21),
LocaleKeys.advancedSearch.tr().toText14(isUnderLine: true, color: MyColors.textMixColor).onPress(() {
openBottomSheet(context);
}).paddingOnly(left: 21, right: 21)
],
),
SmartRefresher(
enablePullDown: true,
enablePullUp: false,
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
),
controller: _refreshController,
onRefresh: _onRefresh,
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: itgRequestTypeIndex != null
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// todo this is commented for temporary purpose, have issue when selecting any itg category and click any item showing wrong details
// SizedBox(
// height: 40,
// child: ListView.separated(
// itemBuilder: (context, index) {
// RequestType type = itgFormsModel!.requestType![index];
// return Container(
// padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8),
// alignment: Alignment.center,
// decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: itgRequestTypeIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
// child: ("${type.requestTypeName}").toText12(color: itgRequestTypeIndex == index ? MyColors.white : MyColors.black),
// ).onPress(() {
// if (itgRequestTypeIndex != index) {
// itgRequestTypeIndex = index;
// setState(() {});
// }
// });
// },
// separatorBuilder: (context, index) => 8.width,
// shrinkWrap: true,
// itemCount: itgFormsModel?.requestType?.length ?? 0,
// scrollDirection: Axis.horizontal,
// padding: const EdgeInsets.only(left: 21, right: 21),
// ),
// ).paddingOnly(top: 16, bottom: 16),
ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return itgRowItem(workListItemTypes[workListItemIndex!], itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails![index], index);
},
separatorBuilder: (context, index) => 12.height,
itemCount: itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails?.length ?? 0,
padding: const EdgeInsets.all(21),
),
],
)
: workList != null
? ((workList!).isEmpty
? Utils.getNoDataWidget(context).paddingOnly(top: 100)
: ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return rowItem(workListItemTypes[workListItemIndex!], workList![index], index);
},
separatorBuilder: (context, index) => 12.height,
itemCount: workList?.length ?? 0,
padding: const EdgeInsets.all(21),
))
: const SizedBox(),
)).expanded,
],
), ),
).paddingOnly(top: 21, bottom: 21),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
workListItemTypes[workListItemIndex].fullName.toSectionHeading().paddingOnly(left: 21, right: 21),
LocaleKeys.advancedSearch.tr().toText14(isUnderLine: true, color: MyColors.textMixColor).onPress(() {
openBottomSheet(context);
}).paddingOnly(left: 21, right: 21)
],
), ),
SmartRefresher(
enablePullDown: true,
enablePullUp: false,
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
),
controller: _refreshController,
onRefresh: _onRefresh,
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: itgRequestTypeIndex != null
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// todo this is commented for temporary purpose, have issue when selecting any itg category and click any item showing wrong details
// SizedBox(
// height: 40,
// child: ListView.separated(
// itemBuilder: (context, index) {
// RequestType type = itgFormsModel!.requestType![index];
// return Container(
// padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8),
// alignment: Alignment.center,
// decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: itgRequestTypeIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
// child: ("${type.requestTypeName}").toText12(color: itgRequestTypeIndex == index ? MyColors.white : MyColors.black),
// ).onPress(() {
// if (itgRequestTypeIndex != index) {
// itgRequestTypeIndex = index;
// setState(() {});
// }
// });
// },
// separatorBuilder: (context, index) => 8.width,
// shrinkWrap: true,
// itemCount: itgFormsModel?.requestType?.length ?? 0,
// scrollDirection: Axis.horizontal,
// padding: const EdgeInsets.only(left: 21, right: 21),
// ),
// ).paddingOnly(top: 16, bottom: 16),
ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return itgRowItem(workListItemTypes[workListItemIndex], itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails![index], index);
},
separatorBuilder: (context, index) => 12.height,
itemCount: itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails?.length ?? 0,
padding: const EdgeInsets.all(21),
),
],
)
: workList != null
? ((workList!).isEmpty
? Utils.getNoDataWidget(context).paddingOnly(top: 100)
: ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return rowItem(workListItemTypes[workListItemIndex], workList![index], index);
},
separatorBuilder: (context, index) => 12.height,
itemCount: workList?.length ?? 0,
padding: const EdgeInsets.all(21),
))
: const SizedBox(),
)).expanded,
],
),
),
); );
} }
@ -349,25 +346,15 @@ class _WorkListScreenState extends State<WorkListScreen> {
if (shouldReloadData != null) { if (shouldReloadData != null) {
if (shouldReloadData.toString() == "delegate_reload") { if (shouldReloadData.toString() == "delegate_reload") {
providerData.itgFormsModel!.totalCount = providerData.itgFormsModel!.totalCount! - 1; providerData.itgFormsModel!.totalCount = providerData.itgFormsModel!.totalCount! - 1;
workListItemIndex = null;
calculateCounter(); calculateCounter();
getWorkList(); if (workListItemIndex != null) {
getWorkList();
} else {
setState(() {});
}
} }
// workList!.remove(data);
// AppState().setWorkList = workList;
// if (data.iTEMTYPE == "ITG") {
//
//
// } else {
// providerData.getOpenNotificationsList?.forEach((element) {
// if (element.itemType == data.iTEMTYPE) {
// element.openNtfNumber = element.openNtfNumber! - 1;
// }
// });
// providerData.workListCounter = providerData.workListCounter - 1;
// providerData.notify();
// }
// calculateCounter();
// if (mounted) setState(() {});
} else { } else {
verifyWorkListCounter(); verifyWorkListCounter();
if (mounted) setState(() {}); if (mounted) setState(() {});
@ -466,7 +453,13 @@ class _WorkListScreenState extends State<WorkListScreen> {
if (shouldReloadData != null) { if (shouldReloadData != null) {
if (shouldReloadData.toString() == "delegate_reload") { if (shouldReloadData.toString() == "delegate_reload") {
verifyWorkListCounter(); verifyWorkListCounter();
getWorkList(); workListItemIndex = null;
calculateCounter();
if (workListItemIndex != null) {
getWorkList();
} else {
setState(() {});
}
} else { } else {
workList!.remove(data); workList!.remove(data);
AppState().setWorkList = workList; AppState().setWorkList = workList;

@ -81,7 +81,6 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
GetContactNotificationBodyList? getContactNotificationBodyList; GetContactNotificationBodyList? getContactNotificationBodyList;
List<GetAddressNotificationBodyList>? getAddressNotificationBodyList = []; List<GetAddressNotificationBodyList>? getAddressNotificationBodyList = [];
GenericResponseModel? getBasicNTFBody; GenericResponseModel? getBasicNTFBody;
GenericResponseModel? getICBody; GenericResponseModel? getICBody;
GenericResponseModel? subordinatesLeavesModel; GenericResponseModel? subordinatesLeavesModel;
@ -93,6 +92,9 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
bool isApproveAvailable = false; bool isApproveAvailable = false;
bool isRejectAvailable = false; bool isRejectAvailable = false;
String approveAction = "";
String rejectAction = "";
bool isAttachmentLoaded = false; bool isAttachmentLoaded = false;
bool isActionHistoryLoaded = false; bool isActionHistoryLoaded = false;
@ -169,29 +171,6 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
if (controller.hasClients) { if (controller.hasClients) {
controller.jumpToPage(0); controller.jumpToPage(0);
} }
// List dataToFetch = await Future.wait([
//
// WorkListApiClient().getActionHistory(workListData!.nOTIFICATIONID!),
// WorkListApiClient().getAttachments(workListData!.nOTIFICATIONID!),
// ]);
//
// notificationButtonsList = dataToFetch[0];
// actionHistoryList = dataToFetch[1];
// getAttachmentList = dataToFetch[2];
// if (notificationButtonsList.isNotEmpty) {
// isCloseAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "CLOSE");
// isApproveAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "APPROVED");
// isRejectAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "REJECTED");
// }
// Utils.hideLoading(context);
// setState(() {});
// } catch (ex) {
// Utils.hideLoading(context);
// Utils.handleException(ex, context, null);
// setState(() {});
// }
} }
List<Future> futureRequest = []; List<Future> futureRequest = [];
@ -320,14 +299,14 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
if (isRejectAvailable) if (isRejectAvailable)
DefaultButton( DefaultButton(
LocaleKeys.reject.tr(), LocaleKeys.reject.tr(),
() => performAction("REJECTED"), () => performAction(rejectAction),
colors: const [Color(0xffE47A7E), Color(0xffDE6D71)], colors: const [Color(0xffE47A7E), Color(0xffDE6D71)],
).expanded, ).expanded,
if (isApproveAvailable && isRejectAvailable) 8.width, if (isApproveAvailable && isRejectAvailable) 8.width,
if (isApproveAvailable) if (isApproveAvailable)
DefaultButton( DefaultButton(
LocaleKeys.approve.tr(), LocaleKeys.approve.tr(),
() => performAction("APPROVED"), () => performAction(approveAction),
colors: const [Color(0xff28C884), Color(0xff1BB271)], colors: const [Color(0xff28C884), Color(0xff1BB271)],
).expanded, ).expanded,
if (isCloseAvailable) if (isCloseAvailable)
@ -417,7 +396,11 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
List<Widget> viewApiButtonsList(List<GetNotificationButtonsList> notificationButtonsList) { List<Widget> viewApiButtonsList(List<GetNotificationButtonsList> notificationButtonsList) {
List<Widget> fabs = []; List<Widget> fabs = [];
for (int i = 0; i < notificationButtonsList.length; i++) { for (int i = 0; i < notificationButtonsList.length; i++) {
if (notificationButtonsList[i].bUTTONACTION! == "REJECTED" || notificationButtonsList[i].bUTTONACTION! == "APPROVED" || notificationButtonsList[i].bUTTONACTION! == "CLOSE") { if (notificationButtonsList[i].bUTTONACTION! == "REJECTED" ||
notificationButtonsList[i].bUTTONACTION! == "REJECT" ||
notificationButtonsList[i].bUTTONACTION! == "APPROVED" ||
notificationButtonsList[i].bUTTONACTION! == "APPROVE" ||
notificationButtonsList[i].bUTTONACTION! == "CLOSE") {
continue; continue;
} }
fabs.add(myFab( fabs.add(myFab(
@ -989,8 +972,20 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
notificationButtonsList = await WorkListApiClient().getNotificationButtons(workListData!.nOTIFICATIONID!); notificationButtonsList = await WorkListApiClient().getNotificationButtons(workListData!.nOTIFICATIONID!);
if (notificationButtonsList.isNotEmpty) { if (notificationButtonsList.isNotEmpty) {
isCloseAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "CLOSE"); isCloseAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "CLOSE");
isApproveAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "APPROVED"); isApproveAvailable = notificationButtonsList.any((element) {
isRejectAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "REJECTED"); if (element.bUTTONACTION == "APPROVED" || element.bUTTONACTION == "APPROVE") {
approveAction = element.bUTTONACTION!;
return true;
}
return false;
});
isRejectAvailable = notificationButtonsList.any((element) {
if (element.bUTTONACTION == "REJECTED" || element.bUTTONACTION == "REJECT") {
rejectAction = element.bUTTONACTION!;
return true;
}
return false;
});
} }
apiCallCount--; apiCallCount--;
if (apiCallCount == 0) { if (apiCallCount == 0) {

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
@ -26,6 +25,7 @@ class _WorklistSettingsState extends State<WorklistSettings> {
List<GetUserItemTypesList> getUserItemTypesList = []; List<GetUserItemTypesList> getUserItemTypesList = [];
UpdateUserItemTypesList? updateUserItemTypesList; UpdateUserItemTypesList? updateUserItemTypesList;
@override
void initState() { void initState() {
super.initState(); super.initState();
userItemTypesList(); userItemTypesList();
@ -47,13 +47,17 @@ class _WorklistSettingsState extends State<WorklistSettings> {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
List<Map<String, dynamic>> itemList = []; List<Map<String, dynamic>> itemList = [];
for (var element in getUserItemTypesList) { for (int index = 0; index < getUserItemTypesList.length; index++) {
itemList.add(UpdateUserTypesList(itemID: element.uSERITEMTYPEID, pITEMTYPE: element.iTEMTYPE, pFYAENABLEDFALG: element.fYAENABLEDFALG, pFYIENABLEDFALG: element.fYIENABLEDFLAG).toJson()); itemList.add(UpdateUserTypesList(
itemID: index,
pITEMTYPE: getUserItemTypesList[index].iTEMTYPE,
pFYAENABLEDFALG: getUserItemTypesList[index].fYAENABLEDFALG,
pFYIENABLEDFALG: getUserItemTypesList[index].fYIENABLEDFLAG)
.toJson());
} }
updateUserItemTypesList = await WorkListApiClient().updateUserItemTypes(itemList); updateUserItemTypesList = await WorkListApiClient().updateUserItemTypes(itemList);
Utils.hideLoading(context); Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.workList); Navigator.pop(context);
setState(() {});
} catch (ex) { } catch (ex) {
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, null); Utils.handleException(ex, context, null);
@ -63,87 +67,81 @@ class _WorklistSettingsState extends State<WorklistSettings> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
appBar: AppBarWidget( appBar: AppBarWidget(
context, context,
title: LocaleKeys.worklistSettings.tr(), title: LocaleKeys.worklistSettings.tr(),
), ),
body: Column( body: Column(
children: [ children: [
ListView( ListView(
padding: const EdgeInsets.only(top: 21, left: 21, right: 21), padding: const EdgeInsets.only(top: 21, left: 21, right: 21),
children: [ children: [
LocaleKeys.TurnNotificationsFor.tr().toText22(color: MyColors.blackColor), LocaleKeys.TurnNotificationsFor.tr().toText22(color: MyColors.blackColor),
16.height, 16.height,
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.itemType.tr().toText14(color: MyColors.blackColor), LocaleKeys.itemType.tr().toText14(color: MyColors.blackColor),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: ["FYA".tr().toText14(color: MyColors.blackColor), 30.width, "FYI".tr().toText14(color: MyColors.blackColor), 30.width], children: ["FYA".tr().toText14(color: MyColors.blackColor), 30.width, "FYI".tr().toText14(color: MyColors.blackColor), 30.width],
) )
], ],
), ),
const Divider(color: MyColors.greyA5Color), const Divider(color: MyColors.greyA5Color),
SingleChildScrollView( ListView.separated(
scrollDirection: Axis.vertical, shrinkWrap: true,
child: ListView.builder( physics: const NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical, itemCount: getUserItemTypesList.length,
shrinkWrap: true, separatorBuilder: (cxt, index) => 1.divider,
physics: ScrollPhysics(), itemBuilder: (BuildContext context, int index) => customSwitch(getUserItemTypesList[index]),
itemCount: getUserItemTypesList == null ? 0 : getUserItemTypesList.length, ),
itemBuilder: (BuildContext context, int index) { ],
return Column(children: [ ).expanded,
customSwitch(getUserItemTypesList[index]), DefaultButton(LocaleKeys.save.tr(), () async {
Divider( updateUserItem();
color: MyColors.greyC4Color, }).insideContainer,
thickness: 0.5, ],
), ),
]); );
}),
),
],
).expanded,
DefaultButton(LocaleKeys.save.tr(), () async {
updateUserItem();
}).insideContainer,
],
));
} }
Widget customSwitch(GetUserItemTypesList list) { Widget customSwitch(GetUserItemTypesList list) {
return Padding( return Padding(
padding: const EdgeInsets.only(top: 21), padding: const EdgeInsets.only(top: 8, bottom: 8),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( list.iTEMTYPE!.toText16(),
list.iTEMTYPE.toString(),
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.blackColor),
),
const Spacer(), const Spacer(),
Row( Row(
children: [ children: [
CupertinoSwitch( Transform.scale(
trackColor: MyColors.grey57Color, scale: 0.8,
activeColor: MyColors.textMixColor, child: CupertinoSwitch(
value: list?.fYAENABLEDFALG == 'Y' ? true : false, trackColor: MyColors.grey57Color,
onChanged: (value) { activeColor: MyColors.textMixColor,
setState(() { value: list.fYAENABLEDFALG == 'Y',
list?.fYAENABLEDFALG = value == true ? 'Y' : 'N'; onChanged: (value) {
}); setState(() {
}), list.fYAENABLEDFALG = value ? 'Y' : 'N';
CupertinoSwitch( });
}),
),
Transform.scale(
scale: 0.8,
child: CupertinoSwitch(
trackColor: MyColors.grey57Color, trackColor: MyColors.grey57Color,
activeColor: MyColors.textMixColor, activeColor: MyColors.textMixColor,
value: list?.fYIENABLEDFLAG == 'Y' ? true : false, value: list.fYIENABLEDFLAG == 'Y',
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
// list.isFYI = value; list.fYIENABLEDFLAG = value ? 'Y' : 'N';
list?.fYIENABLEDFLAG = value == true ? 'Y' : 'N';
}); });
}), },
),
),
], ],
) )
], ],

@ -73,7 +73,7 @@ class _BalancesDashboardWidgetState extends State<BalancesDashboardWidget> {
]; ];
} else { } else {
chartModelList = [ chartModelList = [
PieChartModel(LocaleKeys.adult.tr(), accrualList[1].accrualNetEntitlement ?? 0, MyColors.textMixColor, titleAppend: ""), PieChartModel(LocaleKeys.adult.tr(), accrualList[1].accrualNetEntitlement?.toDouble() ?? 0, MyColors.textMixColor, titleAppend: ""),
PieChartModel(LocaleKeys.child.tr(), accrualList[2].accrualNetEntitlement?.toDouble() ?? 0, MyColors.backgroundBlackColor, titleAppend: ""), PieChartModel(LocaleKeys.child.tr(), accrualList[2].accrualNetEntitlement?.toDouble() ?? 0, MyColors.backgroundBlackColor, titleAppend: ""),
PieChartModel(LocaleKeys.infants.tr(), accrualList[3].accrualNetEntitlement?.toDouble() ?? 0, MyColors.pinkColor, titleAppend: ""), PieChartModel(LocaleKeys.infants.tr(), accrualList[3].accrualNetEntitlement?.toDouble() ?? 0, MyColors.pinkColor, titleAppend: ""),
]; ];
@ -101,7 +101,7 @@ class _BalancesDashboardWidgetState extends State<BalancesDashboardWidget> {
ticketBalanceAccrualList = Provider.of<DashboardProviderModel>(context, listen: false).accrualList ?? []; ticketBalanceAccrualList = Provider.of<DashboardProviderModel>(context, listen: false).accrualList ?? [];
if (ticketBalanceAccrualList!.isNotEmpty) { if (ticketBalanceAccrualList!.isNotEmpty) {
chartModelList = [ chartModelList = [
PieChartModel(LocaleKeys.adult.tr(), ticketBalanceAccrualList![1].accrualNetEntitlement ?? 0, MyColors.textMixColor, titleAppend: ""), PieChartModel(LocaleKeys.adult.tr(), ticketBalanceAccrualList![1].accrualNetEntitlement?.toDouble() ?? 0, MyColors.textMixColor, titleAppend: ""),
PieChartModel(LocaleKeys.child.tr(), ticketBalanceAccrualList![2].accrualNetEntitlement?.toDouble() ?? 0, MyColors.backgroundBlackColor, titleAppend: ""), PieChartModel(LocaleKeys.child.tr(), ticketBalanceAccrualList![2].accrualNetEntitlement?.toDouble() ?? 0, MyColors.backgroundBlackColor, titleAppend: ""),
PieChartModel(LocaleKeys.infants.tr(), ticketBalanceAccrualList![3].accrualNetEntitlement?.toDouble() ?? 0, MyColors.pinkColor, titleAppend: ""), PieChartModel(LocaleKeys.infants.tr(), ticketBalanceAccrualList![3].accrualNetEntitlement?.toDouble() ?? 0, MyColors.pinkColor, titleAppend: ""),
]; ];
@ -185,7 +185,7 @@ class _BalancesDashboardWidgetState extends State<BalancesDashboardWidget> {
Widget getChart(List<PieChartModel> chartModelList) { Widget getChart(List<PieChartModel> chartModelList) {
List<Color> _colorList = chartModelList.map((e) => e.color).toList(); List<Color> _colorList = chartModelList.map((e) => e.color).toList();
return PieChart( return PieChart(
dataMap: {for (var e in chartModelList) e.title: e.parsedValue}, dataMap: {for (var e in chartModelList) e.title: e.value},
animationDuration: const Duration(milliseconds: 800), animationDuration: const Duration(milliseconds: 800),
chartRadius: MediaQuery.of(context).size.width / 3.2, chartRadius: MediaQuery.of(context).size.width / 3.2,
colorList: _colorList, colorList: _colorList,

@ -20,10 +20,13 @@ import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart';
import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart'; import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart';
import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart'; import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class SearchEmployeeBottomSheet extends StatefulWidget { class SearchEmployeeBottomSheet extends StatefulWidget {
int? notificationID; int? notificationID;
@ -47,6 +50,8 @@ class SearchEmployeeBottomSheet extends StatefulWidget {
class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> { class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
TextEditingController username = TextEditingController(); TextEditingController username = TextEditingController();
ScrollController sc = ScrollController();
String searchText = ""; String searchText = "";
List<String>? optionsList = [ List<String>? optionsList = [
@ -61,7 +66,7 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
List<ReplacementList>? nonFavouriteUserList; List<ReplacementList>? nonFavouriteUserList;
// Chat Items // Chat Items
List<ChatUser>? chatUsersList = []; late ChatProviderModel provider;
int _selectedSearchIndex = 0; int _selectedSearchIndex = 0;
@ -88,25 +93,54 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
} }
void fetchChatUser({bool isNeedLoading = true}) async { void fetchChatUser({bool isNeedLoading = true}) async {
if (provider.pageNo == 1) provider.chatUsersList!.clear();
try { try {
Utils.showLoading(context); Utils.showLoading(context);
chatUsersList = await ChatApiClient().getChatMemberFromSearch( await ChatApiClient().getChatMemberFromSearch(searchText, AppState().chatDetails!.response!.id!, provider.pageNo).then((ChatUserModel value) {
searchText, if (value.response != null) {
int.parse(AppState().chatDetails!.response!.id.toString()), if (provider.pageNo == 1) {
); provider.chatUsersList = value.response;
chatUsersList!.removeWhere((element) => element.id == AppState().chatDetails!.response!.id); } else {
print("--------------------------Added More----------------------");
provider.chatUsersList!.addAll(value.response!);
}
}
});
provider.chatUsersList!.removeWhere((ChatUser element) => element.id == AppState().chatDetails!.response!.id);
Utils.hideLoading(context); Utils.hideLoading(context);
setState(() {}); setState(() {});
} catch (e) { } catch (e) {
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(e, context, null); Utils.handleException(e, context, null);
} }
if (isNeedLoading) Utils.hideLoading(context); if (isNeedLoading) Utils.hideLoading(context);
setState(() {}); setState(() {});
return null; return null;
} }
void scrollListener() async {
if (sc.position.pixels == sc.position.maxScrollExtent) {
provider.pageNo++;
logger.w(provider.chatUsersList!.length);
logger.w(provider.pageNo);
fetchChatUser();
}
}
@override
void initState() {
super.initState();
sc.addListener(scrollListener);
provider = Provider.of<ChatProviderModel>(context, listen: false);
}
@override
void dispose() {
super.dispose();
provider.chatUsersList = [];
provider.pageNo = 1;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return SizedBox(
@ -123,7 +157,7 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
11.height, 11.height,
Row( Row(
children: [ children: [
radioOption("Name", 0, _selectedSearchIndex), radioOption(widget.fromChat ? "UserId" : "Name", 0, _selectedSearchIndex),
radioOption("User Name", 1, _selectedSearchIndex), radioOption("User Name", 1, _selectedSearchIndex),
radioOption("Email", 2, _selectedSearchIndex), radioOption("Email", 2, _selectedSearchIndex),
], ],
@ -188,73 +222,137 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
], ],
).expanded, ).expanded,
if (widget.fromChat) if (widget.fromChat)
if (chatUsersList != null && widget.fromChat) if (provider.chatUsersList != null && widget.fromChat)
chatUsersList!.isEmpty provider.chatUsersList!.isEmpty
? Column( ? Column(
children: [ children: [
20.height, 20.height,
Utils.getNoDataWidget(context), Utils.getNoDataWidget(context),
], ],
) )
: ListView( : ListView.separated(
physics: const BouncingScrollPhysics(), itemCount: provider.chatUsersList!.length,
padding: const EdgeInsets.only( shrinkWrap: true,
top: 15, physics: const ClampingScrollPhysics(),
), controller: sc,
children: <Widget>[ padding: const EdgeInsets.only(bottom: 80.0, top: 20),
ListView.separated( itemBuilder: (BuildContext context, int index) {
physics: const NeverScrollableScrollPhysics(), return SizedBox(
shrinkWrap: true, height: 55,
itemBuilder: (BuildContext cxt, int index) { child: Row(
return SizedBox( children: [
height: 55, Stack(
child: ListTile( children: <Widget>[
leading: Stack( SvgPicture.asset(
children: [
SvgPicture.asset(
"assets/images/user.svg", "assets/images/user.svg",
height: 48, height: 48,
width: 48, width: 48,
), ),
Positioned( Positioned(
right: 5, right: 5,
bottom: 1, bottom: 1,
child: Container( child: Container(
width: 10, width: 10,
height: 10, height: 10,
decoration: BoxDecoration( decoration: BoxDecoration(
color: chatUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, color: provider.chatUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red,
borderRadius: const BorderRadius.all( ),
Radius.circular(10), ).circle(10),
)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(provider.chatUsersList![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "")
.toText14(color: MyColors.darkTextColor)
.paddingOnly(left: 11, top: 13),
provider.chatUsersList![index].isTyping!
? 'Typing...'
.toText10(
color: MyColors.textMixColor,
)
.paddingOnly(left: 11.0)
: const SizedBox()
],
).expanded,
SizedBox(
width: 60,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
if (provider.chatUsersList![index].unreadMessageCount! > 0)
Container(
alignment: Alignment.center,
width: 18,
height: 18,
decoration: const BoxDecoration(
color: MyColors.redColor,
borderRadius: BorderRadius.all(
Radius.circular(20),
), ),
), ),
), child: (provider.chatUsersList![index].unreadMessageCount!.toString())
) .toText10(
color: MyColors.white,
)
.center,
).paddingOnly(right: 10).center,
Icon(
provider.chatUsersList![index].isFav != null && provider.chatUsersList![index].isFav == false ? Icons.star_sharp : Icons.star_sharp,
color: provider.chatUsersList![index].isFav != null && provider.chatUsersList![index].isFav == true ? MyColors.yellowColor : MyColors.grey35Color,
).onPress(
() {
if (provider.chatUsersList![index].isFav == null || provider.chatUsersList![index].isFav == false) {
provider
.favoriteUser(
userID: AppState().chatDetails!.response!.id!,
targetUserID: provider.chatUsersList![index].id!,
fromSearch: true
)
.then((value) {
setState(() {});
});
} else if (provider.chatUsersList![index].isFav == true) {
provider
.unFavoriteUser(
userID: AppState().chatDetails!.response!.id!,
targetUserID: provider.chatUsersList![index].id!,
)
.then((value) {
setState(() {});
});
} else {
provider
.favoriteUser(
userID: AppState().chatDetails!.response!.id!,
targetUserID: provider.chatUsersList![index].id!,
fromSearch: true
)
.then((value) {
setState(() {});
});
}
},
).center
], ],
), ),
title: (chatUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor),
minVerticalPadding: 0,
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: ChatDetailedScreenParams(chatUsersList![index], true),
);
},
), ),
); ],
},
separatorBuilder: (BuildContext context, int index) => const Padding(
padding: EdgeInsets.only(right: 10, left: 70, bottom: 0, top: 0),
child: Divider(
color: Color(0xFFE5E5E5),
),
), ),
itemCount: chatUsersList?.length ?? 0, ).onPress(() {
), Navigator.pop(context);
12.height, Navigator.pushNamed(
], context,
AppRoutes.chatDetailed,
arguments: ChatDetailedScreenParams(provider.chatUsersList![index], true),
);
});
},
separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 59),
).expanded, ).expanded,
], ],
).paddingOnly(left: 21, right: 21, bottom: 0, top: 21).expanded, ).paddingOnly(left: 21, right: 21, bottom: 0, top: 21).expanded,
@ -263,6 +361,8 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
LocaleKeys.cancel.tr(), LocaleKeys.cancel.tr(),
() { () {
Navigator.pop(context); Navigator.pop(context);
provider.chatUsersList = [];
provider.pageNo = 1;
}, },
textColor: MyColors.grey3AColor, textColor: MyColors.grey3AColor,
colors: const [ colors: const [

@ -11,56 +11,75 @@ import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
AppBar ChatAppBarWidget(BuildContext context, AppBar ChatAppBarWidget(BuildContext context,
{required String title, {required String title, bool showHomeButton = true, ChatUser? chatUser, bool showTyping = false, List<Widget>? actions, void Function()? onHomeTapped, void Function()? onBackTapped}) {
bool showHomeButton = true,
String? image,
ChatUser? chatUser,
bool showTyping = false,
List<Widget>? actions,
void Function()? onHomeTapped,
void Function()? onBackTapped}) {
return AppBar( return AppBar(
leadingWidth: 0, leadingWidth: 0,
title: Row( title: Consumer<ChatProviderModel>(builder: (BuildContext cxt, ChatProviderModel data, Widget? child) {
children: [ return Row(
GestureDetector( children: [
behavior: HitTestBehavior.opaque, GestureDetector(
onTap: Feedback.wrapForTap(() { behavior: HitTestBehavior.opaque,
(onBackTapped == null ? Navigator.maybePop(context) : onBackTapped()); onTap: Feedback.wrapForTap(() {
}, context), (onBackTapped == null ? Navigator.maybePop(context) : onBackTapped());
child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), }, context),
), child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor),
4.width,
if (image != null)
CircularAvatar(
url: image,
height: 40,
width: 40,
isImageBase64: true,
), ),
if (image != null) 14.width, 4.width,
SizedBox( if (chatUser != null)
height: 40, Stack(
child: Column( children: <Widget>[
crossAxisAlignment: CrossAxisAlignment.start, if (chatUser.isImageLoading!)
mainAxisAlignment: MainAxisAlignment.start, const SizedBox(
children: [ height: 48,
title.toText20(color: MyColors.darkTextColor, isBold: true).expanded, width: 48,
if (showTyping) ).toShimmer().circle(30),
Consumer<ChatProviderModel>( if (!chatUser.isImageLoading! && chatUser.userLocalDownlaodedImage == null)
builder: (BuildContext cxt, ChatProviderModel data, Widget? child) { SvgPicture.asset(
if (chatUser!.isTyping!) { "assets/images/user.svg",
return ("Typing ...").toText10(color: MyColors.textMixColor); height: 48,
} else { width: 48,
return const SizedBox(); ),
} if (!chatUser.isImageLoading! && chatUser.userLocalDownlaodedImage != null)
}, Container(
), width: 48.0,
], height: 48.0,
), decoration: BoxDecoration(
) shape: BoxShape.circle,
], image: DecorationImage(
), fit: BoxFit.cover,
image: FileImage(chatUser.userLocalDownlaodedImage!),
),
),
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: chatUser.userStatus == 1 ? MyColors.green2DColor : Colors.red,
),
).circle(10),
)
],
),
if (chatUser != null) 14.width,
SizedBox(
height: 40,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
title.toText20(color: MyColors.darkTextColor, isBold: true).expanded,
if (showTyping)
if (chatUser!.isTyping!) ("Typing ...").toText10(color: MyColors.textMixColor) else const SizedBox(),
],
),
).expanded
],
);
}),
centerTitle: false, centerTitle: false,
elevation: 0, elevation: 0,
backgroundColor: Colors.white, backgroundColor: Colors.white,

@ -20,7 +20,7 @@ class ImageOptions {
if (Platform.isAndroid) { if (Platform.isAndroid) {
cameraImageAndroid(image); cameraImageAndroid(image);
} else { } else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 10))?.path ?? ""); File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))?.path ?? "");
String fileName = _image.path; String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync(); var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes); String base64Encode = base64.encode(bytes);
@ -33,7 +33,7 @@ class ImageOptions {
if (Platform.isAndroid) { if (Platform.isAndroid) {
galleryImageAndroid(image); galleryImageAndroid(image);
} else { } else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 10))?.path ?? ""); File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))?.path ?? "");
String fileName = _image.path; String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync(); var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes); String base64Encode = base64.encode(bytes);
@ -114,7 +114,7 @@ class ImageOptions {
} }
void galleryImageAndroid(Function(String, File) image) async { void galleryImageAndroid(Function(String, File) image) async {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 10))?.path ?? ""); File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))?.path ?? "");
String fileName = _image.path; String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync(); var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes); String base64Encode = base64.encode(bytes);
@ -124,7 +124,7 @@ void galleryImageAndroid(Function(String, File) image) async {
} }
void cameraImageAndroid(Function(String, File) image) async { void cameraImageAndroid(Function(String, File) image) async {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 10))?.path ?? ""); File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))?.path ?? "");
String fileName = _image.path; String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync(); var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes); String base64Encode = base64.encode(bytes);

@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/privilege_list_model.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/dialogs/success_dialog.dart'; import 'package:mohem_flutter_app/ui/dialogs/success_dialog.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
@ -47,7 +48,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
void checkAttendanceAvailability() async { void checkAttendanceAvailability() async {
bool isAvailable = await NfcManager.instance.isAvailable(); bool isAvailable = await NfcManager.instance.isAvailable();
setState(() { setState(() {
AppState().privilegeListModel!.forEach((element) { AppState().privilegeListModel!.forEach((PrivilegeListModel element) {
if (element.serviceName == "enableNFC") { if (element.serviceName == "enableNFC") {
if (isAvailable) if (element.previlege ?? false) isNfcEnabled = true; if (isAvailable) if (element.previlege ?? false) isNfcEnabled = true;
} else if (element.serviceName == "enableQR") { } else if (element.serviceName == "enableQR") {
@ -144,6 +145,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
Future<void> performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async { Future<void> performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
if (Platform.isIOS) { if (Platform.isIOS) {
Utils.readNFc(onRead: (String nfcId) async { Utils.readNFc(onRead: (String nfcId) async {
Utils.showLoading(context); Utils.showLoading(context);
try { try {
@ -152,7 +154,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
Utils.hideLoading(context); Utils.hideLoading(context);
showDialog( showDialog(
context: context, context: context,
builder: (cxt) => ConfirmDialog( builder: (BuildContext cxt) => ConfirmDialog(
message: g?.errorEndUserMessage ?? "Unexpected error occurred", message: g?.errorEndUserMessage ?? "Unexpected error occurred",
onTap: () { onTap: () {
Navigator.pop(context); Navigator.pop(context);
@ -161,20 +163,18 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
); );
} else { } else {
bool status = await model.fetchAttendanceTracking(context); bool status = await model.fetchAttendanceTracking(context);
if (Platform.isIOS) await Future.delayed(const Duration(seconds: 3));
Utils.hideLoading(context); Utils.hideLoading(context);
showMDialog( showMDialog(
context, context,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
isDismissable: false, isDismissable: true,
child: SuccessDialog(widget.isFromDashboard), child: SuccessDialog(widget.isFromDashboard),
); );
} }
} catch (ex) { } catch (ex) {
print(ex);
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, (msg) { Utils.handleException(ex, context, null);
Utils.confirmDialog(context, msg);
});
} }
}); });
} else { } else {
@ -186,7 +186,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
Utils.hideLoading(context); Utils.hideLoading(context);
showDialog( showDialog(
context: context, context: context,
builder: (cxt) => ConfirmDialog( builder: (BuildContext cxt) => ConfirmDialog(
message: g?.errorEndUserMessage ?? "Unexpected error occurred", message: g?.errorEndUserMessage ?? "Unexpected error occurred",
onTap: () { onTap: () {
Navigator.pop(context); Navigator.pop(context);
@ -206,7 +206,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
} catch (ex) { } catch (ex) {
print(ex); print(ex);
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, (msg) { Utils.handleException(ex, context, (String msg) {
Utils.confirmDialog(context, msg); Utils.confirmDialog(context, msg);
}); });
} }
@ -218,20 +218,33 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
Utils.showLoading(context); Utils.showLoading(context);
bool isConnected = await WiFiForIoTPlugin.connect(AppState().getMohemmWifiSSID ?? "", bool isConnected = await WiFiForIoTPlugin.connect(AppState().getMohemmWifiSSID ?? "",
password: AppState().getMohemmWifiPassword ?? "", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false); password: AppState().getMohemmWifiPassword ?? "", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false);
if (isConnected) {
if (Platform.isIOS) { if (Platform.isIOS) {
await closeWifiRequest(); if (await WiFiForIoTPlugin.getSSID() == AppState().getMohemmWifiSSID) {
await Future.delayed(Duration(seconds: 6)); isConnected = true;
} else { } else {
await WiFiForIoTPlugin.forceWifiUsage(true); isConnected = false;
} }
}
if (isConnected) {
// if (Platform.isIOS) {
// await closeWifiRequest();
// await Future.delayed(Duration(seconds: 6));
// } else {
// await WiFiForIoTPlugin.forceWifiUsage(true);
// }
await WiFiForIoTPlugin.forceWifiUsage(true);
await Future.delayed(const Duration(seconds: 6));
try { try {
GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 3, nfcValue: "", isGpsRequired: isWifiLocationEnabled, lat: lat, long: lng); GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 3, nfcValue: "", isGpsRequired: isWifiLocationEnabled, lat: lat, long: lng);
bool status = await model.fetchAttendanceTracking(context); bool status = await model.fetchAttendanceTracking(context);
Utils.hideLoading(context); Utils.hideLoading(context);
if (Platform.isAndroid) { // if (Platform.isAndroid) {
await closeWifiRequest(); // await closeWifiRequest();
} // }
await closeWifiRequest();
showMDialog( showMDialog(
context, context,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
@ -239,12 +252,9 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
child: SuccessDialog(widget.isFromDashboard), child: SuccessDialog(widget.isFromDashboard),
); );
} catch (ex) { } catch (ex) {
print("performWifiAttendance: " + ex.toString());
await closeWifiRequest(); await closeWifiRequest();
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, (msg) { Utils.handleException(ex, context, null);
Utils.confirmDialog(context, msg);
});
} }
} else { } else {
Utils.hideLoading(context); Utils.hideLoading(context);
@ -262,7 +272,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
Future<void> performQrCodeAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async { Future<void> performQrCodeAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
var qrCodeValue = await Navigator.of(context).push( var qrCodeValue = await Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
builder: (context) => QrScannerDialog(), builder: (BuildContext context) => QrScannerDialog(),
), ),
); );
if (qrCodeValue != null) { if (qrCodeValue != null) {
@ -274,15 +284,13 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
showMDialog( showMDialog(
context, context,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
isDismissable: false, isDismissable: true,
child: SuccessDialog(widget.isFromDashboard), child: SuccessDialog(widget.isFromDashboard),
); );
} catch (ex) { } catch (ex) {
print(ex); print(ex);
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, (msg) { Utils.handleException(ex, context, null);
Utils.confirmDialog(context, msg);
});
} }
} }
} }
@ -296,9 +304,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
} catch (ex) { } catch (ex) {
print(ex); print(ex);
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.handleException(ex, context, (msg) { Utils.handleException(ex, context, null);
Utils.confirmDialog(context, msg);
});
} }
} }

@ -132,7 +132,7 @@ class ServicesHeaderShimmer extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
"Other".tr().toText10().toShimmer(), LocaleKeys.otherCharges.tr().toText10().toShimmer(),
6.height, 6.height,
LocaleKeys.services.tr().toText12(isBold: true).toShimmer(), LocaleKeys.services.tr().toText12(isBold: true).toShimmer(),
], ],
@ -273,7 +273,7 @@ class ChatHomeShimmer extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Container( Container(
width: double.infinity, width: double.infinity,
height: 8.0, height: 20.0,
color: Colors.white, color: Colors.white,
), ),
const Padding( const Padding(
@ -281,7 +281,7 @@ class ChatHomeShimmer extends StatelessWidget {
), ),
Container( Container(
width: double.infinity, width: double.infinity,
height: 8.0, height: 15.0,
color: Colors.white, color: Colors.white,
), ),
const Padding( const Padding(
@ -289,7 +289,7 @@ class ChatHomeShimmer extends StatelessWidget {
), ),
Container( Container(
width: 40.0, width: 40.0,
height: 8.0, height: 10.0,
color: Colors.white, color: Colors.white,
), ),
], ],

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1 version: 3.2.0+300020
environment: environment:
sdk: ">=2.16.0 <3.0.0" sdk: ">=2.16.0 <3.0.0"
@ -40,7 +40,7 @@ dependencies:
provider: ^6.0.1 provider: ^6.0.1
easy_localization: ^3.0.0 easy_localization: ^3.0.0
http: ^0.13.4 http: ^0.13.4
permission_handler: ^9.2.0 permission_handler: ^10.2.0
flutter_svg: any flutter_svg: any
sizer: ^2.0.15 sizer: ^2.0.15
local_auth: ^1.1.9 local_auth: ^1.1.9
@ -49,7 +49,7 @@ dependencies:
flutter_calendar_carousel: ^2.1.0 flutter_calendar_carousel: ^2.1.0
pie_chart: ^5.1.0 pie_chart: ^5.1.0
shared_preferences: ^2.0.12 shared_preferences: ^2.0.12
firebase_messaging: ^11.2.8 firebase_messaging: ^13.0.4
shimmer: ^2.0.0 shimmer: ^2.0.0
logger: ^1.1.0 logger: ^1.1.0
flutter_countdown_timer: ^4.1.0 flutter_countdown_timer: ^4.1.0
@ -67,7 +67,7 @@ dependencies:
month_year_picker: ^0.2.0+1 month_year_picker: ^0.2.0+1
month_picker_dialog_2: 0.5.5 month_picker_dialog_2: 0.5.5
open_file: ^3.2.1 open_file: ^3.2.1
wifi_iot: ^0.3.16 wifi_iot: ^0.3.18
flutter_html: ^3.0.0-alpha.6 flutter_html: ^3.0.0-alpha.6
# flutter_barcode_scanner: ^2.0.0 # flutter_barcode_scanner: ^2.0.0
qr_code_scanner: ^1.0.0 qr_code_scanner: ^1.0.0
@ -92,11 +92,11 @@ dependencies:
swipe_to: ^1.0.2 swipe_to: ^1.0.2
flutter_webrtc: ^0.9.16 flutter_webrtc: ^0.9.16
camera: ^0.10.0+4 camera: ^0.10.0+4
#flutter_local_notifications: any
#Chat Voice Message Recoding & Play #Chat Voice Message Recoding & Play
# record: ^4.4.3
audio_waveforms: ^0.1.5+1 audio_waveforms: ^0.1.5+1
# animated_text_kit: ^4.2.2 rxdart: ^0.27.7
#Encryption #Encryption
flutter_des: ^2.1.0 flutter_des: ^2.1.0
@ -106,6 +106,11 @@ dependencies:
safe_device: ^1.1.2 safe_device: ^1.1.2
flutter_layout_grid: ^2.0.1 flutter_layout_grid: ^2.0.1
dependency_overrides:
firebase_core_platform_interface: 4.5.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
@ -138,6 +143,7 @@ flutter:
- assets/icons/ - assets/icons/
- assets/lottie/ - assets/lottie/
- assets/audio/ - assets/audio/
- assets/json/
- assets/images/ - assets/images/
- assets/images/worklist/ - assets/images/worklist/
- assets/images/services_icons/ - assets/images/services_icons/

Loading…
Cancel
Save