diff --git a/assets/images/mic.svg b/assets/images/mic.svg
new file mode 100644
index 00000000..33c6ee78
--- /dev/null
+++ b/assets/images/mic.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/images/warning.svg b/assets/images/warning.svg
new file mode 100644
index 00000000..98708612
--- /dev/null
+++ b/assets/images/warning.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/lottie/record.json b/assets/lottie/record.json
new file mode 100644
index 00000000..5dbe123c
--- /dev/null
+++ b/assets/lottie/record.json
@@ -0,0 +1 @@
+{"v":"5.7.8","fr":29.9700012207031,"ip":0,"op":41.0000016699642,"w":160,"h":64,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"REC Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[105.58,32.746,0],"ix":2,"l":2},"a":{"a":0,"k":[-19.17,-6.3,0],"ix":1,"l":2},"s":{"a":0,"k":[251,251,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-0.378,0.583],[0,0.873],[0.82,0.674],[1.512,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0.768,-0.346],[0.378,-0.583],[0,-1.23],[-0.82,-0.674],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-26.01,0],[-23.18,0],[-23.18,-0.123],[-25.949,-5.353],[-24.231,-6.746],[-23.664,-8.93],[-24.894,-11.786],[-28.392,-12.797],[-33.147,-12.797],[-33.147,0],[-30.51,0],[-30.51,-4.685],[-28.41,-4.685]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.343,-0.346],[0,-0.603],[0.363,-0.337],[0.662,0],[0,0]],"o":[[0,0],[0.709,0],[0.343,0.346],[0,0.592],[-0.363,0.337],[0,0],[0,0]],"v":[[-30.51,-10.661],[-28.392,-10.661],[-26.815,-10.143],[-26.3,-8.719],[-26.845,-7.326],[-28.383,-6.82],[-30.51,-6.82]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.294117647059,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"R","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-13.511,-7.611],[-18.573,-7.611],[-18.573,-10.661],[-12.649,-10.661],[-12.649,-12.797],[-21.21,-12.797],[-21.21,0],[-12.632,0],[-12.632,-2.118],[-18.573,-2.118],[-18.573,-5.546],[-13.511,-5.546]],"c":true},"ix":2},"nm":"E","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.294117647059,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"E","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.401,-0.372],[0.814,0],[0.419,0.639],[0,1.383],[0,0],[-0.437,0.63],[-0.879,0],[-0.396,-0.372],[-0.065,-0.826],[0,0],[0.902,0.791],[1.477,0],[0.806,-0.501],[0.434,-0.937],[0,-1.23],[0,0],[-0.94,-1.104],[-1.641,0],[-0.917,0.791],[-0.1,1.377]],"o":[[-0.059,0.779],[-0.401,0.372],[-0.902,0],[-0.419,-0.639],[0,0],[0.012,-1.324],[0.436,-0.63],[0.809,0],[0.396,0.372],[0,0],[-0.141,-1.43],[-0.902,-0.791],[-1.066,0],[-0.806,0.501],[-0.434,0.938],[0,0],[0,1.928],[0.94,1.105],[1.5,0],[0.917,-0.791],[0,0]],"v":[[-3.226,-4.263],[-3.916,-2.536],[-5.739,-1.978],[-7.721,-2.936],[-8.35,-5.968],[-8.35,-6.935],[-7.677,-9.866],[-5.704,-10.811],[-3.898,-10.252],[-3.208,-8.455],[-0.571,-8.455],[-2.136,-11.786],[-5.704,-12.973],[-8.512,-12.221],[-10.371,-10.063],[-11.021,-6.812],[-11.021,-6.029],[-9.611,-1.481],[-5.739,0.176],[-2.114,-1.011],[-0.589,-4.263]],"c":true},"ix":2},"nm":"C","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.294117647059,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"C","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":41.0000016699642,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[31,32,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[127,127,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":10,"s":[147,147,100]},{"t":20.0000008146167,"s":[127,127,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[26.25,26.25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.294117647059,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.375,0.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":41.0000016699642,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[100]},{"t":40.0000016292334,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[31,32,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[127,127,100]},{"t":40.0000016292334,"s":[250,250,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[26.25,26.25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.294117647059,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.375,0.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":41.0000016699642,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart
index c9160a1f..0bcbf913 100644
--- a/lib/controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart
+++ b/lib/controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart
@@ -8,6 +8,7 @@ import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
+@Deprecated("Use the one inside lib/providers folder")
class ServiceRequestPriorityProvider extends ChangeNotifier {
//reset provider data
void reset() {
diff --git a/lib/extensions/text_extensions.dart b/lib/extensions/text_extensions.dart
index 7a08a656..b89f6625 100644
--- a/lib/extensions/text_extensions.dart
+++ b/lib/extensions/text_extensions.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
+import 'package:lottie/lottie.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
@@ -144,4 +145,11 @@ extension FilesExtension on String {
BoxFit fit = BoxFit.contain,
}) =>
Image.asset("assets/images/$this.png", width: width?.toScreenWidth, height: height?.toScreenHeight, color: color, fit: fit);
+ LottieBuilder toLottieAsset({
+ int width,
+ int height,
+ BoxFit fit = BoxFit.contain,
+ bool repeat = true,
+ }) =>
+ Lottie.asset("assets/lottie/$this.json", width: width?.toScreenWidth, height: height?.toScreenHeight, fit: fit, repeat: repeat);
}
diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb
index e3e12807..1b6e7504 100644
--- a/lib/l10n/app_ar.arb
+++ b/lib/l10n/app_ar.arb
@@ -1,6 +1,6 @@
{
"serverErrorMessage": "الخدمة غير متاحة حاليا",
- "failedRequestMessage": "الفشل في إكمال الطلب",
+ "failedRequestMessage": "فشل إكمال الطلب",
"successfulRequestMessage": "تم إكمال الطلب بنجاح",
"requestLockMessage": "انتظر حتى إكمال الطلب",
"cancel": "إلغاء",
@@ -252,5 +252,11 @@
"serialNumber" : "الرقم التسلسلي",
"device" : "الجهاز",
"pickAsset" : "إختر جهاز",
- "firstAction" : "First Action"
+ "firstAction" : "First Action",
+ "priority" : "الأولوية",
+ "equipmentStatus" : "حالة المعدات",
+ "attachImage" : "إرفاق صورة",
+ "callComments" : "",
+ "comments" : "تعليقات",
+ "recordVoice" : "تسجيل صوت"
}
\ No newline at end of file
diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb
index ec5fbcf8..040c3b8c 100644
--- a/lib/l10n/app_en.arb
+++ b/lib/l10n/app_en.arb
@@ -254,5 +254,11 @@
"pickAsset" : "Pick Asset",
"firstAction" : "First Action",
"workOrder" : "Work Orders",
- "viewWorkOrder" : "View All Work Order"
+ "viewWorkOrder" : "View All Work Order",
+ "priority" : "Priority",
+ "equipmentStatus" : "Equipment Status",
+ "attachImage" : "Attach Image",
+ "callComments" : "Call Comments",
+ "comments": "Comments",
+ "recordVoice" : "Record Voice"
}
\ No newline at end of file
diff --git a/lib/main.dart b/lib/main.dart
index ddcac114..49c29e7a 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -3,10 +3,9 @@ import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
-import 'package:flutter_localizations/flutter_localizations.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:localization/localization.dart';
import 'package:provider/provider.dart';
-import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/asset_transfer_provider.dart';
import 'package:test_sa/controllers/providers/api/departments_provider.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
@@ -55,6 +54,8 @@ import 'package:test_sa/providers/gas_request_providers/cylinder_type_provider.d
import 'package:test_sa/providers/gas_request_providers/gas_types_provider.dart';
import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
+import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart';
+import 'package:test_sa/providers/service_request_providers/priority_provider.dart';
import 'package:test_sa/views/pages/device_transfer/request_device_transfer.dart';
import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart';
import 'package:test_sa/views/pages/sub_workorder/create_sub_workorder_page.dart';
@@ -78,8 +79,6 @@ import 'controllers/providers/api/user_provider.dart';
import 'controllers/providers/settings/setting_provider.dart';
import 'new_views/pages/new_gas_refill_request_page.dart';
-import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-
void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (Platform.isIOS) {
@@ -159,6 +158,8 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => ServiceReportMaintenanceSituationProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportUsersProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportAssistantsEmployeeProvider()),
+ ChangeNotifierProvider(create: (_) => PriorityProvider()),
+ ChangeNotifierProvider(create: (_) => EquipmentStatusProvider()),
],
child: GestureDetector(
onTap: () {
diff --git a/lib/models/service_request/service_request.dart b/lib/models/service_request/service_request.dart
index 5769d0c1..350185fb 100644
--- a/lib/models/service_request/service_request.dart
+++ b/lib/models/service_request/service_request.dart
@@ -1,4 +1,7 @@
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
+import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/fault_description.dart';
import 'package:test_sa/models/lookup.dart';
@@ -138,4 +141,18 @@ class ServiceRequest {
priority: Lookup.fromJson(parsedJson['priority']),
);
}
+
+ Future validateNewRequest(BuildContext context) async {
+ if (device == null) {
+ await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.device}");
+ return false;
+ } else if (priority == null) {
+ await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.priority}");
+ return false;
+ } else if (defectType == null) {
+ await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.equipmentStatus}");
+ return false;
+ }
+ return true;
+ }
}
diff --git a/lib/new_views/common_widgets/app_dashed_button.dart b/lib/new_views/common_widgets/app_dashed_button.dart
new file mode 100644
index 00000000..f6108cd6
--- /dev/null
+++ b/lib/new_views/common_widgets/app_dashed_button.dart
@@ -0,0 +1,33 @@
+import 'package:dotted_border/dotted_border.dart';
+import 'package:flutter/material.dart';
+import 'package:test_sa/extensions/context_extension.dart';
+import 'package:test_sa/extensions/int_extensions.dart';
+import 'package:test_sa/extensions/text_extensions.dart';
+import 'package:test_sa/extensions/widget_extensions.dart';
+
+import '../app_style/app_color.dart';
+
+class AppDashedButton extends StatelessWidget {
+ final String title;
+ final VoidCallback onPressed;
+
+ const AppDashedButton({@required this.title, @required this.onPressed, Key key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: double.infinity,
+ padding: EdgeInsets.symmetric(horizontal: 2.toScreenWidth),
+ decoration: BoxDecoration(color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(10)),
+ child: DottedBorder(
+ strokeWidth: 2,
+ padding: EdgeInsets.symmetric(vertical: 16.toScreenHeight, horizontal: 16.toScreenWidth),
+ color: context.isDark ? AppColor.primary40 : AppColor.primary60,
+ dashPattern: const [4, 3],
+ radius: const Radius.circular(10),
+ borderType: BorderType.RRect,
+ child: title.heading6(context).custom(color: context.isDark ? AppColor.primary40 : AppColor.primary60).center,
+ ),
+ ).onPress(onPressed);
+ }
+}
diff --git a/lib/providers/service_request_providers/equipment_status_provider.dart b/lib/providers/service_request_providers/equipment_status_provider.dart
new file mode 100644
index 00000000..71a5760f
--- /dev/null
+++ b/lib/providers/service_request_providers/equipment_status_provider.dart
@@ -0,0 +1,36 @@
+import 'dart:convert';
+
+import 'package:http/http.dart';
+import 'package:test_sa/providers/loading_list_notifier.dart';
+
+import '../../controllers/api_routes/api_manager.dart';
+import '../../controllers/api_routes/urls.dart';
+import '../../models/lookup.dart';
+
+class EquipmentStatusProvider extends LoadingListNotifier {
+ @override
+ Future getDate() async {
+ if (loading == true) return -2;
+ loading = true;
+ notifyListeners();
+ loading = true;
+ notifyListeners();
+ try {
+ Response response = await ApiManager.instance.get(URLs.equipmentStatus);
+ stateCode = response.statusCode;
+ if (response.statusCode >= 200 && response.statusCode < 300) {
+ // client's request was successfully received
+ List categoriesListJson = json.decode(response.body)["data"];
+ items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
+ }
+ loading = false;
+ notifyListeners();
+ return response.statusCode;
+ } catch (error) {
+ loading = false;
+ stateCode = -1;
+ notifyListeners();
+ return -1;
+ }
+ }
+}
diff --git a/lib/providers/service_request_providers/priority_provider.dart b/lib/providers/service_request_providers/priority_provider.dart
new file mode 100644
index 00000000..a1c4f10f
--- /dev/null
+++ b/lib/providers/service_request_providers/priority_provider.dart
@@ -0,0 +1,36 @@
+import 'dart:convert';
+
+import 'package:http/http.dart';
+import 'package:test_sa/providers/loading_list_notifier.dart';
+
+import '../../controllers/api_routes/api_manager.dart';
+import '../../controllers/api_routes/urls.dart';
+import '../../models/lookup.dart';
+
+class PriorityProvider extends LoadingListNotifier {
+ @override
+ Future getDate() async {
+ if (loading == true) return -2;
+ loading = true;
+ notifyListeners();
+ loading = true;
+ notifyListeners();
+ try {
+ Response response = await ApiManager.instance.get(URLs.getServiceReportPriority);
+ stateCode = response.statusCode;
+ if (response.statusCode >= 200 && response.statusCode < 300) {
+ // client's request was successfully received
+ List categoriesListJson = json.decode(response.body)["data"];
+ items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
+ }
+ loading = false;
+ notifyListeners();
+ return response.statusCode;
+ } catch (error) {
+ loading = false;
+ stateCode = -1;
+ notifyListeners();
+ return -1;
+ }
+ }
+}
diff --git a/lib/views/pages/user/requests/create_request.dart b/lib/views/pages/user/requests/create_request.dart
index 348f42bb..1429a4fa 100644
--- a/lib/views/pages/user/requests/create_request.dart
+++ b/lib/views/pages/user/requests/create_request.dart
@@ -1,43 +1,34 @@
import 'dart:convert';
import 'dart:io';
+import 'package:file_picker/file_picker.dart';
+import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
-import 'package:font_awesome_flutter/font_awesome_flutter.dart';
+import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
-import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
-import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
-import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
+import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/service_request/service_request.dart';
-import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
-import 'package:test_sa/views/widgets/app_text_form_field.dart';
-import 'package:test_sa/views/widgets/date_and_time/time_picker.dart';
import 'package:test_sa/views/widgets/equipment/pick_asset.dart';
-import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/sound/record_sound.dart';
-import 'package:test_sa/views/widgets/sound/sound_player.dart';
-import 'package:test_sa/views/widgets/speech_to_text/speech_to_text.dart';
-import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart';
-import 'package:test_sa/views/widgets/status/service_request/service_request_priority_mune.dart';
-import 'package:test_sa/views/widgets/status/service_request/service_request_through_mune.dart';
-import 'package:test_sa/views/widgets/status/service_request/service_request_types_mune.dart';
-import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
-import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_through_provider.dart';
-import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_type_provider.dart';
-import '../../../../models/device/device.dart';
-import '../../../../models/enums/translation_keys.dart';
+import '../../../../models/lookup.dart';
+import '../../../../new_views/app_style/app_color.dart';
+import '../../../../new_views/common_widgets/app_dashed_button.dart';
+import '../../../../new_views/common_widgets/app_lazy_loading.dart';
+import '../../../../new_views/common_widgets/app_text_form_field.dart';
import '../../../../new_views/common_widgets/default_app_bar.dart';
-import '../../../widgets/status/service_request/service_request_first_action.dart';
-import '../../../widgets/status/service_request/service_request_loan_availability.dart';
+import '../../../../new_views/common_widgets/single_item_drop_down_menu.dart';
+import '../../../../providers/service_request_providers/equipment_status_provider.dart';
+import '../../../../providers/service_request_providers/priority_provider.dart';
class CreateRequestPage extends StatefulWidget {
static const String id = "/create-request";
@@ -50,6 +41,8 @@ class CreateRequestPage extends StatefulWidget {
}
class CreateRequestPageState extends State {
+ TextEditingController _commentController;
+
double _height;
UserProvider _userProvider;
SettingProvider _settingProvider;
@@ -58,21 +51,17 @@ class CreateRequestPageState extends State {
final List _deviceImages = [];
bool _isLoading = false;
bool _showDatePicker = false;
- Device _asset;
final GlobalKey _formKey = GlobalKey();
final GlobalKey _scaffoldKey = GlobalKey();
- TextEditingController _maintenanceController, _commentController, _reviewCommentController;
DateTime _dateTime;
bool isFirstActionSubmitted = false;
@override
void initState() {
- _maintenanceController = TextEditingController();
_commentController = TextEditingController();
if (widget.serviceRequest != null) {
_serviceRequest = widget.serviceRequest;
- _asset = _serviceRequest.device;
_deviceImages.addAll(_serviceRequest.devicePhotos.map((e) => File(e)).toList());
_showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit";
if (_showDatePicker && _serviceRequest.visitDate != null) {
@@ -107,7 +96,6 @@ class CreateRequestPageState extends State {
@override
void dispose() {
- _maintenanceController.dispose();
_commentController.dispose();
super.dispose();
}
@@ -127,7 +115,7 @@ class CreateRequestPageState extends State {
return Scaffold(
key: _scaffoldKey,
- appBar: DefaultAppBar(title: context.translation.newServiceRequest),
+ appBar: DefaultAppBar(title: context.translation.newServiceRequest),
body: SafeArea(
child: LoadingManager(
isLoading: _isLoading,
@@ -143,235 +131,58 @@ class CreateRequestPageState extends State {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
PickAsset(
- device: _asset,
+ device: _serviceRequest.device,
onPickAsset: (asset) {
- _asset = asset;
+ _serviceRequest.device = asset;
setState(() {});
},
),
- const SizedBox(
- height: 8,
- ),
- const ASubTitle("Priority"),
- const SizedBox(
- height: 4,
- ),
- ServiceRequestPriorityMenu(
- initialValue: widget.serviceRequest?.priority,
- onSelect: (status) {
- _serviceRequest.priority = status;
+ 8.height,
+ SingleItemDropDownMenu(
+ context: context,
+ title: context.translation.priority,
+ initialValue: _serviceRequest?.priority,
+ onSelect: (value) {
+ _serviceRequest.priority = value;
},
- enabled: widget.serviceRequest == null ? true : false,
- ),
- const SizedBox(
- height: 8,
),
- const ASubTitle("Equipment Status"),
- const SizedBox(
- height: 4,
- ),
- ServiceRequestDefectTypesMenu(
- initialValue: _serviceRequest.defectType,
- onSelect: (status) {
- _serviceRequest.defectType = status;
+ 8.height,
+ SingleItemDropDownMenu(
+ context: context,
+ title: context.translation.equipmentStatus,
+ initialValue: _serviceRequest?.defectType,
+ onSelect: (value) {
+ _serviceRequest.defectType = value;
},
- enabled: widget.serviceRequest == null ? true : false,
),
- 12.height,
- const SizedBox(
- height: 8,
+ 8.height,
+ AppDashedButton(title: _serviceRequest.devicePhotos?.first?.split("/")?.last ?? context.translation.attachImage, onPressed: _attachImage),
+ 16.height,
+ Align(
+ alignment: AlignmentDirectional.centerStart,
+ child: context.translation.callComments.heading5(context),
),
- const ASubTitle("Type of Request"),
- const SizedBox(
- height: 4,
+ 8.height,
+ AppTextFormField(
+ controller: _commentController,
+ labelText: context.translation.comments,
+ suffixIcon: "warning".toSvgAsset(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, width: 24).paddingOnly(end: 16),
),
- ServiceRequestTypesMenu(
- initialValue: _serviceRequest.type,
- onSelect: (status) {
- _serviceRequest.type = status;
+ 8.height,
+ RecordSound(
+ onRecord: (audio) {
+ _serviceRequest.audio = audio;
},
- enabled: false,
- withDefaultItem: widget.serviceRequest == null,
- ),
- const SizedBox(
- height: 8,
- ),
- const ASubTitle("Through"),
- const SizedBox(
- height: 4,
- ),
- ServiceRequestedThroughMenu(
- initialValue: _serviceRequest.requestedThrough,
- enabled: false,
- ),
- if (widget.serviceRequest != null) 12.height,
- if (widget.serviceRequest != null) const ASubTitle("First Action"),
- const SizedBox(
- height: 4,
- ),
- if (widget.serviceRequest != null)
- ServiceRequestedFirstAction(
- initialValue: _serviceRequest.firstAction,
- enabled: !isFirstActionSubmitted,
- onSelect: (status) {
- _dateTime = null;
- _serviceRequest.firstAction = status;
- _showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit";
- _serviceRequestsProvider.notifyListeners();
- },
- ),
- if (_showDatePicker) 12.height,
- if (_showDatePicker)
- ADateTimePicker(
- date: _dateTime,
- enable: !isFirstActionSubmitted,
- from: DateTime.now(),
- onDateTimePicker: (date) {
- _dateTime = date;
- setState(() {});
- },
- ),
- if (widget.serviceRequest != null) 12.height,
- if (widget.serviceRequest != null) const ASubTitle("Loan Availability"),
- const SizedBox(
- height: 4,
- ),
- if (widget.serviceRequest != null)
- ServiceRequestedLoanAvailability(
- initialValue: _serviceRequest.loanAvailability,
- onSelect: (status) {
- _serviceRequest.loanAvailability = status;
- },
- ),
- 12.height,
- if (widget.serviceRequest != null) const ASubTitle("Comments"),
- const SizedBox(
- height: 4,
- ),
- if (widget.serviceRequest != null)
- ATextFormField(
- controller: _reviewCommentController,
- initialValue: _serviceRequest.reviewComment,
- hintText: context.translation.comment,
- style: Theme.of(context).textTheme.titleMedium,
- textInputType: TextInputType.multiline,
- onSaved: (value) {
- _serviceRequest.reviewComment = value;
- },
- enable: widget.serviceRequest != null ? false : true,
- ),
- 12.height,
- MultiFilesPicker(
- label: context.translation.deviceFiles,
- files: _deviceImages,
- enabled: widget.serviceRequest == null ? true : false,
- ),
- 12.height,
- SpeechToTextButton(
- controller: _maintenanceController,
enabled: widget.serviceRequest == null ? true : false,
),
- 12.height,
- ATextFormField(
- controller: _maintenanceController,
- initialValue: _serviceRequest.callComments,
- hintText: context.translation.maintenanceIssue,
- prefixIconData: FontAwesomeIcons.triangleExclamation,
- style: Theme.of(context).textTheme.titleLarge,
- textInputType: TextInputType.multiline,
- validator: (value) => widget.serviceRequest != null || Validator.hasValue(value) ? null : context.translation.maintenanceIssueRequired,
- onSaved: (value) {
- _serviceRequest.callComments = value;
- },
- enable: widget.serviceRequest == null ? true : false,
- ),
- 12.height,
- if (_serviceRequest.audio?.isNotEmpty == true)
- ASoundPlayer(
- audio: _serviceRequest.audio,
- )
- else
- RecordSound(
- onRecord: (audio) {
- _serviceRequest.audio = audio;
- },
- enabled: widget.serviceRequest == null ? true : false,
- ),
- 12.height,
- if (widget.serviceRequest != null)
- ATextFormField(
- controller: _commentController,
- initialValue: _serviceRequest.comments,
- hintText: context.translation.comment,
- style: Theme.of(context).textTheme.titleMedium,
- textInputType: TextInputType.multiline,
- onSaved: (value) {
- _serviceRequest.comments = value;
- },
- ),
+ 16.height,
],
),
).expanded,
AppFilledButton(
- onPressed: () async {
- if (!_formKey.currentState.validate()) return;
- if (_asset?.id == null) {
- Fluttertoast.showToast(msg: context.translation.pickDevice);
- return;
- }
- if (_serviceRequest.firstAction?.name == "Need a visit" && _dateTime == null) {
- Fluttertoast.showToast(msg: "first action is required");
- return;
- }
- if (widget.serviceRequest != null && (_serviceRequest?.engineerId == null || (_serviceRequest?.engineerId?.isEmpty ?? false))) {
- await Fluttertoast.showToast(msg: "No Assigned Employee");
- return;
- }
- _formKey.currentState.save();
- _serviceRequest.deviceId = _asset?.id;
- if (widget.serviceRequest == null) {
- _serviceRequest.type = Provider.of(context, listen: false).getDefaultItem();
- }
- _serviceRequest.requestedThrough = Provider.of(context, listen: false).getDefaultItem();
- _isLoading = true;
- setState(() {});
- _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList();
- if (_serviceRequest.audio != null) {
- if (_isLocalUrl(_serviceRequest.audio)) {
- final File file = File(_serviceRequest.audio);
- _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}";
- }
- }
- int status = 0;
- if (widget.serviceRequest == null) {
- status = await _serviceRequestsProvider.createRequest(
- user: _userProvider.user,
- host: _settingProvider.host,
- serviceRequest: _serviceRequest,
- );
- } else {
- status = await _serviceRequestsProvider.updateDate(
- user: _userProvider.user,
- host: _settingProvider.host,
- request: _serviceRequest,
- date: _dateTime,
- );
- }
- _isLoading = false;
- setState(() {});
- if (status >= 200 && status < 300) {
- Fluttertoast.showToast(
- msg: context.translation.successfulRequestMessage,
- );
- Navigator.of(context).pop();
- } else {
- String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: context.translation);
- ScaffoldMessenger.of(context).showSnackBar(SnackBar(
- content: Text(errorMessage),
- ));
- }
- },
- label: context.translation.submitRequest),
+ onPressed: _submit,
+ label: context.translation.submitRequest,
+ ),
],
),
).paddingOnly(start: 16, end: 16, bottom: 24, top: 16),
@@ -379,4 +190,81 @@ class CreateRequestPageState extends State {
),
);
}
+
+ _attachImage() async {
+ ImageSource source = await showDialog(
+ context: context,
+ builder: (dialogContext) => CupertinoAlertDialog(
+ actions: [
+ TextButton(
+ child: Text(context.translation.pickFromCamera),
+ onPressed: () {
+ Navigator.of(dialogContext).pop(ImageSource.camera);
+ },
+ ),
+ TextButton(
+ child: Text(context.translation.pickFromGallery),
+ onPressed: () {
+ Navigator.of(dialogContext).pop(ImageSource.gallery);
+ },
+ ),
+ TextButton(
+ child: Text(context.translation.pickFromFiles),
+ onPressed: () async {
+ await _fromFilePicker();
+ Navigator.pop(context);
+ },
+ ),
+ ],
+ ),
+ );
+ if (source == null) return;
+
+ final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 70, maxWidth: 800, maxHeight: 800);
+ if (pickedFile != null) {
+ _serviceRequest.devicePhotos ??= [];
+ _serviceRequest.devicePhotos?.clear();
+ _serviceRequest.devicePhotos?.add(pickedFile.path);
+ setState(() {});
+ }
+ }
+
+ _fromFilePicker() async {
+ FilePickerResult result = await FilePicker.platform.pickFiles(
+ type: FileType.custom,
+ allowedExtensions: ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xlsx', 'pptx'],
+ );
+ if (result?.files?.first != null) {
+ _serviceRequest.devicePhotos ??= [];
+ _serviceRequest.devicePhotos?.clear();
+ _serviceRequest.devicePhotos?.add(result?.files?.first?.path);
+ setState(() {});
+ }
+ }
+
+ Future _submit() async {
+ if (_formKey.currentState.validate() && await _serviceRequest.validateNewRequest(context)) {
+ _formKey.currentState.save();
+ _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList();
+ if (_serviceRequest.audio != null) {
+ if (_isLocalUrl(_serviceRequest.audio)) {
+ final File file = File(_serviceRequest.audio);
+ _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}";
+ }
+ }
+ showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
+ int status = await _serviceRequestsProvider.createRequest(
+ user: _userProvider.user,
+ host: _settingProvider.host,
+ serviceRequest: _serviceRequest,
+ );
+ Navigator.of(context);
+ if (status >= 200 && status < 300) {
+ Fluttertoast.showToast(msg: context.translation.successfulRequestMessage);
+ Navigator.pop(context);
+ } else {
+ Fluttertoast.showToast(msg: context.translation.failedRequestMessage);
+ }
+ }
+ }
}
diff --git a/lib/views/widgets/equipment/pick_asset.dart b/lib/views/widgets/equipment/pick_asset.dart
index 6221631a..06faaf8a 100644
--- a/lib/views/widgets/equipment/pick_asset.dart
+++ b/lib/views/widgets/equipment/pick_asset.dart
@@ -3,11 +3,10 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
-import 'package:test_sa/models/enums/translation_keys.dart';
-import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/equipment/single_device_picker.dart';
import '../../../models/device/device.dart';
+import '../../../new_views/app_style/app_color.dart';
class PickAsset extends StatelessWidget {
final Function(Device) onPickAsset;
@@ -19,22 +18,36 @@ class PickAsset extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
children: [
- AppTextFormField(
- enable: false,
- labelText: context.translation.device,
- initialValue: context.translation.site,
- suffixIcon: "qr".toSvgAsset(height: 24, fit: BoxFit.fitHeight).paddingOnly(end: 16),
- ).onPress(() async {
- Device device = await Navigator.of(context).pushNamed(SingleDevicePicker.id) as Device;
- onPickAsset(device);
- }),
- if (device != null) 8.height,
+ Container(
+ decoration: BoxDecoration(
+ color: Theme.of(context).cardColor,
+ borderRadius: BorderRadius.circular(10),
+ boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
+ ),
+ child: Row(
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ context.translation.device.tinyFont(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral50),
+ context.translation.pickAsset.bodyText(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral50),
+ ],
+ ).onPress(() async {
+ Device device = await Navigator.of(context).pushNamed(SingleDevicePicker.id) as Device;
+ onPickAsset(device);
+ }).expanded,
+ "qr".toSvgAsset(height: 24, fit: BoxFit.fitHeight).onPress(() {
+ /// TODO [Zaid] : open qr reader
+ }),
+ ],
+ ).paddingOnly(start: 16, end: 16, top: 8, bottom: 8),
+ ),
if (device != null)
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
- context.translation.myAssets.heading5(context),
+ device.modelDefinition?.assetName?.heading5(context),
8.height,
"${context.translation.assetNo}: ${device.assetNumber}".bodyText(context),
"${context.translation.manufacture}: ${device.modelDefinition?.manufacturerName}".bodyText(context),
@@ -45,7 +58,7 @@ class PickAsset extends StatelessWidget {
"${context.translation.site}: ${device.site?.custName}".bodyText(context),
],
).paddingAll(16),
- ),
+ ).paddingOnly(top: 8),
],
);
}
diff --git a/lib/views/widgets/sound/record_sound.dart b/lib/views/widgets/sound/record_sound.dart
index 3b6b75b6..3b116069 100644
--- a/lib/views/widgets/sound/record_sound.dart
+++ b/lib/views/widgets/sound/record_sound.dart
@@ -1,17 +1,20 @@
+import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
-import 'package:flutter_sound/flutter_sound.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
-import 'package:rive/rive.dart';
-import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
-import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
-import 'package:test_sa/views/widgets/sound/sound_player.dart';
import 'package:record_mp3/record_mp3.dart';
-import '../../app_style/sizing.dart';
+import 'package:rive/rive.dart';
+import 'package:test_sa/extensions/context_extension.dart';
+import 'package:test_sa/extensions/int_extensions.dart';
+import 'package:test_sa/extensions/text_extensions.dart';
+import 'package:test_sa/extensions/widget_extensions.dart';
+
+import '../../../new_views/app_style/app_color.dart';
+import '../../../new_views/common_widgets/app_text_form_field.dart';
class RecordSound extends StatefulWidget {
final Function(String) onRecord;
@@ -30,6 +33,8 @@ class _RecordSoundState extends State {
bool _recording = false;
String _record;
Artboard _rive;
+ Timer _timer;
+ TextEditingController _timeController;
@override
void setState(VoidCallback fn) {
@@ -39,7 +44,7 @@ class _RecordSoundState extends State {
@override
void initState() {
super.initState();
-
+ _timeController = TextEditingController();
_recorderIsOpened = true;
// RecordMp3.instance.start(recordFilePath, (type) {
// // record fail callback
@@ -70,6 +75,7 @@ class _RecordSoundState extends State {
@override
void dispose() {
+ _timeController?.dispose();
// Be careful : you must `close` the audio session when you have finished with it.
RecordMp3.instance.stop();
//_myRecorder.closeRecorder();
@@ -80,7 +86,6 @@ class _RecordSoundState extends State {
String recordingFileDirectory;
_startRecording() async {
- // await Permission.camera
PermissionStatus status = await Permission.microphone.request();
if (!status.isGranted) {
PermissionStatus status = await Permission.microphone.request();
@@ -89,6 +94,11 @@ class _RecordSoundState extends State {
return;
}
}
+ _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
+ setState(() {
+ _timeController.text = ((timer?.tick ?? 0) / 60)?.toStringAsFixed(2);
+ });
+ });
_rive.addController(SimpleAnimation('recording'));
if (!_recorderIsOpened) {
// await _myRecorder.openRecorder();
@@ -111,7 +121,9 @@ class _RecordSoundState extends State {
setState(() {});
return;
}
-
+ if (_timer?.isActive ?? false) {
+ _timer.cancel();
+ }
RecordMp3.instance.stop();
//String path = (await _myRecorder.stopRecorder()).toString();
@@ -137,94 +149,30 @@ class _RecordSoundState extends State {
@override
Widget build(BuildContext context) {
- return Container(
- padding: const EdgeInsets.only(left: 12, right: 0),
- decoration: BoxDecoration(
- color: const Color(0xfff5f5f5),
- border: Border.all(
- color: const Color(0xffefefef),
+ return Stack(
+ alignment: AlignmentDirectional.centerEnd,
+ children: [
+ AppTextFormField(
+ enable: false,
+ controller: _timeController,
+ labelText: context.translation.recordVoice,
+ initialValue: (_timeController?.text?.isEmpty ?? true) ? "00:00" : _timeController?.text,
+ suffixIcon: (_recording ? "record".toLottieAsset(height: 24) : (_record != null ? "trash" : "mic").toSvgAsset(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, height: 24))
+ .paddingOnly(end: 16),
),
- borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
- ),
- child: Column(
- children: [
- Row(
- children: [
- Expanded(
- child: _recording
- ? Row(
- children: [
- ASmallButton(
- text: "done",
- onPressed: () {
- _stopRecording();
- },
- ),
- Expanded(
- child: Stack(
- children: [
- SizedBox(
- height: 24 * AppStyle.getScaleFactor(context),
- child: Rive(
- artboard: _rive,
- )),
- InkWell(
- child: SizedBox(
- height: 32 * AppStyle.getScaleFactor(context),
- width: MediaQuery.of(context).size.width,
- ),
- onTap: () {
- _cancelRecording();
- },
- ),
- ],
- ),
- ),
- ],
- )
- : _record != null
- ? Row(
- children: [
- Expanded(child: ASoundPlayer(audio: _record)),
- AIconButton2(
- iconData: Icons.delete,
- onPressed: () {
- widget.onRecord(null);
- _record = null;
- setState(() {});
- },
- )
- ],
- )
- : const Text("Record Voice"),
- ),
- Material(
- color: Colors.transparent,
- child: GestureDetector(
- //key: ValueKey("voice"),
- onTapDown: widget.enabled
- ? (TapDownDetails details) async {
- _startRecording();
- }
- : null,
- onTapUp: widget.enabled
- ? (TapUpDetails details) async {
- _stopRecording();
- }
- : null,
- onTapCancel: widget.enabled
- ? () async {
- _cancelRecording();
- }
- : null,
- //key: ValueKey("voice"),
- child: const Padding(padding: EdgeInsets.all(12.0), child: Icon(Icons.mic)),
- ),
- ),
- ],
- ),
- ],
- ),
+ SizedBox(height: 50.toScreenHeight, width: 50.toScreenWidth).onPress(() {
+ if (_recording) {
+ _stopRecording();
+ } else if (_record != null) {
+ _timeController?.text = "00:00";
+ widget.onRecord(null);
+ _record = null;
+ setState(() {});
+ } else {
+ _startRecording();
+ }
+ })
+ ],
);
}
}
diff --git a/pubspec.lock b/pubspec.lock
index b3a50550..538a911f 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -209,6 +209,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.8"
+ dotted_border:
+ dependency: "direct main"
+ description:
+ name: dotted_border
+ sha256: "108837e11848ca776c53b30bc870086f84b62ed6e01c503ed976e8f8c7df9c04"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
fake_async:
dependency: transitive
description:
@@ -661,6 +669,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
+ lottie:
+ dependency: "direct main"
+ description:
+ name: lottie
+ sha256: "23522951540d20a57a60202ed7022e6376bed206a4eee1c347a91f58bd57eb9f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.2"
matcher:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 7a84b17e..a52f678d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -68,6 +68,8 @@ dependencies:
path_provider: ^2.1.0
open_file: ^3.3.2
localization: ^2.1.0
+ dotted_border: ^2.1.0
+ lottie: ^2.3.0
dev_dependencies:
flutter_test:
@@ -97,6 +99,7 @@ flutter:
assets:
- assets/
- assets/images/
+ - assets/lottie/
- assets/subtitles/
- assets/rives/
- assets/translations/