From e76c4a66434578a0d62658c3953bc40e3a89c175 Mon Sep 17 00:00:00 2001 From: shoaib-mohmad <shoaib.mohmad@tarento.com> Date: Tue, 29 Mar 2022 17:45:30 +0530 Subject: [PATCH] Completed attachment support in offline mode. --- lib/constants/app_constants.dart | 1 + lib/database/offline_model.dart | 30 ++++ lib/l10n/app_en.arb | 5 +- lib/models/application_model.dart | 12 +- lib/pages/application_details_page.dart | 145 +++++++++++------ lib/pages/attachment_viewer.dart | 52 ++++++ lib/pages/home_page.dart | 1 + lib/pages/inspection_summary.dart | 1 - lib/pages/login_email_page.dart | 16 +- lib/repositories/application_repository.dart | 35 ++-- lib/repositories/form_repository.dart | 1 + lib/services/application_service.dart | 4 +- lib/widgets/application_card.dart | 32 ++-- ...assistant_inspector_application_field.dart | 152 +++++++++++++++--- .../lead_inspector_application_field.dart | 128 ++++++++++----- 15 files changed, 467 insertions(+), 148 deletions(-) create mode 100644 lib/pages/attachment_viewer.dart diff --git a/lib/constants/app_constants.dart b/lib/constants/app_constants.dart index 743a3a8..34c32dc 100644 --- a/lib/constants/app_constants.dart +++ b/lib/constants/app_constants.dart @@ -41,6 +41,7 @@ class AppDatabase { static const String formsTable = 'forms'; static const String inspectionTable = 'inspections'; static const String loginPinsTable = 'login_pins'; + static const String attachmentsTable = 'attachments'; } class Storage { diff --git a/lib/database/offline_model.dart b/lib/database/offline_model.dart index 666f3da..9c73202 100644 --- a/lib/database/offline_model.dart +++ b/lib/database/offline_model.dart @@ -12,6 +12,7 @@ class OfflineModel { const String formsTable = AppDatabase.formsTable; const String inspectionTable = AppDatabase.inspectionTable; const String loginPinsTable = AppDatabase.loginPinsTable; + const String attachmentsTable = AppDatabase.attachmentsTable; await db.execute('''CREATE TABLE $applicationsTable ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -33,6 +34,11 @@ class OfflineModel { username VARCHAR(64), pin VARCHAR(4) )'''); + await db.execute('''CREATE TABLE $attachmentsTable ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + application_id VARCHAR(64), + attachment VARCHAR(512) + )'''); }, version: 1); } @@ -132,4 +138,28 @@ class OfflineModel { whereArgs: whereArgs); return rows.isNotEmpty ? rows[0] : {}; } + + static Future<void> saveAttachment(Map<String, Object> data) async { + final db = await OfflineModel.database(); + db.insert( + AppDatabase.attachmentsTable, + data, + conflictAlgorithm: ConflictAlgorithm.replace, + ); + } + + static Future<List<Map>> getAttachments(String applicationId) async { + final db = await OfflineModel.database(); + List<dynamic> whereArgs = [applicationId]; + List<Map> rows = await db.query(AppDatabase.attachmentsTable, + where: 'application_id = ?', orderBy: 'id DESC', whereArgs: whereArgs); + return rows; + } + + static Future<void> deleteAttachments(String applicationId) async { + Database db = await OfflineModel.database(); + List<dynamic> whereArgs = [applicationId]; + await db.delete(AppDatabase.attachmentsTable, + where: 'application_id = ?', whereArgs: whereArgs); + } } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 4904b68..7e68b32 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -32,7 +32,7 @@ "pastApplications": "Past applications", "viewPastApplications": "View past applications", "next": "Next", - "previous": "previous", + "previous": "Previous", "inspectionCompleted": "Inspection completed", "leadInspectorCompleted": "Lead inspector completed", "completed": "Completed", @@ -66,5 +66,6 @@ "fileViewer": "File viewer", "preview": "Preview", "remove": "Remove", - "attachment": "Attachment" + "attachment": "Attachment", + "version": "Version" } \ No newline at end of file diff --git a/lib/models/application_model.dart b/lib/models/application_model.dart index c1f8cca..305ca68 100644 --- a/lib/models/application_model.dart +++ b/lib/models/application_model.dart @@ -39,14 +39,18 @@ class Application { email: json['email'] ?? '', status: json['status'], dataObject: json['dataObject'], - inspectors: json['inspection']['assignedTo'] ?? [], - leadInspector: json['inspection']['leadInspector'] ?? [], + inspectors: + json['inspection'] != null ? json['inspection']['assignedTo'] : [], + leadInspector: + json['inspection'] != null ? json['inspection']['leadInspector'] : [], inspectorDataObject: json['inspectorDataObject'] != null ? json['inspectorDataObject']['dataObject'] : {}, inspectorSummaryDataObject: json['inspectorSummaryDataObject'] ?? {}, - inspectionStatus: json['inspection']['status'] ?? '', - scheduledDate: json['inspection']['scheduledDate'] ?? '', + inspectionStatus: + json['inspection'] != null ? json['inspection']['status'] : '', + scheduledDate: + json['inspection'] != null ? json['inspection']['scheduledDate'] : '', createdDate: json['createdDate'], createdBy: json['createdBy'], ); diff --git a/lib/pages/application_details_page.dart b/lib/pages/application_details_page.dart index e240dc6..431340a 100644 --- a/lib/pages/application_details_page.dart +++ b/lib/pages/application_details_page.dart @@ -583,52 +583,71 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> CrossAxisAlignment .start, children: [ - Padding( - padding: - const EdgeInsets - .only(top: 5), - child: Text( - AppLocalizations.of( - context)! - .inspectionSummary, - style: - GoogleFonts.lato( - color: AppColors - .black87, - fontSize: 14.0, - letterSpacing: 0.25, - fontWeight: - FontWeight.w700, - ), - ), - ), - Container( - margin: const EdgeInsets - .only(top: 10), - padding: - const EdgeInsets - .fromLTRB( - 15, 10, 15, 10), - width: double.infinity, - decoration: - BoxDecoration( - border: Border.all( - color: AppColors - .black16), - ), - child: Text( - _inspectionSummary, - style: - GoogleFonts.lato( - color: AppColors - .black87, - fontSize: 14.0, - letterSpacing: 0.25, - fontWeight: - FontWeight.w400, - ), - ), - ), + _inspectionSummary != '' + ? Padding( + padding: + const EdgeInsets + .only( + top: 5), + child: Text( + AppLocalizations.of( + context)! + .inspectionSummary, + style: + GoogleFonts + .lato( + color: AppColors + .black87, + fontSize: + 14.0, + letterSpacing: + 0.25, + fontWeight: + FontWeight + .w700, + ), + ), + ) + : const Center(), + _inspectionSummary != '' + ? Container( + margin: + const EdgeInsets + .only( + top: 10), + padding: + const EdgeInsets + .fromLTRB( + 15, + 10, + 15, + 10), + width: double + .infinity, + decoration: + BoxDecoration( + border: Border.all( + color: AppColors + .black16), + ), + child: Text( + _inspectionSummary, + style: + GoogleFonts + .lato( + color: AppColors + .black87, + fontSize: + 14.0, + letterSpacing: + 0.25, + fontWeight: + FontWeight + .w400, + ), + ), + ) + : const Center(), _leadInspectorId != 0 ? Container( margin: const EdgeInsets @@ -717,6 +736,9 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> itemBuilder: (context, i) { return _isleadInspector ? LeadInspectorApplicationField( + applicationId: widget + .application + .applicationId, fieldName: field.keys.elementAt(i), fieldData: field[field.keys @@ -739,14 +761,25 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> parentAction: updateField, ) : widget.application.status == - InspectionStatus - .inspectionCompleted + InspectionStatus + .inspectionCompleted || + widget.application + .status == + InspectionStatus + .approved || + widget.application + .inspectionStatus == + InspectionStatus + .leadInspectorCompleted ? AssistantInspectorApplicationField( fieldName: field.keys .elementAt(i), fieldData: field[field .keys .elementAt(i)], + fieldType: _fieldTypes[ + field.keys + .elementAt(i)], leadInspectorData: _leadInspectorFields[ _leadInspectorFields @@ -785,7 +818,9 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> ), ), child: Column(children: [ - !_isleadInspector + !_isleadInspector && + widget.application.inspectionStatus == + InspectionStatus.leadInspectorCompleted ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -978,7 +1013,8 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> ) ], )) - : (widget.application.status != + : (_isleadInspector && + widget.application.status != InspectionStatus .inspectionCompleted && widget.application.inspectionStatus != @@ -986,9 +1022,12 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> .leadInspectorCompleted && widget.application.status != InspectionStatus.approved) || - (widget.application.status == - InspectionStatus.sentForInspection && - !_isleadInspector) + (widget.application.inspectionStatus == + InspectionStatus + .leadInspectorCompleted && + !_isleadInspector && + widget.application.status != + InspectionStatus.inspectionCompleted) ? TextButton( onPressed: () { _submitInspection(); diff --git a/lib/pages/attachment_viewer.dart b/lib/pages/attachment_viewer.dart new file mode 100644 index 0000000..2e995dd --- /dev/null +++ b/lib/pages/attachment_viewer.dart @@ -0,0 +1,52 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:smf_mobile/constants/color_constants.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:webview_flutter/webview_flutter.dart'; +import 'dart:async'; + +class AttachmentViewer extends StatefulWidget { + final String fileUrl; + const AttachmentViewer({Key? key, required this.fileUrl}) : super(key: key); + @override + _AttachmentViewerState createState() => _AttachmentViewerState(); +} + +class _AttachmentViewerState extends State<AttachmentViewer> { + final Completer<WebViewController> _controller = + Completer<WebViewController>(); + late String _fileUrl; + bool _isLoading = true; + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + titleSpacing: 10, + elevation: 0, + backgroundColor: Colors.white, + leading: const BackButton(color: AppColors.black60), + title: Text( + AppLocalizations.of(context)!.fileViewer, + style: GoogleFonts.lato( + color: AppColors.black87, + fontSize: 16.0, + letterSpacing: 0.12, + fontWeight: FontWeight.w600, + ), + ), + // centerTitle: true, + ), + // Tab controller + body: Container( + color: AppColors.scaffoldBackground, + height: MediaQuery.of(context).size.height, + child: Image.file(File(widget.fileUrl)))); + } +} diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 971ee17..05c79cc 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -112,6 +112,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver { } Future<dynamic> _syncApplications() async { + // print('_syncApplications...'); var synced = await Provider.of<ApplicationRespository>(context, listen: false) .submitBulkInspection(); diff --git a/lib/pages/inspection_summary.dart b/lib/pages/inspection_summary.dart index 2343f02..3ef74b9 100644 --- a/lib/pages/inspection_summary.dart +++ b/lib/pages/inspection_summary.dart @@ -146,7 +146,6 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> { final responseCode = await Provider.of<ApplicationRespository>(context, listen: false) .submitInspection(isInternetConnected, data); - // print(responseCode.toString()); if (responseCode == 200) { Navigator.of(context).pushReplacement(MaterialPageRoute( builder: (context) => const InspectionCompletedPage())); diff --git a/lib/pages/login_email_page.dart b/lib/pages/login_email_page.dart index 4970319..c1271b2 100644 --- a/lib/pages/login_email_page.dart +++ b/lib/pages/login_email_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; +import 'package:smf_mobile/constants/app_constants.dart'; import 'package:smf_mobile/constants/app_urls.dart'; import 'package:smf_mobile/constants/color_constants.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -10,7 +11,7 @@ import 'package:smf_mobile/pages/login_pin_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:unique_identifier/unique_identifier.dart'; +// import 'package:unique_identifier/unique_identifier.dart'; import 'dart:async'; import 'package:email_validator/email_validator.dart'; @@ -256,6 +257,19 @@ class _LoginEmailPageState extends State<LoginEmailPage> { ), ]), ), + Padding( + padding: const EdgeInsets.only(top: 10, bottom: 20), + child: Text( + AppLocalizations.of(context)!.version + ' ' + appVersion, + style: GoogleFonts.lato( + color: AppColors.black87, + fontSize: 12, + letterSpacing: + 0.25 /*percentages not used in flutter. defaulting to zero*/, + fontWeight: FontWeight.w700, + height: 1.4), + ), + ), const Spacer(), Column( children: [ diff --git a/lib/repositories/application_repository.dart b/lib/repositories/application_repository.dart index 16914e3..e157ee3 100644 --- a/lib/repositories/application_repository.dart +++ b/lib/repositories/application_repository.dart @@ -54,16 +54,15 @@ class ApplicationRespository with ChangeNotifier { if (!internetConnected) { Map<String, Object> applicationData = { 'inspector_type': Inspector.leadInspector, - 'inspection_data': data + 'inspection_data': json.encode(data) }; await OfflineModel.saveInspection(applicationData); // Updating application status in the database String username = await Helper.getUser(Storage.username); - var rawData = await OfflineModel.getForms(username); + var rawData = await OfflineModel.getApplications(username); Map applicationFieldData = json.decode(rawData['application_data']); List applications = applicationFieldData['responseData']; - for (int i = 0; i < applications.length; i++) { if (applications[i]['applicationId'] == data['applicationId']) { applications[i]['inspection']['status'] = @@ -71,6 +70,7 @@ class ApplicationRespository with ChangeNotifier { applications[i]['inspectorDataObject'] = data; } } + applicationFieldData['responseData'] = applications; _saveApplications(username, jsonEncode(applicationFieldData)); } else { @@ -97,13 +97,24 @@ class ApplicationRespository with ChangeNotifier { List<Map> consents = []; Map data1 = {}, data2 = {}; bool response = false; + List<Map> attachments = []; try { List<Map> rawInspections = await OfflineModel.getInspections(); for (var inspection in rawInspections) { + Map inspectionData = jsonDecode(inspection['inspection_data']); + attachments = + await OfflineModel.getAttachments(inspectionData['applicationId']); + for (var attachment in attachments) { + String temp = json.encode(inspectionData); + String fileUrl = + await ApplicationService.uploadImage(attachment['attachment']); + temp = temp.replaceAll(attachment['attachment'], fileUrl); + inspectionData = json.decode(temp); + } if (inspection['inspector_type'] == Inspector.leadInspector) { - inspections.add(jsonDecode(inspection['inspection_data'])); + inspections.add(inspectionData); } else { - consents.add(jsonDecode(inspection['inspection_data'])); + consents.add(inspectionData); } } if (inspections.isNotEmpty) { @@ -116,14 +127,18 @@ class ApplicationRespository with ChangeNotifier { data2 = json.decode(request2.body); } } catch (_) { - return _; + return false; + } + if (data1['statusInfo']['statusCode'] != 200 || + data2['statusInfo']['statusCode'] != 200) { + _errorMessage = _data['statusInfo']['errorMessage']; } - // if (data1['statusInfo']['statusCode'] != 200 || - // data2['statusInfo']['statusCode'] != 200) { - // _errorMessage = _data['statusInfo']['errorMessage']; - // } if ((inspections.isNotEmpty && data1['statusInfo']['statusCode']) || (consents.isNotEmpty && data2['statusInfo']['statusCode'])) { + for (var attachment in attachments) { + await OfflineModel.deleteAttachments(attachment['attachment']); + } + await OfflineModel.deleteInspections(); response = true; } return response; diff --git a/lib/repositories/form_repository.dart b/lib/repositories/form_repository.dart index bcd60d2..2102a41 100644 --- a/lib/repositories/form_repository.dart +++ b/lib/repositories/form_repository.dart @@ -69,6 +69,7 @@ class FormRespository with ChangeNotifier { if (formDetails['id'] == null) { return; } + // print(formDetails); } catch (_) { return _; } diff --git a/lib/services/application_service.dart b/lib/services/application_service.dart index ae76d92..8690c02 100644 --- a/lib/services/application_service.dart +++ b/lib/services/application_service.dart @@ -1,12 +1,12 @@ import 'dart:convert'; import 'dart:io'; import 'package:dio/dio.dart'; -import 'package:dio/adapter.dart'; +// import 'package:dio/adapter.dart'; import 'package:http/http.dart' as http; import 'package:smf_mobile/constants/api_endpoints.dart'; import 'package:smf_mobile/constants/app_constants.dart'; import 'package:smf_mobile/services/base_service.dart'; -import 'dart:developer' as developer; +// import 'dart:developer' as developer; class ApplicationService extends BaseService { ApplicationService(HttpClient client) : super(client); diff --git a/lib/widgets/application_card.dart b/lib/widgets/application_card.dart index 31b865f..739c38c 100644 --- a/lib/widgets/application_card.dart +++ b/lib/widgets/application_card.dart @@ -24,29 +24,31 @@ class _ApplicationCardState extends State<ApplicationCard> { super.initState(); } - String _getApplicationStatus(String inspetionStatus, String actualStatus) { - String status = ''; - if (actualStatus == InspectionStatus.inspectionCompleted) { - status = InspectionStatus.inspectionCompleted; - } - if (inspetionStatus == InspectionStatus.leadInspectorCompleted) { - status = InspectionStatus.leadInspectorCompleted; - } else { - status = actualStatus; - } - return status; - } + // String _getApplicationStatus(String inspetionStatus, String actualStatus) { + // String status = ''; + // if (actualStatus == InspectionStatus.inspectionCompleted) { + // status = InspectionStatus.inspectionCompleted; + // } + // if (inspetionStatus == InspectionStatus.leadInspectorCompleted) { + // status = InspectionStatus.leadInspectorCompleted; + // } else { + // status = actualStatus; + // } + // return status; + // } @override Widget build(BuildContext context) { return InkWell( - onTap: () => Navigator.push( + onTap: () { + // print(widget.application.inspectionStatus); + Navigator.push( context, MaterialPageRoute( builder: (context) => ApplicationDetailsPage( application: widget.application, - )), - ), + ))); + }, child: Container( width: double.infinity, margin: const EdgeInsets.only(bottom: 10), diff --git a/lib/widgets/assistant_inspector_application_field.dart b/lib/widgets/assistant_inspector_application_field.dart index 473781f..6380ec1 100644 --- a/lib/widgets/assistant_inspector_application_field.dart +++ b/lib/widgets/assistant_inspector_application_field.dart @@ -3,17 +3,20 @@ 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:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:smf_mobile/pages/file_viewer.dart'; import 'package:smf_mobile/util/helper.dart'; class AssistantInspectorApplicationField extends StatefulWidget { final String fieldName; final Map fieldData; + final String fieldType; final Map leadInspectorData; final ValueChanged<Map> parentAction; const AssistantInspectorApplicationField({ Key? key, required this.fieldName, required this.fieldData, + required this.fieldType, required this.leadInspectorData, required this.parentAction, }) : super(key: key); @@ -29,13 +32,27 @@ class _AssistantInspectorApplicationFieldState String _inspectionComment = ''; String _attachment = ''; String _noteText = ''; + final List<String> _imageExtensions = [ + 'apng', + 'png', + 'jpg', + 'jpeg', + 'avif', + 'gif', + 'svg' + ]; @override void initState() { super.initState(); + // print(widget.leadInspectorData['value']); + + _radioValue = widget.leadInspectorData['value'] == null || + widget.leadInspectorData['value'] == '' + ? FieldValue.correct + : widget.leadInspectorData['value']; try { _inspectionComment = widget.leadInspectorData['comments']; - _radioValue = widget.leadInspectorData['value']; _inspectionValue = widget.leadInspectorData['inspectionValue']; _attachment = widget.leadInspectorData['attachment']; } catch (_) { @@ -62,6 +79,31 @@ class _AssistantInspectorApplicationFieldState widget.parentAction(data); } + void _viewFile(String fileUrl) { + String extension = fileUrl.split('.').last.toLowerCase(); + if (_imageExtensions.contains(extension) || extension == FieldType.pdf) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FileViewer( + fileType: extension == FieldType.pdf + ? FieldType.pdf + : FieldType.image, + fileUrl: fileUrl, + )), + ); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FileViewer( + fileType: '', + fileUrl: fileUrl, + )), + ); + } + } + @override Widget build(BuildContext context) { return SingleChildScrollView( @@ -105,22 +147,44 @@ class _AssistantInspectorApplicationFieldState ), ), Container( - margin: const EdgeInsets.only(top: 10), - padding: const EdgeInsets.fromLTRB(15, 10, 15, 10), - width: double.infinity, - decoration: BoxDecoration( - border: Border.all(color: AppColors.black16), - ), - child: Text( - widget.fieldData.keys.elementAt(0), - style: GoogleFonts.lato( - color: AppColors.black87, - fontSize: 14.0, - letterSpacing: 0.25, - fontWeight: FontWeight.w400, + margin: const EdgeInsets.only(top: 10), + padding: const EdgeInsets.fromLTRB(15, 10, 15, 10), + width: double.infinity, + decoration: BoxDecoration( + border: Border.all(color: AppColors.black16), ), - ), - ) + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.fieldData.keys.elementAt(0), + style: GoogleFonts.lato( + color: AppColors.black87, + fontSize: 14.0, + letterSpacing: 0.25, + fontWeight: FontWeight.w400, + ), + ), + widget.fieldType == FieldType.file + ? InkWell( + onTap: () => _viewFile( + widget.fieldData.keys.elementAt(0)), + child: Padding( + padding: + const EdgeInsets.only(top: 10), + child: Text( + AppLocalizations.of(context)! + .preview, + style: GoogleFonts.lato( + color: AppColors.primaryBlue, + fontSize: 14.0, + letterSpacing: 0.25, + fontWeight: FontWeight.w700, + ), + ))) + : const Center(), + ], + )) ], ), ), @@ -298,8 +362,60 @@ class _AssistantInspectorApplicationFieldState color: AppColors.black08, ), ), - child: - Image.network(_attachment), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + _attachment, + style: GoogleFonts.lato( + color: + AppColors.black87, + fontSize: 14.0, + letterSpacing: 0.25, + fontWeight: + FontWeight.w400, + ), + ), + Row( + children: [ + InkWell( + onTap: () => Navigator + .push( + context, + MaterialPageRoute( + builder: (context) => + FileViewer( + fileType: FieldType.image, + fileUrl: _attachment, + ))), + child: Padding( + padding: const EdgeInsets + .only( + top: 10), + child: Text( + AppLocalizations.of( + context)! + .preview, + style: + GoogleFonts + .lato( + color: AppColors + .primaryBlue, + fontSize: + 14.0, + letterSpacing: + 0.25, + fontWeight: + FontWeight + .w700, + ), + ))), + const Spacer(), + ], + ), + ]), ), ) : const Center(), diff --git a/lib/widgets/lead_inspector_application_field.dart b/lib/widgets/lead_inspector_application_field.dart index ba6b791..e75074d 100644 --- a/lib/widgets/lead_inspector_application_field.dart +++ b/lib/widgets/lead_inspector_application_field.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; 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/database/offline_model.dart'; +import 'package:smf_mobile/pages/attachment_viewer.dart'; import 'package:smf_mobile/pages/file_viewer.dart'; import 'package:smf_mobile/services/application_service.dart'; import 'package:smf_mobile/util/helper.dart'; @@ -12,6 +14,7 @@ import 'package:image_picker/image_picker.dart'; import 'package:image_cropper/image_cropper.dart'; class LeadInspectorApplicationField extends StatefulWidget { + final String applicationId; final String fieldName; final Map fieldData; final String fieldType; @@ -20,6 +23,7 @@ class LeadInspectorApplicationField extends StatefulWidget { final ValueChanged<Map> parentAction; const LeadInspectorApplicationField({ Key? key, + required this.applicationId, required this.fieldName, required this.fieldData, required this.fieldType, @@ -249,7 +253,22 @@ class _LeadInspectorApplicationFieldState statusBarColor: Colors.grey.shade900, backgroundColor: Colors.white, )); - String fileUrl = await ApplicationService.uploadImage(cropped!.path); + + String fileUrl = ''; + bool isInternetConnected = await Helper.isInternetConnected(); + if (isInternetConnected) { + fileUrl = await ApplicationService.uploadImage(cropped!.path); + } else { + fileUrl = cropped!.path; + Map<String, Object> data = { + 'application_id': widget.applicationId, + 'attachment': fileUrl + }; + await OfflineModel.saveAttachment(data); + // List<Map> attachments = + // await OfflineModel.getAttachments(widget.applicationId); + // print(attachments); + } _triggerAttachmentUpdate(fileUrl); } catch (e) { // print(e); @@ -259,14 +278,16 @@ class _LeadInspectorApplicationFieldState } Future<void> _deleteAttachment(String attachment) async { - List data = [attachment]; - final bool fileDeleted = await ApplicationService.deleteImage(data); - if (fileDeleted) { - Helper.toastMessage('Attachment removed'); - setState(() { - _attachment = ''; - }); + bool isInternetConnected = await Helper.isInternetConnected(); + if (isInternetConnected) { + List data = [attachment]; + await ApplicationService.deleteImage(data); } + + Helper.toastMessage('Attachment removed'); + setState(() { + _attachment = ''; + }); } void _viewFile(String fileUrl) { @@ -691,18 +712,34 @@ class _LeadInspectorApplicationFieldState Row( children: [ InkWell( - onTap: () => Navigator.push( - context, - MaterialPageRoute( - builder: - (context) => - FileViewer( - fileType: - FieldType - .image, - fileUrl: - _attachment, - ))), + onTap: () async { + bool isInternetConnected = + await Helper + .isInternetConnected(); + if (isInternetConnected) { + Navigator.push( + context, + MaterialPageRoute( + builder: + (context) => + FileViewer( + fileType: + FieldType.image, + fileUrl: + _attachment, + ))); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: + (context) => + AttachmentViewer( + fileUrl: + _attachment, + ))); + } + }, child: Padding( padding: const EdgeInsets @@ -722,28 +759,35 @@ class _LeadInspectorApplicationFieldState ), ))), const Spacer(), - InkWell( - onTap: () => - _deleteAttachment( - _attachment), - child: Padding( - padding: - const EdgeInsets - .only(top: 10), - child: Text( - AppLocalizations.of( - context)! - .remove, - style: - GoogleFonts.lato( - color: AppColors - .sentForIns, - fontSize: 14.0, - letterSpacing: 0.25, - fontWeight: - FontWeight.w700, - ), - ))), + widget.applicationStatus != + InspectionStatus + .inspectionCompleted + ? InkWell( + onTap: () => + _deleteAttachment( + _attachment), + child: Padding( + padding: + const EdgeInsets + .only( + top: 10), + child: Text( + AppLocalizations.of( + context)! + .remove, + style: GoogleFonts + .lato( + color: AppColors + .sentForIns, + fontSize: 14.0, + letterSpacing: + 0.25, + fontWeight: + FontWeight + .w700, + ), + ))) + : const Center(), ], ), ])) -- GitLab