Erweiterungen
This commit is contained in:
1 parent
fbdd2a4338
commit
41d086e13e
7 files changed
+244
-185
No files matched your search
@@ -327,20 +327,23 @@ class _MainPageState extends State<MainPage> {
|
||||
}
|
||||
}
|
||||
|
||||
showLogoutAlertDialog(BuildContext context) {
|
||||
showLogoutAlertDialog(BuildContext context) async {
|
||||
Widget yesButton = TextButton(
|
||||
child: const Text("Ja"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
_sendLogoutMessage();
|
||||
|
||||
Future.delayed(const Duration(seconds: 1), () async {
|
||||
MessageService().publish<DisconnectClientMessage>(Constants.messageTopicDisconnectClient, arguments: DisconnectClientMessage());
|
||||
});
|
||||
showMessageDialog(context, "Information", "Sie werden abgemeldet.\nBitte warten...");
|
||||
|
||||
_sendLogoutMessage();
|
||||
|
||||
_loggedOut = true;
|
||||
|
||||
setState(() {});
|
||||
Future.delayed(const Duration(seconds: 5), () async {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
setState(() {});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
+5
-3
@@ -449,10 +449,12 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
|
||||
});
|
||||
}
|
||||
|
||||
void _connectionStatusChanged(ConnectionStatus connectionStatus) {
|
||||
Util.logInfo("_connectionStatusChanged called: $connectionStatus");
|
||||
void _connectionStatusChanged(ConnectionStatus newConnectionStatus) {
|
||||
var currentConnectionStatus = newConnectionStatus.status;
|
||||
|
||||
_connectionLostValueNotifier.value = connectionStatus.status == ConnectionStatusEnum.notConnected;
|
||||
Util.logInfo("_connectionStatusChanged called: $currentConnectionStatus");
|
||||
|
||||
_connectionLostValueNotifier.value = newConnectionStatus.status == ConnectionStatusEnum.notConnected;
|
||||
}
|
||||
|
||||
void _jobReceived(Job job) async {
|
||||
|
||||
+165
-153
@@ -1,10 +1,8 @@
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mqtt_client/mqtt_client.dart';
|
||||
import 'package:stadtbote/main.dart';
|
||||
import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
|
||||
@@ -57,169 +55,182 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs, Function(
|
||||
}
|
||||
});
|
||||
|
||||
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, jobs, (jobdMessage) async {
|
||||
jobs.removeWhere((value) => value.id == jobdMessage.job.id);
|
||||
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, jobs, (jobMessage) async {
|
||||
jobs.removeWhere((value) => value.id == jobMessage.job.id);
|
||||
|
||||
jobs.add(jobdMessage.job);
|
||||
if (jobMessage.job.state == 0) {
|
||||
jobs.add(jobMessage.job);
|
||||
|
||||
if (context.mounted) {
|
||||
setState(() {});
|
||||
if (context.mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return SizedBox(
|
||||
key: GlobalKey(),
|
||||
height: MediaQuery.of(context).size.height * 1,
|
||||
width: MediaQuery.of(context).size.width * 1.2,
|
||||
child: Container(
|
||||
key: GlobalKey(),
|
||||
height: MediaQuery.of(context).size.height * 1,
|
||||
width: MediaQuery.of(context).size.width * 1.2,
|
||||
child: Container(
|
||||
height: 100,
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: ListView.builder(
|
||||
itemCount: jobs.length,
|
||||
itemBuilder: (_, i) {
|
||||
var job = jobs[i];
|
||||
|
||||
for (var job in jobs) {
|
||||
int enableDelay = job.delayOrderTime;
|
||||
if (job.firstDisplayTime == null) {
|
||||
MyApp.isarInstance.writeTxn(() async {
|
||||
job.firstDisplayTime = DateTime.now();
|
||||
|
||||
await MyApp.isarInstance.jobs.put(job);
|
||||
});
|
||||
} else {
|
||||
enableDelay = max(0, DateTime.now().difference(job.firstDisplayTime!).inSeconds);
|
||||
}
|
||||
|
||||
job.enableDelay = enableDelay;
|
||||
child: FutureBuilder<List<Widget>>(
|
||||
future: fetchJobWidgets(jobs),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Util.getWaitWidget(context);
|
||||
} else {
|
||||
return ListView(
|
||||
children: snapshot.requireData,
|
||||
);
|
||||
}
|
||||
|
||||
return ExpandableNotifier(
|
||||
child: ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
title: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
color: Constants.colorPrimary,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: badges.Badge(
|
||||
position: badges.BadgePosition.topEnd(top: -13, end: -5),
|
||||
showBadge: false,
|
||||
badgeContent: const Text(
|
||||
'Neu',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18.0,
|
||||
),
|
||||
),
|
||||
badgeStyle: badges.BadgeStyle(
|
||||
shape: badges.BadgeShape.square,
|
||||
badgeColor: Constants.colorPrimary,
|
||||
padding: const EdgeInsets.all(5),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: const BorderSide(color: Constants.colorPrimary, width: 0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Text(
|
||||
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.transparent),
|
||||
),
|
||||
),
|
||||
SizedBox(width: double.infinity, child: Text('Auftragsnummer: ${job.id}', textAlign: TextAlign.left)),
|
||||
SizedBox(width: double.infinity, child: Text(job.tours[0].comp, textAlign: TextAlign.left)),
|
||||
SizedBox(width: double.infinity, child: Text(job.tours[0].street, textAlign: TextAlign.left)),
|
||||
SizedBox(width: double.infinity, child: Text(job.tours[0].city, textAlign: TextAlign.left)),
|
||||
Row(
|
||||
children: [
|
||||
Image.asset("assets/${mapVehicleTypeToImageName(job.vhtId)}", width: 60, height: 60),
|
||||
const SizedBox(width: 10),
|
||||
Text(mapVehicleTypeToText(job.vhtId)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
ScrollOnExpand(
|
||||
scrollOnExpand: true,
|
||||
scrollOnCollapse: false,
|
||||
child: ExpandablePanel(
|
||||
theme: const ExpandableThemeData(
|
||||
headerAlignment: ExpandablePanelHeaderAlignment.center,
|
||||
tapBodyToCollapse: true,
|
||||
),
|
||||
header: const Padding(
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Text(
|
||||
"Weitere Infos....",
|
||||
style: TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.bold),
|
||||
)),
|
||||
collapsed: const SizedBox(),
|
||||
expanded: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: const Color(0xfffff4e4),
|
||||
border: Border.all(
|
||||
color: Colors.grey,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(job.rem),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(children: [
|
||||
Expanded(
|
||||
child: getDefaultButton(!job.global ? 'Ablehnen' : 'Ignorieren',
|
||||
() {
|
||||
_sendAnswer(job, !job.global ? 2 : 3);
|
||||
|
||||
jobs.removeWhere((value) => value.id == job.id);
|
||||
|
||||
setState(() {});
|
||||
}),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
Expanded(
|
||||
child: getDefaultButton('Annehmen', enabledTimerActive: job.global == false && job.enableDelay > 0, enabledTimerDelay: job.enableDelay, () {
|
||||
_sendAnswer(job, 1);
|
||||
|
||||
jobs.removeWhere((value) => value.id == job.id);
|
||||
|
||||
setState(() {});
|
||||
}),
|
||||
)
|
||||
])
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)),
|
||||
);
|
||||
),
|
||||
));
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<Widget>> fetchJobWidgets(List<Job> jobs) async {
|
||||
List<Widget> widgets = [];
|
||||
|
||||
for (var job in jobs) {
|
||||
int enableDelay = 3; //job.delayOrderTime;
|
||||
if (job.firstDisplayTime == null) {
|
||||
await MyApp.isarInstance.writeTxn(() async {
|
||||
job.firstDisplayTime = DateTime.now();
|
||||
|
||||
await MyApp.isarInstance.jobs.put(job);
|
||||
});
|
||||
} else {
|
||||
enableDelay = max(0, DateTime.now().difference(job.firstDisplayTime!).inSeconds);
|
||||
}
|
||||
|
||||
widgets.add(StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||
return ExpandableNotifier(
|
||||
child: ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
title: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
color: Constants.colorPrimary,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: badges.Badge(
|
||||
position: badges.BadgePosition.topEnd(top: -13, end: -5),
|
||||
showBadge: false,
|
||||
badgeContent: const Text(
|
||||
'Neu',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18.0,
|
||||
),
|
||||
),
|
||||
badgeStyle: badges.BadgeStyle(
|
||||
shape: badges.BadgeShape.square,
|
||||
badgeColor: Constants.colorPrimary,
|
||||
padding: const EdgeInsets.all(5),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: const BorderSide(color: Constants.colorPrimary, width: 0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Text(
|
||||
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.transparent),
|
||||
),
|
||||
),
|
||||
SizedBox(width: double.infinity, child: Text('Auftragsnummer: ${job.id}', textAlign: TextAlign.left)),
|
||||
SizedBox(width: double.infinity, child: Text(job.tours[0].comp, textAlign: TextAlign.left)),
|
||||
SizedBox(width: double.infinity, child: Text(job.tours[0].street, textAlign: TextAlign.left)),
|
||||
SizedBox(width: double.infinity, child: Text(job.tours[0].city, textAlign: TextAlign.left)),
|
||||
Row(
|
||||
children: [
|
||||
Image.asset("assets/${mapVehicleTypeToImageName(job.vhtId)}", width: 60, height: 60),
|
||||
const SizedBox(width: 10),
|
||||
Text(mapVehicleTypeToText(job.vhtId)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
ScrollOnExpand(
|
||||
scrollOnExpand: true,
|
||||
scrollOnCollapse: false,
|
||||
child: ExpandablePanel(
|
||||
theme: const ExpandableThemeData(
|
||||
headerAlignment: ExpandablePanelHeaderAlignment.center,
|
||||
tapBodyToCollapse: true,
|
||||
),
|
||||
header: const Padding(
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Text(
|
||||
"Weitere Infos....",
|
||||
style: TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.bold),
|
||||
)),
|
||||
collapsed: const SizedBox(),
|
||||
expanded: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: const Color(0xfffff4e4),
|
||||
border: Border.all(
|
||||
color: Colors.grey,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(job.rem),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(children: [
|
||||
Expanded(
|
||||
child: getDefaultButton(!job.global ? 'Ablehnen' : 'Ignorieren', () {
|
||||
_sendAnswer(job, !job.global ? 2 : 3);
|
||||
|
||||
jobs.removeWhere((value) => value.id == job.id);
|
||||
|
||||
setState(() {});
|
||||
}),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
Expanded(
|
||||
child: getDefaultButton('Annehmen', enabledTimerActive: enableDelay > 0, enabledTimerDelay: enableDelay, () {
|
||||
_sendAnswer(job, 1);
|
||||
|
||||
jobs.removeWhere((value) => value.id == job.id);
|
||||
|
||||
setState(() {});
|
||||
}),
|
||||
)
|
||||
])
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
||||
return widgets;
|
||||
}
|
||||
|
||||
_sendAnswer(Job job, int item) async {
|
||||
var currentPosition = MyApp.currentPosition;
|
||||
|
||||
@@ -234,9 +245,10 @@ _sendAnswer(Job job, int item) async {
|
||||
message.track.pos!.long = currentPosition != null ? currentPosition.longitude : 0.0;
|
||||
message.track.pos!.acc = currentPosition != null ? currentPosition.accuracy.toInt() : 0;
|
||||
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "reaction", message: message.toJson(), qos: MqttQos.exactlyOnce));
|
||||
MessageService().publish<PublishPayloadMessage>(Constants.messageTopicPublishPayload,
|
||||
arguments: PublishPayloadMessage(topic: "reaction", message: message.toJson(), qos: MqttQos.exactlyOnce));
|
||||
|
||||
await MyApp.isarInstance.writeTxn(() async{
|
||||
await MyApp.isarInstance.writeTxn(() async {
|
||||
await MyApp.isarInstance.jobs.delete(job.id);
|
||||
});
|
||||
|
||||
|
||||
+22
-17
@@ -52,8 +52,6 @@ import 'util.dart';
|
||||
|
||||
enum ConnectionStateEnum { notConnected, connected }
|
||||
|
||||
//const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('app_icon');
|
||||
|
||||
class MqttCore {
|
||||
late ConnectionStateEnum connectionState = ConnectionStateEnum.notConnected;
|
||||
|
||||
@@ -81,18 +79,21 @@ class MqttCore {
|
||||
_processBootstrap();
|
||||
}
|
||||
|
||||
_disconnect() {
|
||||
_disconnectMqttClient() {
|
||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
|
||||
|
||||
_disconnectInProgress = true;
|
||||
|
||||
_cancelReconnectTimer();
|
||||
|
||||
_cancelTrackTimer();
|
||||
|
||||
if (_mqttClient != null) {
|
||||
if (_mqttClient != null && _mqttClient!.connectionStatus == ConnectionStateEnum.connected) {
|
||||
_mqttClient!.disconnect();
|
||||
}
|
||||
|
||||
connectionState = ConnectionStateEnum.notConnected;
|
||||
|
||||
}
|
||||
|
||||
_connectToBroker() async {
|
||||
@@ -102,15 +103,17 @@ class MqttCore {
|
||||
Util.logInfo("broker uri: $_brokerUri");
|
||||
Util.logInfo("broker port: $_brokerPort");
|
||||
|
||||
_mqttClient = MqttServerClient.withPort(_brokerUri, clientId, _brokerPort);
|
||||
_mqttClient!.logging(on: false);
|
||||
_mqttClient!.keepAlivePeriod = 60;
|
||||
_mqttClient!.disconnectOnNoResponsePeriod = 10;
|
||||
_mqttClient!.autoReconnect = true;
|
||||
_mqttClient!.onDisconnected = _clientDisconnected;
|
||||
_mqttClient!.onAutoReconnect = _clientDisconnected;
|
||||
_mqttClient!.onAutoReconnected = _clientConnected;
|
||||
_mqttClient!.connectionMessage = MqttConnectMessage().withClientIdentifier(await Util.getAppUuid()).authenticateAs("app", "apppwd");
|
||||
if (_mqttClient == null) {
|
||||
_mqttClient = MqttServerClient.withPort(_brokerUri, clientId, _brokerPort);
|
||||
_mqttClient!.logging(on: false);
|
||||
_mqttClient!.keepAlivePeriod = 60;
|
||||
_mqttClient!.disconnectOnNoResponsePeriod = 10;
|
||||
_mqttClient!.autoReconnect = true;
|
||||
_mqttClient!.onDisconnected = _clientDisconnected;
|
||||
_mqttClient!.onAutoReconnect = _clientDisconnected;
|
||||
_mqttClient!.onAutoReconnected = _clientConnected;
|
||||
_mqttClient!.connectionMessage = MqttConnectMessage().withClientIdentifier(await Util.getAppUuid()).authenticateAs("app", "apppwd");
|
||||
}
|
||||
|
||||
await _mqttClient!.connect();
|
||||
|
||||
@@ -384,8 +387,10 @@ class MqttCore {
|
||||
}
|
||||
|
||||
void _cancelReconnectTimer() {
|
||||
if (_reconnectTimer != null && _reconnectTimer!.isActive) {
|
||||
_reconnectTimer!.cancel();
|
||||
if (!_disconnectInProgress) {
|
||||
if (_reconnectTimer != null && _reconnectTimer!.isActive) {
|
||||
_reconnectTimer!.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,7 +399,7 @@ class MqttCore {
|
||||
|
||||
connectionState = ConnectionStateEnum.notConnected;
|
||||
|
||||
_startTrackTimer();
|
||||
_cancelTrackTimer();
|
||||
|
||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
|
||||
}
|
||||
@@ -546,7 +551,7 @@ class MqttCore {
|
||||
|
||||
MessageService().subscribe<DisconnectClientMessage>(Constants.messageTopicDisconnectClient, this,
|
||||
(DisconnectClientMessage disconnectClientMessage) {
|
||||
_disconnect();
|
||||
_disconnectMqttClient();
|
||||
});
|
||||
|
||||
MessageService().subscribe<ConnectClientMessage>(Constants.messageTopicConnectClient, this, (ConnectClientMessage connectClientMessage) {
|
||||
|
||||
+15
-2
@@ -220,8 +220,8 @@ class Util {
|
||||
}
|
||||
}
|
||||
|
||||
Widget getDefaultButton(String text, Function() onPressed, {Image? image, double? buttonHeight, bool enabledTimerActive = true, int enabledTimerDelay = 0}) {
|
||||
bool enabledState = enabledTimerActive;
|
||||
Widget getDefaultButton(String text, Function() onPressed, {Image? image, double? buttonHeight, bool enabledTimerActive = false, int enabledTimerDelay = 0}) {
|
||||
bool enabledState = !enabledTimerActive;
|
||||
|
||||
return StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||
if (!enabledState) {
|
||||
@@ -411,6 +411,19 @@ Future<void> showAlertDialog(BuildContext context, String title, String message)
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> showMessageDialog(BuildContext context, String title, String message) async {
|
||||
await showDialog(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(title),
|
||||
content: Text(message),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
class DecimalTextInputFormatter extends TextInputFormatter {
|
||||
int maxLength;
|
||||
|
||||
|
||||
Reference in new issue
Block a user