diff --git a/lib/content_views/assigned_jobs_page.dart b/lib/content_views/assigned_jobs_page.dart index 4b602b7..39708df 100644 --- a/lib/content_views/assigned_jobs_page.dart +++ b/lib/content_views/assigned_jobs_page.dart @@ -1,14 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart'; import 'package:isar/isar.dart'; -import 'package:stadtbote/content_views/tour_list_page.dart'; import 'package:stadtbote/content_views/utils/content_view_widget.dart'; import 'package:stadtbote/content_views/utils/header_info.dart'; import 'package:intl/intl.dart'; import '../main.dart'; import '../model/job.dart'; -import '../tools/constants.dart'; import '../tools/util.dart'; class AssignedJobsPage extends ContentViewWidget { diff --git a/lib/content_views/task_list_page.dart b/lib/content_views/task_list_page.dart index 068f14a..f43cc13 100644 --- a/lib/content_views/task_list_page.dart +++ b/lib/content_views/task_list_page.dart @@ -6,7 +6,10 @@ import 'package:stadtbote/content_views/utils/header_info.dart'; import 'package:stadtbote/model/job_tour.dart'; import 'package:stadtbote/popups/tasks_popups/arrived_popup.dart'; import 'package:stadtbote/popups/tasks_popups/commision_number_popup.dart'; +import 'package:stadtbote/popups/tasks_popups/receipt_giver_popup.dart'; import 'package:stadtbote/popups/tasks_popups/scan_barcodes_popup.dart'; +import 'package:stadtbote/popups/tasks_popups/station_notice_popup.dart'; +import 'package:stadtbote/popups/tasks_popups/take_photos_popup.dart'; import '../main.dart'; import '../model/task_info.dart'; @@ -178,20 +181,32 @@ class _TaskListPageState extends State { void _processTask(TaskInfo taskInfo) { switch(taskInfo.task.type) { case 3: - _processTaskArrived(taskInfo); + _processTaskArrivedOrFinished(taskInfo); + break; + + case 4: + _processTakePhotos(taskInfo); break; case 5: _processScanBarcodes(taskInfo); break; + case 7: + _processReceiptGiver(taskInfo); + break; + + case 8: + _processStationNotice(taskInfo); + break; + case 9: _processCommissionNumber(taskInfo); break; } } - void _processTaskArrived(TaskInfo taskInfo) { + void _processTaskArrivedOrFinished(TaskInfo taskInfo) { _popup = showTaskArrivedPopup(context, taskInfo, () => { _popup.dismiss(context), }); @@ -208,4 +223,22 @@ class _TaskListPageState extends State { _popup.dismiss(context) }); } + + void _processTakePhotos(TaskInfo taskInfo) { + _popup = showTakePhotosPopup(context, taskInfo, () => { + _popup.dismiss(context) + }); + } + + void _processStationNotice(TaskInfo taskInfo) { + _popup = showStationNoticePopup(context, taskInfo, () => { + _popup.dismiss(context) + }); + } + + void _processReceiptGiver(TaskInfo taskInfo) { + _popup = showReceiptGiverPopup(context, taskInfo, () => { + _popup.dismiss(context) + }); + } } diff --git a/lib/model/bootstrap_request.dart b/lib/model/bootstrap_request.dart index 36dded5..029d307 100644 --- a/lib/model/bootstrap_request.dart +++ b/lib/model/bootstrap_request.dart @@ -1,4 +1,3 @@ -import 'package:isar/isar.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:stadtbote/model/device_object.dart'; diff --git a/lib/model/bootstrap_response_config.dart b/lib/model/bootstrap_response_config.dart index a6a487d..60f758a 100644 --- a/lib/model/bootstrap_response_config.dart +++ b/lib/model/bootstrap_response_config.dart @@ -1,7 +1,5 @@ -import 'package:isar/isar.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:stadtbote/model/bootstrap_response_topics.dart'; -import 'package:stadtbote/model/device_object.dart'; part 'bootstrap_response_config.g.dart'; diff --git a/lib/model/bootstrap_response_payload.dart b/lib/model/bootstrap_response_payload.dart index d7b2ccf..b8b0dcc 100644 --- a/lib/model/bootstrap_response_payload.dart +++ b/lib/model/bootstrap_response_payload.dart @@ -1,7 +1,5 @@ -import 'package:isar/isar.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:stadtbote/model/bootstrap_response_config.dart'; -import 'package:stadtbote/model/device_object.dart'; part 'bootstrap_response_payload.g.dart'; diff --git a/lib/model/bootstrap_response_topics.dart b/lib/model/bootstrap_response_topics.dart index 43b4ae8..1e37ac7 100644 --- a/lib/model/bootstrap_response_topics.dart +++ b/lib/model/bootstrap_response_topics.dart @@ -1,6 +1,4 @@ -import 'package:isar/isar.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:stadtbote/model/device_object.dart'; part 'bootstrap_response_topics.g.dart'; diff --git a/lib/model/device_object.dart b/lib/model/device_object.dart index db2d2c7..330d559 100644 --- a/lib/model/device_object.dart +++ b/lib/model/device_object.dart @@ -1,4 +1,3 @@ -import 'package:isar/isar.dart'; import 'package:json_annotation/json_annotation.dart'; part 'device_object.g.dart'; diff --git a/lib/popups/tasks_popups/arrived_popup.dart b/lib/popups/tasks_popups/arrived_popup.dart index 368f07a..7fa0983 100644 --- a/lib/popups/tasks_popups/arrived_popup.dart +++ b/lib/popups/tasks_popups/arrived_popup.dart @@ -47,9 +47,9 @@ KumiPopupWindow showTaskArrivedPopup(BuildContext context, TaskInfo taskInfo, Fu padding: const EdgeInsets.all(35.0), child: Column( children: [ - const Text('Bitte bestätigen Sie Ihre Ankunft'), + Text(taskInfo.task.topic), const SizedBox(height: 20), - getDefaultButton('Ankunft bestätigen', () => { + getDefaultButton(taskInfo.task.topic, () => { onFinished() }), ], diff --git a/lib/popups/tasks_popups/commision_number_popup.dart b/lib/popups/tasks_popups/commision_number_popup.dart index acea400..c8773f1 100644 --- a/lib/popups/tasks_popups/commision_number_popup.dart +++ b/lib/popups/tasks_popups/commision_number_popup.dart @@ -55,7 +55,7 @@ KumiPopupWindow showCommisionNumberPopup(BuildContext context, TaskInfo taskInfo Util.getDefaultTextField('Kommisionsnummer', type: TextInputType.text, formatter: [FilteringTextInputFormatter.singleLineFormatter], controller: textEditingController, autofocus: true), const SizedBox(height: 20), - getDefaultButton('Ankunft bestätigen', () => { + getDefaultButton('Übernehmen', () => { onFinished() }) ], ), diff --git a/lib/popups/tasks_popups/receipt_giver_popup.dart b/lib/popups/tasks_popups/receipt_giver_popup.dart new file mode 100644 index 0000000..1c0787d --- /dev/null +++ b/lib/popups/tasks_popups/receipt_giver_popup.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:kumi_popup_window/kumi_popup_window.dart'; +import 'package:stadtbote/model/task_info.dart'; +import 'package:stadtbote/tools/util.dart'; + +KumiPopupWindow showReceiptGiverPopup(BuildContext context, TaskInfo taskInfo, Function() onFinished) { + return showPopupWindow( + context, + //childSize:Size(240, MediaQuery.of(context).size.width * 0.8), + gravity: KumiPopupGravity.center, + //curve: Curves.elasticOut, + bgColor: Colors.grey.withOpacity(0.5), + clickOutDismiss: true, + clickBackDismiss: true, + customAnimation: false, + customPop: false, + customPage: false, + // targetRenderBox: (btnKey.currentContext.findRenderObject() as RenderBox), + //needSafeDisplay: true, + underStatusBar: false, + underAppBar: false, + //offsetX: -180, + //offsetY: 50, + duration: const Duration(milliseconds: 200), + onShowStart: (pop) {}, + onShowFinish: (pop) {}, + onDismissStart: (pop) {}, + onDismissFinish: (pop) {}, + onClickOut: (pop) {}, + onClickBack: (pop) {}, + childFun: (pop) { + TextEditingController textEditingController = TextEditingController(); + + return SizedBox( + key: GlobalKey(), + height: 260, + width: MediaQuery.of(context).size.width * 0.8, + child: Container( + height: 100, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + border: Border.all( + color: Colors.grey, + width: 0.5, + ), + ), + child: Padding( + padding: const EdgeInsets.all(35.0), + child: Column( + children: [ + Text(taskInfo.task.topic), + const SizedBox(height: 20), + Util.getDefaultTextField(taskInfo.task.topic, + type: TextInputType.text, formatter: [FilteringTextInputFormatter.singleLineFormatter], controller: textEditingController, autofocus: true), + const SizedBox(height: 20), + getDefaultButton('Übernehmen', () => { + onFinished() + }) + ], + ), + ), + )); + }, + ); +} + diff --git a/lib/popups/tasks_popups/scan_barcodes_popup.dart b/lib/popups/tasks_popups/scan_barcodes_popup.dart index 57fc267..348d29d 100644 --- a/lib/popups/tasks_popups/scan_barcodes_popup.dart +++ b/lib/popups/tasks_popups/scan_barcodes_popup.dart @@ -39,7 +39,7 @@ KumiPopupWindow showScanBarcodesPopup(BuildContext context, TaskInfo taskInfo, F List barcodeWidgets = []; for(var barcode in scannedBarcodes) { - barcodeWidgets.add(Container( + barcodeWidgets.add(SizedBox( height: 20, child: Center(child: Text(barcode)), )); diff --git a/lib/popups/tasks_popups/station_notice_popup.dart b/lib/popups/tasks_popups/station_notice_popup.dart new file mode 100644 index 0000000..d4cfc98 --- /dev/null +++ b/lib/popups/tasks_popups/station_notice_popup.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; +import 'package:kumi_popup_window/kumi_popup_window.dart'; +import 'package:stadtbote/model/task_info.dart'; +import 'package:stadtbote/tools/util.dart'; + +KumiPopupWindow showStationNoticePopup(BuildContext context, TaskInfo taskInfo, Function() onFinished) { + return showPopupWindow( + context, + //childSize:Size(240, MediaQuery.of(context).size.width * 0.8), + gravity: KumiPopupGravity.center, + //curve: Curves.elasticOut, + bgColor: Colors.grey.withOpacity(0.5), + clickOutDismiss: true, + clickBackDismiss: true, + customAnimation: false, + customPop: false, + customPage: false, + // targetRenderBox: (btnKey.currentContext.findRenderObject() as RenderBox), + //needSafeDisplay: true, + underStatusBar: false, + underAppBar: false, + //offsetX: -180, + //offsetY: 50, + duration: const Duration(milliseconds: 200), + onShowStart: (pop) {}, + onShowFinish: (pop) {}, + onDismissStart: (pop) {}, + onDismissFinish: (pop) {}, + onClickOut: (pop) {}, + onClickBack: (pop) {}, + childFun: (pop) { + TextEditingController textEditingController = TextEditingController(); + + return SizedBox( + key: GlobalKey(), + height: 280, + width: MediaQuery.of(context).size.width * 0.8, + child: Container( + height: 100, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + border: Border.all( + color: Colors.grey, + width: 0.5, + ), + ), + child: Padding( + padding: const EdgeInsets.all(35.0), + child: Column( + children: [ + Text(taskInfo.task.topic), + const SizedBox(height: 20), + Container( + height: 100, + child: Util.getDefaultTextField(taskInfo.task.topic, + type: TextInputType.text, + maxLines: 10, + formatter: [FilteringTextInputFormatter.singleLineFormatter], + controller: textEditingController, + autofocus: true), + ), + const SizedBox(height: 20), + getDefaultButton('Übernehmen', buttonHeight: 50, () => {onFinished()}) + ], + ), + ), + )); + }, + ); +} + +/* + + */ diff --git a/lib/popups/tasks_popups/take_photos_popup.dart b/lib/popups/tasks_popups/take_photos_popup.dart new file mode 100644 index 0000000..c362af4 --- /dev/null +++ b/lib/popups/tasks_popups/take_photos_popup.dart @@ -0,0 +1,115 @@ +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; +import 'package:kumi_popup_window/kumi_popup_window.dart'; +import 'package:stadtbote/model/task_info.dart'; +import 'package:stadtbote/tools/util.dart'; + +KumiPopupWindow showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Function() onFinished) { + return showPopupWindow( + context, + //childSize:Size(240, MediaQuery.of(context).size.width * 0.8), + gravity: KumiPopupGravity.center, + //curve: Curves.elasticOut, + bgColor: Colors.grey.withOpacity(0.5), + clickOutDismiss: true, + clickBackDismiss: true, + customAnimation: false, + customPop: false, + customPage: false, + // targetRenderBox: (btnKey.currentContext.findRenderObject() as RenderBox), + //needSafeDisplay: true, + underStatusBar: false, + underAppBar: false, + //offsetX: -180, + //offsetY: 50, + duration: const Duration(milliseconds: 200), + onShowStart: (pop) {}, + onShowFinish: (pop) {}, + onDismissStart: (pop) {}, + onDismissFinish: (pop) {}, + onClickOut: (pop) {}, + onClickBack: (pop) {}, + childFun: (pop) { + List imageList = []; + List imageWidgetsList = []; + + ValueNotifier> imageWidgetsListNotifier = ValueNotifier>([]); + + void capturePhoto() async { + var photo = await Util.capturePhoto(); + + if (photo != null) { + var imageData = await photo.readAsBytes(); + photo.delete(); + + imageList.add(imageData); + + imageWidgetsList.clear(); + for(var image in imageList) { + imageWidgetsList.add(GestureDetector( + onTap: () { + }, + child: Image.memory(image), + )); + } + + imageWidgetsListNotifier.value = imageWidgetsList; + imageWidgetsListNotifier.notifyListeners(); + } + } + + return SizedBox( + key: GlobalKey(), + height: 530, + width: MediaQuery.of(context).size.width * 0.8, + child: Container( + height: 100, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + border: Border.all( + color: Colors.grey, + width: 0.5, + ), + ), + child: Padding( + padding: const EdgeInsets.all(35.0), + child: Column( + children: [ + const Text('Aufgenommene Fotos'), + const SizedBox(height: 20), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + border: Border.all( + color: Colors.grey, + width: 0.5, + ), + ), + height: 300, + child: ValueListenableBuilder>( + valueListenable: imageWidgetsListNotifier, + builder: (context, value, child) { + return CarouselSlider( + options: CarouselOptions( + disableCenter: false, + enableInfiniteScroll: false, + ), + items: imageWidgetsList.toList() + ); + }, + ), + ), + const SizedBox(height: 20), + getDefaultButton('Hinzufügen', buttonHeight: 50, () => {capturePhoto()}), + getDefaultButton('Übernehmen', buttonHeight: 50, () => {onFinished()}) + ], + ), + ), + )); + }, + ); +} diff --git a/lib/tools/mqtt_core.dart b/lib/tools/mqtt_core.dart index b333ff1..c8d911d 100644 --- a/lib/tools/mqtt_core.dart +++ b/lib/tools/mqtt_core.dart @@ -193,7 +193,7 @@ class MqttCore { var jsonMap = handshakeMessage.toJson(); var json = jsonEncode(jsonMap); var uri = "https://init-x.assecutor.de/bootstrap?get_mqtt_broker=$json"; - print("Bootstrap request: $uri"); + Util.logInfo("Bootstrap request: $uri"); var response = await http.get(Uri.parse(uri)); var responseText = response.body; diff --git a/lib/tools/util.dart b/lib/tools/util.dart index 2e84311..96ceb9d 100644 --- a/lib/tools/util.dart +++ b/lib/tools/util.dart @@ -1,6 +1,9 @@ +import 'dart:io'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:image_picker/image_picker.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:stadtbote/tools/constants.dart'; import 'package:uuid/uuid.dart'; @@ -160,6 +163,17 @@ class Util { borderRadius: BorderRadius.all(Radius.circular(20.0)), ); } + + static Future capturePhoto() async { + final imagePicker = ImagePicker(); + final pickedFile = await imagePicker.pickImage(source: ImageSource.camera); + + if (pickedFile != null) { + return File(pickedFile.path); + } + + return null; + } } Widget getDefaultButton(String text, Function() onPressed, {Image? image, double? buttonHeight}) { diff --git a/pubspec.lock b/pubspec.lock index fea5d38..232e2f8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -129,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "8.7.0" + carousel_slider: + dependency: "direct main" + description: + name: carousel_slider + sha256: "9c695cc963bf1d04a47bd6021f68befce8970bcd61d24938e1fb0918cf5d9c42" + url: "https://pub.dev" + source: hosted + version: "4.2.1" characters: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7103ad3..9822007 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,6 +61,7 @@ dependencies: flutter_map: ^4.0.0 latlong2: ^0.8.2 flutter_barcode_scanner: ^2.0.0 + carousel_slider: ^4.2.1 dev_dependencies: flutter_test: