Skip to content
GitLab
Explore
Projects
Groups
Topics
Snippets
Projects
Groups
Topics
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Register
Sign in
Toggle navigation
Menu
UPSMF
uphrh-smf-mobile
Commits
b3b1d465
Commit
b3b1d465
authored
3 years ago
by
Shoaib
Browse files
Options
Download
Patches
Plain Diff
Push notifications in progress.
parent
2a6f420b
master
add-assessor-location
deps-update
two-lead-assessor
No related merge requests found
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
android/app/build.gradle
+3
-0
android/app/build.gradle
android/app/google-services.json
+47
-0
android/app/google-services.json
android/app/src/main/AndroidManifest.xml
+6
-1
android/app/src/main/AndroidManifest.xml
android/app/src/main/res/drawable/flutter_devs.png
+0
-0
android/app/src/main/res/drawable/flutter_devs.png
android/build.gradle
+1
-0
android/build.gradle
lib/constants/api_endpoints.dart
+2
-0
lib/constants/api_endpoints.dart
lib/constants/app_constants.dart
+7
-0
lib/constants/app_constants.dart
lib/l10n/app_en.arb
+7
-1
lib/l10n/app_en.arb
lib/landing_page.dart
+63
-33
lib/landing_page.dart
lib/pages/application_details_page.dart
+7
-1
lib/pages/application_details_page.dart
lib/pages/home_page.dart
+1
-1
lib/pages/home_page.dart
lib/pages/inspection_summary.dart
+2
-2
lib/pages/inspection_summary.dart
lib/pages/login_email_page.dart
+29
-6
lib/pages/login_email_page.dart
lib/pages/login_otp_page.dart
+40
-14
lib/pages/login_otp_page.dart
lib/repositories/login_repository.dart
+43
-1
lib/repositories/login_repository.dart
lib/services/login_service.dart
+15
-3
lib/services/login_service.dart
lib/util/helper.dart
+14
-1
lib/util/helper.dart
lib/util/notification_helper.dart
+61
-0
lib/util/notification_helper.dart
lib/widgets/application_card.dart
+28
-22
lib/widgets/application_card.dart
lib/widgets/application_field.dart
+35
-18
lib/widgets/application_field.dart
with
411 additions
and
104 deletions
+411
-104
android/app/build.gradle
+
3
−
0
View file @
b3b1d465
...
...
@@ -23,6 +23,7 @@ if (flutterVersionName == null) {
apply
plugin:
'com.android.application'
apply
plugin:
'kotlin-android'
apply
plugin:
'com.google.gms.google-services'
apply
from:
"$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android
{
...
...
@@ -65,4 +66,6 @@ flutter {
dependencies
{
implementation
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation
'com.google.firebase:firebase-messaging:20.3.0'
}
This diff is collapsed.
Click to expand it.
android/app/google-services.json
0 → 100644
+
47
−
0
View file @
b3b1d465
{
"project_info"
:
{
"project_number"
:
"927565375305"
,
"project_id"
:
"up-smf-47fd3"
,
"storage_bucket"
:
"up-smf-47fd3.appspot.com"
},
"client"
:
[
{
"client_info"
:
{
"mobilesdk_app_id"
:
"1:927565375305:android:72f8b2fed08ff47dc6dc98"
,
"android_client_info"
:
{
"package_name"
:
"com.example.smf_mobile"
}
},
"oauth_client"
:
[
{
"client_id"
:
"927565375305-57h44768ioqql1j8lm5q0jrq4es9lqj8.apps.googleusercontent.com"
,
"client_type"
:
1
,
"android_info"
:
{
"package_name"
:
"com.example.smf_mobile"
,
"certificate_hash"
:
"7157475a2fccb7c2857112262c12be29359f845d"
}
},
{
"client_id"
:
"927565375305-den7asbeb5ucg36rpbn76ppnnd10pm4r.apps.googleusercontent.com"
,
"client_type"
:
3
}
],
"api_key"
:
[
{
"current_key"
:
"AIzaSyDmWSOiwgEnSoTt6GKiArZT9wHREe-f1rw"
}
],
"services"
:
{
"appinvite_service"
:
{
"other_platform_oauth_client"
:
[
{
"client_id"
:
"927565375305-den7asbeb5ucg36rpbn76ppnnd10pm4r.apps.googleusercontent.com"
,
"client_type"
:
3
}
]
}
}
}
],
"configuration_version"
:
"1"
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
android/app/src/main/AndroidManifest.xml
+
6
−
1
View file @
b3b1d465
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"com.example.smf_mobile"
>
<application
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<application
android:label=
"UP SMF"
android:name=
"${applicationName}"
android:icon=
"@mipmap/ic_launcher"
>
...
...
@@ -24,6 +25,10 @@
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
<intent-filter>
<action
android:name=
"FLUTTER_NOTIFICATION_CLICK"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
...
...
This diff is collapsed.
Click to expand it.
android/app/src/main/res/drawable/flutter_devs.png
0 → 100644
+
0
−
0
View file @
b3b1d465
37 KB
This diff is collapsed.
Click to expand it.
android/build.gradle
+
1
−
0
View file @
b3b1d465
...
...
@@ -8,6 +8,7 @@ buildscript {
dependencies
{
classpath
'com.android.tools.build:gradle:4.1.0'
classpath
"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath
'com.google.gms:google-services:4.3.4'
}
}
...
...
This diff is collapsed.
Click to expand it.
lib/constants/api_endpoints.dart
+
2
−
0
View file @
b3b1d465
...
...
@@ -2,6 +2,8 @@ class ApiUrl {
static
const
baseUrl
=
'https://smfdev.idc.tarento.com'
;
static
const
getOtp
=
'
$baseUrl
/api/user/requestOTP'
;
static
const
validateOtp
=
'
$baseUrl
/api/signIn'
;
static
const
updateUserDeviceToken
=
'
$baseUrl
/api/user/updateUserDeviceToken'
;
static
const
getAllApplications
=
'
$baseUrl
/api/forms/getAllApplications'
;
static
const
submitInspection
=
'
$baseUrl
/api/forms/submitInspection'
;
static
const
getAllUsers
=
'
$baseUrl
/api/user/v1/getAllUser'
;
...
...
This diff is collapsed.
Click to expand it.
lib/constants/app_constants.dart
+
7
−
0
View file @
b3b1d465
...
...
@@ -18,6 +18,13 @@ class FieldType {
}
class
InspectionStatus
{
static
const
String
newInspection
=
'NEW'
;
static
const
String
sentForInspection
=
'SENTFORINS'
;
static
const
String
inspectionCompleted
=
'INSCOMPLETED'
;
static
const
String
returned
=
'RETURNED'
;
}
class
FieldValue
{
static
const
String
correct
=
'Correct'
;
static
const
String
inCorrect
=
'Incorrect'
;
}
This diff is collapsed.
Click to expand it.
lib/l10n/app_en.arb
+
7
−
1
View file @
b3b1d465
...
...
@@ -13,5 +13,11 @@
"viewPastApplications"
:
"View past applications"
,
"next"
:
"Next"
,
"previous"
:
"previous"
,
"inspectionCompleted"
:
"Inspection completed"
"inspectionCompleted"
:
"Inspection completed"
,
"sessionExpiredMessage"
:
"Your session has expired."
,
"isGivenInformationCorrect"
:
"Is the given information found correct?"
,
"typeHere"
:
"Type here"
,
"cancel"
:
"Cancel"
,
"submit"
:
"Submit"
,
"actualValue"
:
"Actual value(s)"
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
lib/landing_page.dart
+
63
−
33
View file @
b3b1d465
...
...
@@ -8,11 +8,13 @@ import 'package:smf_mobile/repositories/application_repository.dart';
import
'package:smf_mobile/repositories/form_repository.dart'
;
import
'package:smf_mobile/repositories/login_repository.dart'
;
import
'package:smf_mobile/repositories/user_repository.dart'
;
import
'package:smf_mobile/util/helper.dart'
;
import
'constants/app_constants.dart'
;
import
'constants/app_urls.dart'
;
import
'constants/color_constants.dart'
;
import
'routes.dart'
;
import
'package:flutter_gen/gen_l10n/app_localizations.dart'
;
import
'package:firebase_core/firebase_core.dart'
;
class
LandingPage
extends
StatefulWidget
{
static
const
route
=
AppUrl
.
landingPage
;
...
...
@@ -28,6 +30,12 @@ class LandingPage extends StatefulWidget {
class
_LandingPageState
extends
State
<
LandingPage
>
{
final
client
=
HttpClient
();
Locale
_locale
=
const
Locale
(
'en'
,
'US'
);
bool
_isTokenExpired
=
false
;
@override
void
initState
()
{
super
.
initState
();
}
void
setLocale
(
Locale
value
)
{
setState
(()
{
...
...
@@ -35,40 +43,62 @@ class _LandingPageState extends State<LandingPage> {
});
}
Future
<
dynamic
>
_initilizeApp
()
async
{
_isTokenExpired
=
await
Helper
.
isTokenExpired
();
await
Firebase
.
initializeApp
();
// await Future.delayed(const Duration(microseconds: 100));
return
true
;
}
@override
Widget
build
(
BuildContext
context
)
{
return
MultiProvider
(
providers:
[
ChangeNotifierProvider
.
value
(
value:
LoginRespository
()),
ChangeNotifierProvider
.
value
(
value:
ApplicationRespository
()),
ChangeNotifierProvider
.
value
(
value:
UserRespository
()),
ChangeNotifierProvider
.
value
(
value:
FormRespository
()),
],
child:
MaterialApp
(
title:
appName
,
locale:
_locale
,
localizationsDelegates:
const
[
AppLocalizations
.
delegate
,
GlobalMaterialLocalizations
.
delegate
,
GlobalWidgetsLocalizations
.
delegate
,
GlobalCupertinoLocalizations
.
delegate
,
],
supportedLocales:
const
[
Locale
(
'en'
,
'US'
),
// Locale('es', 'ES'),
],
theme:
ThemeData
(
scaffoldBackgroundColor:
AppColors
.
scaffoldBackground
,
primaryColor:
Colors
.
white
,
visualDensity:
VisualDensity
.
adaptivePlatformDensity
,
dividerColor:
AppColors
.
black08
,
canvasColor:
Colors
.
white
,
unselectedWidgetColor:
AppColors
.
black40
),
debugShowCheckedModeBanner:
false
,
onGenerateRoute:
Routes
.
generateRoute
,
onUnknownRoute:
Routes
.
errorRoute
,
home:
const
LoginEmailPage
(),
// home: const HomePage(),
));
return
Container
(
color:
AppColors
.
scaffoldBackground
,
child:
FutureBuilder
(
// Initialize FlutterFire
future:
_initilizeApp
(),
builder:
(
context
,
AsyncSnapshot
<
dynamic
>
snapshot
)
{
// Check for errors
if
(
snapshot
.
hasData
)
{
return
MultiProvider
(
providers:
[
ChangeNotifierProvider
.
value
(
value:
LoginRespository
()),
ChangeNotifierProvider
.
value
(
value:
ApplicationRespository
()),
ChangeNotifierProvider
.
value
(
value:
UserRespository
()),
ChangeNotifierProvider
.
value
(
value:
FormRespository
()),
],
child:
MaterialApp
(
title:
appName
,
locale:
_locale
,
localizationsDelegates:
const
[
AppLocalizations
.
delegate
,
GlobalMaterialLocalizations
.
delegate
,
GlobalWidgetsLocalizations
.
delegate
,
GlobalCupertinoLocalizations
.
delegate
,
],
supportedLocales:
const
[
Locale
(
'en'
,
'US'
),
// Locale('es', 'ES'),
],
theme:
ThemeData
(
scaffoldBackgroundColor:
AppColors
.
scaffoldBackground
,
primaryColor:
Colors
.
white
,
visualDensity:
VisualDensity
.
adaptivePlatformDensity
,
dividerColor:
AppColors
.
black08
,
canvasColor:
Colors
.
white
,
unselectedWidgetColor:
AppColors
.
black40
),
debugShowCheckedModeBanner:
false
,
onGenerateRoute:
Routes
.
generateRoute
,
onUnknownRoute:
Routes
.
errorRoute
,
home:
!
_isTokenExpired
?
const
HomePage
()
:
const
LoginEmailPage
(),
// home: const HomePage(),
));
}
else
{
return
const
Center
();
}
}));
}
}
This diff is collapsed.
Click to expand it.
lib/pages/application_details_page.dart
+
7
−
1
View file @
b3b1d465
...
...
@@ -32,6 +32,7 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
int
_activeTabIndex
=
0
;
final
Map
_data
=
{};
final
Map
_fieldTypes
=
{};
final
Map
_fieldOptions
=
{};
final
List
<
String
>
_tabs
=
[];
final
List
<
Map
>
_fields
=
[];
...
...
@@ -59,6 +60,8 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
if
(
_formData
.
fields
[
i
][
'fieldType'
]
!=
FieldType
.
heading
)
{
_fieldTypes
[
_formData
.
fields
[
i
][
'name'
]]
=
_formData
.
fields
[
i
][
'fieldType'
];
_fieldOptions
[
_formData
.
fields
[
i
][
'name'
]]
=
_formData
.
fields
[
i
][
'values'
];
}
}
}
...
...
@@ -98,12 +101,13 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
})
}
});
// print(fieldData);
}
void
_validateUser
()
async
{
bool
tokenExpired
=
await
Helper
.
isTokenExpired
();
if
(
tokenExpired
)
{
Helper
.
toastMessage
(
'Your session has expired.'
);
Helper
.
toastMessage
(
AppLocalizations
.
of
(
context
)
!.
sessionExpiredMessage
);
Navigator
.
of
(
context
)
.
pushReplacement
(
MaterialPageRoute
(
builder:
(
context
)
=
>
const
LoginEmailPage
(),
));
...
...
@@ -241,6 +245,8 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
field
.
keys
.
elementAt
(
i
)],
fieldType:
_fieldTypes
[
field
.
keys
.
elementAt
(
i
)],
fieldOptions:
_fieldOptions
[
field
.
keys
.
elementAt
(
i
)],
applicationStatus:
widget
.
application
.
status
,
parentAction:
updateField
,
...
...
This diff is collapsed.
Click to expand it.
lib/pages/home_page.dart
+
1
−
1
View file @
b3b1d465
...
...
@@ -34,7 +34,7 @@ class _HomePageState extends State<HomePage> {
void
_validateUser
()
async
{
bool
tokenExpired
=
await
Helper
.
isTokenExpired
();
if
(
tokenExpired
)
{
Helper
.
toastMessage
(
'Your session has expired.'
);
Helper
.
toastMessage
(
AppLocalizations
.
of
(
context
)
!.
sessionExpiredMessage
);
Navigator
.
of
(
context
)
.
pushReplacement
(
MaterialPageRoute
(
builder:
(
context
)
=
>
const
LoginEmailPage
(),
));
...
...
This diff is collapsed.
Click to expand it.
lib/pages/inspection_summary.dart
+
2
−
2
View file @
b3b1d465
import
'package:flutter/material.dart'
;
import
'package:fluttertoast/fluttertoast.dart'
;
import
'package:google_fonts/google_fonts.dart'
;
import
'package:provider/provider.dart'
;
import
'package:smf_mobile/constants/app_constants.dart'
;
...
...
@@ -12,6 +11,7 @@ import 'package:smf_mobile/repositories/form_repository.dart';
import
'package:smf_mobile/util/helper.dart'
;
import
'package:smf_mobile/widgets/people_card.dart'
;
import
'inspection_completed.dart'
;
import
'package:flutter_gen/gen_l10n/app_localizations.dart'
;
class
InspectionSummaryPage
extends
StatefulWidget
{
static
const
route
=
AppUrl
.
inspectionSummary
;
...
...
@@ -65,7 +65,7 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> {
void
_validateUser
()
async
{
bool
tokenExpired
=
await
Helper
.
isTokenExpired
();
if
(
tokenExpired
)
{
Helper
.
toastMessage
(
'Your session has expired.'
);
Helper
.
toastMessage
(
AppLocalizations
.
of
(
context
)
!.
sessionExpiredMessage
);
Navigator
.
of
(
context
)
.
pushReplacement
(
MaterialPageRoute
(
builder:
(
context
)
=
>
const
LoginEmailPage
(),
));
...
...
This diff is collapsed.
Click to expand it.
lib/pages/login_email_page.dart
+
29
−
6
View file @
b3b1d465
// import 'dart:math';
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
import
'package:provider/provider.dart'
;
...
...
@@ -8,6 +9,8 @@ import 'package:smf_mobile/pages/login_otp_page.dart';
import
'package:smf_mobile/repositories/login_repository.dart'
;
import
'package:smf_mobile/util/helper.dart'
;
import
'package:flutter_gen/gen_l10n/app_localizations.dart'
;
import
'package:firebase_messaging/firebase_messaging.dart'
;
import
'package:smf_mobile/util/notification_helper.dart'
;
class
LoginEmailPage
extends
StatefulWidget
{
static
const
route
=
AppUrl
.
loginEmailPage
;
...
...
@@ -20,19 +23,39 @@ class LoginEmailPage extends StatefulWidget {
class
_LoginEmailPageState
extends
State
<
LoginEmailPage
>
{
final
TextEditingController
_emailController
=
TextEditingController
();
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
GlobalKey
<
ScaffoldState
>();
FirebaseMessaging
messaging
=
FirebaseMessaging
.
instance
;
String
_errorMessage
=
''
;
late
Locale
locale
;
@override
void
initState
()
{
super
.
initState
();
// _configureMessaging();
}
// This method should be triggered on some event
// _setLang() async {
// locale = const Locale('es', '');
// LandingPage.of(context)?.setLocale(locale);
// _configureMessaging() async {
// NotificationSettings settings = await messaging.requestPermission(
// alert: true,
// announcement: false,
// badge: true,
// carPlay: false,
// criticalAlert: false,
// provisional: false,
// sound: true,
// );
// print('User granted permission: ${settings.authorizationStatus}');
// FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// if (message.notification != null) {
// var random = Random();
// int notificationId = random.nextInt(999999);
// String body =
// message.notification!.body.toString() + message.data.toString();
// NotificationHelper.scheduleNotification(context, DateTime.now(),
// notificationId, message.notification!.title.toString(), body);
// }
// print('Message data: $message');
// });
// }
Future
<
void
>
_generateOtp
()
async
{
...
...
@@ -45,7 +68,7 @@ class _LoginEmailPageState extends State<LoginEmailPage> {
try
{
final
responseCode
=
await
Provider
.
of
<
LoginRespository
>(
context
,
listen:
false
)
.
getOtp
(
email
);
.
getOtp
(
email
.
trim
()
);
if
(
responseCode
==
200
)
{
Navigator
.
of
(
context
)
.
pushReplacement
(
MaterialPageRoute
(
builder:
(
context
)
=
>
const
LoginOtpPage
(),
...
...
This diff is collapsed.
Click to expand it.
lib/pages/login_otp_page.dart
+
40
−
14
View file @
b3b1d465
...
...
@@ -10,6 +10,8 @@ import 'package:otp_text_field/style.dart';
import
'package:smf_mobile/repositories/login_repository.dart'
;
import
'package:smf_mobile/util/helper.dart'
;
import
'package:flutter_gen/gen_l10n/app_localizations.dart'
;
import
'package:unique_identifier/unique_identifier.dart'
;
import
'package:flutter/services.dart'
;
class
LoginOtpPage
extends
StatefulWidget
{
static
const
route
=
AppUrl
.
loginOtpPage
;
...
...
@@ -23,10 +25,27 @@ class _LoginOtpPageState extends State<LoginOtpPage> {
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
GlobalKey
<
ScaffoldState
>();
String
_errorMessage
=
''
;
String
_otp
=
''
;
late
String
_identifier
;
@override
void
initState
()
{
super
.
initState
();
initUniqueIdentifierState
();
}
Future
<
void
>
initUniqueIdentifierState
()
async
{
String
?
identifier
;
try
{
identifier
=
await
UniqueIdentifier
.
serial
;
}
on
PlatformException
{
identifier
=
'Failed to get Unique Identifier'
;
}
if
(
!
mounted
)
return
;
setState
(()
{
_identifier
=
identifier
!
;
});
}
Future
<
void
>
_validateOtp
()
async
{
...
...
@@ -34,7 +53,7 @@ class _LoginOtpPageState extends State<LoginOtpPage> {
try
{
final
responseCode
=
await
Provider
.
of
<
LoginRespository
>(
context
,
listen:
false
)
.
validateOtp
(
otp
);
.
validateOtp
(
context
,
otp
,
_identifier
);
if
(
responseCode
==
200
)
{
Navigator
.
of
(
context
)
.
pushReplacement
(
MaterialPageRoute
(
builder:
(
context
)
=
>
const
HomePage
(),
...
...
@@ -144,19 +163,26 @@ class _LoginOtpPageState extends State<LoginOtpPage> {
color:
Colors
.
white
,
),
child:
OTPTextField
(
length:
6
,
width:
MediaQuery
.
of
(
context
)
.
size
.
width
,
fieldWidth:
38
,
style:
const
TextStyle
(
fontSize:
14
),
textFieldAlignment:
MainAxisAlignment
.
spaceAround
,
fieldStyle:
FieldStyle
.
underline
,
onCompleted:
(
pin
)
{
setState
(()
{
_otp
=
pin
;
});
},
),
length:
6
,
width:
MediaQuery
.
of
(
context
)
.
size
.
width
,
fieldWidth:
38
,
style:
const
TextStyle
(
fontSize:
14
),
textFieldAlignment:
MainAxisAlignment
.
spaceAround
,
fieldStyle:
FieldStyle
.
underline
,
onCompleted:
(
pin
)
{
setState
(()
{
_otp
=
pin
;
});
},
onChanged:
(
String
?
pin
)
{
if
(
pin
?.
length
==
6
)
{
setState
(()
{
_otp
=
pin
.
toString
();
});
}
}),
)
],
),
...
...
This diff is collapsed.
Click to expand it.
lib/repositories/login_repository.dart
+
43
−
1
View file @
b3b1d465
import
'dart:convert'
;
import
'package:firebase_messaging/firebase_messaging.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:smf_mobile/models/login_model.dart'
;
import
'package:flutter_secure_storage/flutter_secure_storage.dart'
;
import
'package:smf_mobile/services/login_service.dart'
;
import
'package:smf_mobile/util/helper.dart'
;
import
'package:smf_mobile/util/notification_helper.dart'
;
class
LoginRespository
with
ChangeNotifier
{
late
Map
_data
;
late
Login
_loginDetails
;
String
_errorMessage
=
''
;
final
FirebaseMessaging
_firebaseMessaging
=
FirebaseMessaging
.
instance
;
final
_storage
=
const
FlutterSecureStorage
();
...
...
@@ -27,7 +31,7 @@ class LoginRespository with ChangeNotifier {
return
_data
[
'statusInfo'
][
'statusCode'
];
}
Future
<
dynamic
>
validateOtp
(
String
otp
)
async
{
Future
<
dynamic
>
validateOtp
(
context
,
String
otp
,
String
identifier
)
async
{
try
{
final
username
=
await
_storage
.
read
(
key:
'username'
);
final
request
=
await
LoginService
.
validateOtp
(
username
!
,
otp
);
...
...
@@ -45,10 +49,48 @@ class LoginRespository with ChangeNotifier {
_storage
.
write
(
key:
'firstName'
,
value:
_loginDetails
.
firstName
);
_storage
.
write
(
key:
'lastName'
,
value:
_loginDetails
.
lastName
);
_storage
.
write
(
key:
'authToken'
,
value:
_loginDetails
.
authToken
);
_firebaseMessaging
.
getToken
()
.
then
((
token
)
async
{
final
request
=
await
LoginService
.
updateUserDeviceToken
(
token
.
toString
(),
identifier
,
_loginDetails
.
id
,
);
_data
=
json
.
decode
(
request
.
body
);
// print(_data);
if
(
_data
[
'statusInfo'
][
'statusCode'
]
==
200
)
{
// print('_configureMessaging...');
_configureMessaging
(
context
);
}
});
}
return
_data
[
'statusInfo'
][
'statusCode'
];
}
_configureMessaging
(
context
)
async
{
NotificationSettings
settings
=
await
_firebaseMessaging
.
requestPermission
(
alert:
true
,
announcement:
false
,
badge:
true
,
carPlay:
false
,
criticalAlert:
false
,
provisional:
false
,
sound:
true
,
);
print
(
'User granted permission:
${settings.authorizationStatus}
'
);
FirebaseMessaging
.
onMessage
.
listen
((
RemoteMessage
message
)
{
print
(
'message.notification...'
);
if
(
message
.
notification
!=
null
)
{
// int uniqueNotificationId = Helper.getUniqueId();
String
body
=
message
.
notification
!.
body
.
toString
();
NotificationHelper
.
scheduleNotification
(
context
,
DateTime
.
now
(),
0
,
message
.
notification
!.
title
.
toString
(),
body
);
}
print
(
'Message data:
$message
'
);
});
return
;
}
Future
<
void
>
clearData
()
async
{
await
_storage
.
deleteAll
();
}
...
...
This diff is collapsed.
Click to expand it.
lib/services/login_service.dart
+
15
−
3
View file @
b3b1d465
...
...
@@ -9,9 +9,7 @@ class LoginService extends BaseService {
LoginService
(
HttpClient
client
)
:
super
(
client
);
static
Future
<
dynamic
>
getOtp
(
String
username
)
async
{
Map
requestData
=
{
'username'
:
username
,
};
Map
requestData
=
{
'username'
:
username
,
'isMobile'
:
true
};
var
body
=
json
.
encode
(
requestData
);
Map
<
String
,
String
>
headers
=
await
BaseService
.
getHeaders
();
final
response
=
...
...
@@ -27,4 +25,18 @@ class LoginService extends BaseService {
headers:
headers
,
body:
body
);
return
response
;
}
static
Future
<
dynamic
>
updateUserDeviceToken
(
String
token
,
String
identifier
,
int
userId
)
async
{
Map
requestData
=
{
"deviceToken"
:
token
,
"deviceId"
:
identifier
,
"userId"
:
userId
};
var
body
=
json
.
encode
(
requestData
);
Map
<
String
,
String
>
headers
=
await
BaseService
.
getHeaders
();
final
response
=
await
http
.
post
(
Uri
.
parse
(
ApiUrl
.
updateUserDeviceToken
),
headers:
headers
,
body:
body
);
return
response
;
}
}
This diff is collapsed.
Click to expand it.
lib/util/helper.dart
+
14
−
1
View file @
b3b1d465
import
'dart:math'
;
import
'package:flutter/material.dart'
;
import
'package:fluttertoast/fluttertoast.dart'
;
import
'package:jwt_decoder/jwt_decoder.dart'
;
...
...
@@ -33,7 +35,9 @@ class Helper {
static
Future
<
bool
>
isTokenExpired
()
async
{
bool
isTokenExpired
=
true
;
var
authToken
=
await
_storage
.
read
(
key:
'authToken'
);
isTokenExpired
=
JwtDecoder
.
isExpired
(
authToken
!
);
if
(
authToken
!=
null
)
{
isTokenExpired
=
JwtDecoder
.
isExpired
(
authToken
);
}
return
isTokenExpired
;
}
...
...
@@ -47,4 +51,13 @@ class Helper {
textColor:
Colors
.
white
,
fontSize:
16.0
);
}
static
getUniqueId
()
{
DateTime
_now
=
DateTime
.
now
();
var
random
=
Random
();
int
id1
=
random
.
nextInt
(
99999
);
int
id2
=
random
.
nextInt
(
99999
);
int
notificationId
=
id1
+
id2
+
_now
.
millisecond
;
return
notificationId
;
}
}
This diff is collapsed.
Click to expand it.
lib/util/notification_helper.dart
0 → 100644
+
61
−
0
View file @
b3b1d465
// import 'dart:convert';
// import 'package:crypto/crypto.dart';
import
'dart:convert'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_local_notifications/flutter_local_notifications.dart'
;
import
'package:smf_mobile/pages/home_page.dart'
;
class
NotificationHelper
{
// static BuildContext get context => null;
static
void
onSelectNotification
(
BuildContext
context
,
String
payload
,
)
{
Navigator
.
of
(
context
)
.
pushReplacement
(
MaterialPageRoute
(
builder:
(
context
)
=
>
const
HomePage
(),
));
}
static
Future
<
void
>
scheduleNotification
(
BuildContext
context
,
DateTime
scheduledNotificationDateTime
,
int
notificationId
,
String
title
,
String
notes
)
async
{
FlutterLocalNotificationsPlugin
flutterLocalNotificationsPlugin
=
FlutterLocalNotificationsPlugin
();
var
initializationSettingsAndroid
=
const
AndroidInitializationSettings
(
'flutter_devs'
);
var
initializationSettingsIOs
=
const
IOSInitializationSettings
();
var
initSetttings
=
InitializationSettings
(
android:
initializationSettingsAndroid
,
iOS:
initializationSettingsIOs
);
flutterLocalNotificationsPlugin
.
initialize
(
initSetttings
,
onSelectNotification:
(
payload
)
async
{
onSelectNotification
(
context
,
payload
!
);
});
var
androidPlatformChannelSpecifics
=
const
AndroidNotificationDetails
(
'channel id'
,
'channel name'
,
icon:
'flutter_devs'
,
enableVibration:
true
,
enableLights:
true
,
playSound:
true
,
// sound: RawResourceAndroidNotificationSound('mixkit_happy_bell'),
largeIcon:
DrawableResourceAndroidBitmap
(
'flutter_devs'
),
styleInformation:
BigTextStyleInformation
(
''
),
);
var
iOSPlatformChannelSpecifics
=
const
IOSNotificationDetails
();
var
platformChannelSpecifics
=
NotificationDetails
(
android:
androidPlatformChannelSpecifics
,
iOS:
iOSPlatformChannelSpecifics
);
Map
payload
=
{};
// ignore: deprecated_member_use
await
flutterLocalNotificationsPlugin
.
schedule
(
notificationId
,
title
,
notes
,
scheduledNotificationDateTime
,
platformChannelSpecifics
,
payload:
jsonEncode
(
payload
));
}
}
This diff is collapsed.
Click to expand it.
lib/widgets/application_card.dart
+
28
−
22
View file @
b3b1d465
...
...
@@ -17,11 +17,29 @@ class ApplicationCard extends StatefulWidget {
}
class
_ApplicationCardState
extends
State
<
ApplicationCard
>
{
String
_inspectionStatus
=
''
;
@override
void
initState
()
{
super
.
initState
();
_getInspectionStatus
();
}
void
_getInspectionStatus
()
{
if
(
widget
.
application
.
status
==
InspectionStatus
.
inspectionCompleted
)
{
_inspectionStatus
=
'Completed'
;
}
else
if
(
widget
.
application
.
status
==
InspectionStatus
.
sentForInspection
)
{
_inspectionStatus
=
'Pending'
;
}
else
{
_inspectionStatus
=
_toCapitalized
(
widget
.
application
.
status
);
}
setState
(()
{});
}
_toCapitalized
(
String
string
)
=
>
string
.
isNotEmpty
?
'
${string[0].toUpperCase()}${string.substring(1).toLowerCase()}
'
:
''
;
@override
Widget
build
(
BuildContext
context
)
{
return
InkWell
(
...
...
@@ -89,28 +107,16 @@ class _ApplicationCardState extends State<ApplicationCard> {
fontWeight:
FontWeight
.
w400
,
)),
),
widget
.
application
.
status
==
InspectionStatus
.
inspectionCompleted
?
Padding
(
padding:
const
EdgeInsets
.
only
(
bottom:
10
),
child:
Text
(
'Completed'
,
style:
GoogleFonts
.
lato
(
color:
AppColors
.
black60
,
fontSize:
14.0
,
letterSpacing:
0.12
,
fontWeight:
FontWeight
.
w700
,
)),
)
:
Padding
(
padding:
const
EdgeInsets
.
only
(
bottom:
10
),
child:
Text
(
'Pending'
,
style:
GoogleFonts
.
lato
(
color:
AppColors
.
black60
,
fontSize:
14.0
,
letterSpacing:
0.12
,
fontWeight:
FontWeight
.
w700
,
)),
)
Padding
(
padding:
const
EdgeInsets
.
only
(
bottom:
10
),
child:
Text
(
_inspectionStatus
,
style:
GoogleFonts
.
lato
(
color:
AppColors
.
black60
,
fontSize:
14.0
,
letterSpacing:
0.12
,
fontWeight:
FontWeight
.
w700
,
)),
),
],
)
],
...
...
This diff is collapsed.
Click to expand it.
lib/widgets/application_field.dart
+
35
−
18
View file @
b3b1d465
...
...
@@ -3,11 +3,13 @@ import 'package:google_fonts/google_fonts.dart';
import
'package:smf_mobile/constants/app_constants.dart'
;
import
'package:smf_mobile/constants/color_constants.dart'
;
import
'package:smf_mobile/widgets/application_field_dialog.dart'
;
import
'package:flutter_gen/gen_l10n/app_localizations.dart'
;
class
ApplicationField
extends
StatefulWidget
{
final
String
fieldName
;
final
Map
fieldData
;
final
String
fieldType
;
final
List
fieldOptions
;
final
String
applicationStatus
;
final
ValueChanged
<
Map
>
parentAction
;
const
ApplicationField
({
...
...
@@ -15,6 +17,7 @@ class ApplicationField extends StatefulWidget {
required
this
.
fieldName
,
required
this
.
fieldData
,
required
this
.
fieldType
,
required
this
.
fieldOptions
,
required
this
.
applicationStatus
,
required
this
.
parentAction
,
})
:
super
(
key:
key
);
...
...
@@ -27,15 +30,21 @@ class _ApplicationFieldState extends State<ApplicationField> {
late
String
_radioValue
;
String
_inspectionValue
=
''
;
String
_summaryText
=
''
;
final
List
<
String
>
_options
=
[
'C
orrect
'
,
'Inc
orrect
'
];
final
List
<
String
>
_options
=
[
FieldValue
.
c
orrect
,
FieldValue
.
inC
orrect
];
@override
void
initState
()
{
super
.
initState
();
// print(widget.fieldName + ', ' + widget.fieldType);
_data
=
widget
.
fieldData
[
widget
.
fieldData
.
keys
.
elementAt
(
0
)];
// print('Field: ' + _data.toString());
_radioValue
=
_data
[
_data
.
keys
.
elementAt
(
0
)];
_summaryText
=
_data
[
_data
.
keys
.
elementAt
(
1
)];
try
{
_inspectionValue
=
_data
[
_data
.
keys
.
elementAt
(
2
)];
}
catch
(
_
)
{
return
;
}
}
triggerUpdate
(
Map
dialogData
)
{
...
...
@@ -64,6 +73,7 @@ class _ApplicationFieldState extends State<ApplicationField> {
summaryText:
_summaryText
,
inspectionValue:
_inspectionValue
,
fieldType:
widget
.
fieldType
,
fieldOptions:
widget
.
fieldOptions
,
parentAction:
triggerUpdate
,
);
}));
...
...
@@ -158,7 +168,8 @@ class _ApplicationFieldState extends State<ApplicationField> {
width:
MediaQuery
.
of
(
context
)
.
size
.
width
,
padding:
const
EdgeInsets
.
only
(
bottom:
10
),
child:
Text
(
'Is the given information found correct?'
,
AppLocalizations
.
of
(
context
)
!
.
sessionExpiredMessage
,
style:
GoogleFonts
.
lato
(
color:
AppColors
.
black60
,
fontWeight:
FontWeight
.
w700
,
...
...
@@ -182,7 +193,7 @@ class _ApplicationFieldState extends State<ApplicationField> {
_radioValue
=
_options
[
i
];
});
if
(
_options
[
i
]
==
'Inc
orrect
'
)
{
FieldValue
.
inC
orrect
)
{
_displayCommentDialog
();
}
Map
data
=
{
...
...
@@ -239,7 +250,8 @@ class _ApplicationFieldState extends State<ApplicationField> {
};
triggerUpdate
(
data
);
if
(
_options
[
i
]
==
'Incorrect'
)
{
FieldValue
.
inCorrect
)
{
_displayCommentDialog
();
}
}
...
...
@@ -264,24 +276,27 @@ class _ApplicationFieldState extends State<ApplicationField> {
if
(
widget
.
applicationStatus
==
InspectionStatus
.
sentForInspection
&&
_radioValue
!=
'Correct'
)
{
_radioValue
!=
FieldValue
.
correct
)
{
_displayCommentDialog
();
}
},
icon:
_radioValue
!=
'Correct'
?
const
Icon
(
Icons
.
edit
,
color:
AppColors
.
black40
,
)
:
const
Icon
(
Icons
.
message
,
color:
AppColors
.
black40
,
),
icon:
_radioValue
!=
FieldValue
.
correct
?
const
Icon
(
Icons
.
edit
,
color:
AppColors
.
black40
,
)
:
const
Icon
(
Icons
.
message
,
color:
AppColors
.
black40
,
),
),
)
],
)),
_radioValue
!=
'Correct'
&&
_summaryText
!=
''
_radioValue
!=
FieldValue
.
correct
&&
_summaryText
!=
''
?
Container
(
margin:
const
EdgeInsets
.
only
(
top:
10
),
padding:
const
EdgeInsets
.
fromLTRB
(
...
...
@@ -304,7 +319,8 @@ class _ApplicationFieldState extends State<ApplicationField> {
),
)
:
const
Center
(),
_radioValue
!=
'Correct'
&&
_inspectionValue
!=
''
_radioValue
!=
FieldValue
.
correct
&&
_inspectionValue
!=
''
?
Container
(
width:
MediaQuery
.
of
(
context
)
.
size
.
width
,
padding:
const
EdgeInsets
.
only
(
top:
20
),
...
...
@@ -318,7 +334,8 @@ class _ApplicationFieldState extends State<ApplicationField> {
),
))
:
const
Center
(),
_radioValue
!=
'Correct'
&&
_inspectionValue
!=
''
_radioValue
!=
FieldValue
.
correct
&&
_inspectionValue
!=
''
?
Container
(
margin:
const
EdgeInsets
.
only
(
top:
10
),
padding:
const
EdgeInsets
.
fromLTRB
(
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Topics
Snippets