Merge branch 'main' into new_appserver
# Conflicts: # lib/content_views/approach_area_page.dart # lib/content_views/assigned_jobs_page.dart # lib/content_views/main_page.dart # lib/content_views/task_list_page.dart # lib/main.dart # lib/popups/accept_jobs_popup.dart # lib/protocoll_messages/logout_message.dart # lib/protocoll_messages/logout_message.g.dart # lib/tools/constants.dart # lib/tools/mqtt_core.dart # pubspec.lock # pubspec.yaml
No files matched your search
@@ -49,10 +49,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
|
||||||
applicationId "de.assecutor.stadtbote"
|
applicationId "de.assecutor.stadtbote"
|
||||||
// You can update the following values to match your application needs.
|
|
||||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
|
||||||
minSdkVersion flutter.minSdkVersion
|
minSdkVersion flutter.minSdkVersion
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="de.assecutor.stadtbote">
|
package="de.assecutor.stadtbote">
|
||||||
<application
|
<application
|
||||||
android:label="stadtbote"
|
android:label="Stadtbote"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/launcher_icon">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|||||||
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 586 B After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 7.1 KiB |
@@ -45,6 +45,12 @@ class _AcceptedJobsPageState extends State<AcceptedJobsPage> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
Future.delayed(const Duration(seconds: 0), () async {
|
Future.delayed(const Duration(seconds: 0), () async {
|
||||||
_jobs = await MyApp.isarInstance.jobs.filter().stateEqualTo(Constants.stateAccepted).findAll();
|
_jobs = await MyApp.isarInstance.jobs.filter().stateEqualTo(Constants.stateAccepted).findAll();
|
||||||
|
_jobs.sort((job1, job2) {
|
||||||
|
var date1 = DateTime.parse(job1.ordertime).millisecondsSinceEpoch;
|
||||||
|
var date2 = DateTime.parse(job2.ordertime).millisecondsSinceEpoch;
|
||||||
|
|
||||||
|
return date1 - date2;
|
||||||
|
});
|
||||||
|
|
||||||
_initCompleted = true;
|
_initCompleted = true;
|
||||||
|
|
||||||
@@ -88,8 +94,8 @@ class _AcceptedJobsPageState extends State<AcceptedJobsPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(),
|
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
|
||||||
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.white),
|
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.transparent),
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
||||||
import 'package:stadtbote/content_views/utils/header_info.dart';
|
import 'package:stadtbote/content_views/utils/header_info.dart';
|
||||||
import 'package:stadtbote/model/rank.dart';
|
import 'package:stadtbote/model/ranking.dart';
|
||||||
import 'package:stadtbote/popups/tasks_popups/zip_popup.dart';
|
import 'package:stadtbote/popups/tasks_popups/zip_popup.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/zip_message.dart';
|
import 'package:stadtbote/protocoll_messages/zip_message.dart';
|
||||||
|
import 'package:stadtbote/tools/constants.dart';
|
||||||
|
import 'package:stadtbote/tools/message_service.dart';
|
||||||
|
import 'package:stadtbote/tools/messages/ranking_updated.dart';
|
||||||
import 'package:stadtbote/tools/mqtt_core.dart';
|
import 'package:stadtbote/tools/mqtt_core.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
@@ -43,21 +44,30 @@ class ApproachAreaPage extends ContentViewWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ApproachAreaPageState extends State<ApproachAreaPage> {
|
class _ApproachAreaPageState extends State<ApproachAreaPage> {
|
||||||
late List<Rank>? _rankings;
|
late Ranking? _ranking;
|
||||||
|
|
||||||
late bool _initCompleted = false;
|
late bool _initCompleted = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
Future.delayed(const Duration(seconds: 0), () async {
|
Future.delayed(const Duration(seconds: 0), () async {
|
||||||
_rankings = await MyApp.isarInstance.ranks.where().findAll();
|
_ranking = await MyApp.isarInstance.rankings.where().findFirst();
|
||||||
|
|
||||||
_initCompleted = true;
|
_initCompleted = true;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
|
|
||||||
super.initState();
|
_initMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void deactivate() {
|
||||||
|
super.deactivate();
|
||||||
|
|
||||||
|
MessageService().unsubscribe(Constants.messageTopicRankingUpdated, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -84,18 +94,16 @@ class _ApproachAreaPageState extends State<ApproachAreaPage> {
|
|||||||
List<Widget> _fillColumns() {
|
List<Widget> _fillColumns() {
|
||||||
List<Widget> columns = [];
|
List<Widget> columns = [];
|
||||||
|
|
||||||
if (_rankings != null) {
|
if (_ranking != null) {
|
||||||
for (int i = 0; i < _rankings!.length; i++) {
|
for (int i = 0; i < _ranking!.ranks.length; i++) {
|
||||||
var rank = _rankings![i];
|
var rank = _ranking!.ranks[i];
|
||||||
|
|
||||||
List<Widget> entries = [];
|
List<Widget> entries = [];
|
||||||
entries.add(
|
entries.add(
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: ()=> {
|
onTap: () => {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
showZipPopup(context, 'ACHTUNG: Wenn Sie Ihre PLZ ändern, verlieren Sie Ihr Ranking!\n', 'Freimelden', (zip) => {_sendZip(rank, zip, ModeEnum.set)}),
|
showZipPopup(context, 'ACHTUNG: Wenn Sie Ihre PLZ ändern, verlieren Sie Ihr Ranking!\n', 'Freimelden', (zip) => {_sendZip(rank, zip, ModeEnum.set)}),
|
||||||
} else {
|
|
||||||
showZipPopup(context, 'ACHTUNG: Wenn Sie Ihre PLZ ändern, verlieren Sie Ihr Ranking!\n', 'OK', (zip) => {_sendZip(rank, zip, ModeEnum.request)}),
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -103,7 +111,7 @@ class _ApproachAreaPageState extends State<ApproachAreaPage> {
|
|||||||
margin: const EdgeInsets.all(2),
|
margin: const EdgeInsets.all(2),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
color: i == 0 ? Colors.lightGreen : Colors.white,
|
color: i == 0 ? Constants.colorPrimary : Colors.white,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
@@ -114,10 +122,11 @@ class _ApproachAreaPageState extends State<ApproachAreaPage> {
|
|||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
Text(
|
Text(
|
||||||
rank.zip,
|
rank.zip,
|
||||||
style: const TextStyle(fontSize: 20),
|
style: TextStyle(fontSize: 20, color: (i == 0 ? Colors.white : Colors.black)),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
rank.area,
|
rank.area,
|
||||||
|
style: TextStyle(fontSize: 13, color: (i == 0 ? Colors.white : Colors.black)),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -168,56 +177,36 @@ class _ApproachAreaPageState extends State<ApproachAreaPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_sendZip(Rank rank, String zip, ModeEnum mode) {
|
_sendZip(Rank rank, String zip, ModeEnum mode) {
|
||||||
var message = ZipMessage();
|
var zipMessage = ZipMessage();
|
||||||
|
|
||||||
if (mode == ModeEnum.set) {
|
if (mode == ModeEnum.set) {
|
||||||
var position = MyApp.currentPosition;
|
var position = MyApp.currentPosition;
|
||||||
|
|
||||||
message.setPos = ZipSetPos();
|
zipMessage.setPos = ZipSetPos();
|
||||||
message.setPos!.zip = zip;
|
zipMessage.setPos!.zip = zip;
|
||||||
|
|
||||||
if (position != null) {
|
if (position != null) {
|
||||||
message.setPos!.track = ZipTrack();
|
zipMessage.setPos!.track = ZipTrack();
|
||||||
message.setPos!.track.time = DateTime.now().toIso8601String();
|
zipMessage.setPos!.track!.time = DateTime.now().toIso8601String();
|
||||||
message.setPos!.track.pos = ZipTrackPos();
|
zipMessage.setPos!.track!.pos = ZipTrackPos();
|
||||||
message.setPos!.track.pos!.lat = position.latitude;
|
zipMessage.setPos!.track!.pos!.lat = position.latitude;
|
||||||
message.setPos!.track.pos!.long = position.longitude;
|
zipMessage.setPos!.track!.pos!.long = position.longitude;
|
||||||
message.setPos!.track.pos!.acc = position.accuracy.toInt();
|
zipMessage.setPos!.track!.pos!.acc = position.accuracy.toInt();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
message.reqZip = ZipReqZip();
|
zipMessage.reqZip = ZipReqZip();
|
||||||
message.reqZip!.id = rank.id;
|
zipMessage.reqZip!.id = rank.id;
|
||||||
message.reqZip!.zip = zip;
|
zipMessage.reqZip!.zip = zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttCore.instance.publishText("set_location", jsonEncode(message.toJson()));
|
MqttCore.instance.publishPayloadMessage("rank", zipMessage.toJson());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
_initMessages() {
|
||||||
private void SendMessage(int columnNumber, string zipNumber)
|
MessageService().subscribe<RankingUpdated>(Constants.messageTopicRankingUpdated, this, (rankingUpdateMessage) async {
|
||||||
{
|
_ranking = await MyApp.isarInstance.rankings.where().findFirst();
|
||||||
var payloadObject = new JObject();
|
|
||||||
|
|
||||||
if (columnNumber == 0)
|
setState(() {});
|
||||||
{
|
});
|
||||||
var setPosObject = new JObject();
|
}
|
||||||
payloadObject.Add(new JProperty("set_pos", setPosObject));
|
}
|
||||||
|
|
||||||
setPosObject.Add(new JProperty("zip", zipNumber));
|
|
||||||
setPosObject.Add(new JProperty("track", CreateTrackObject()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var regZipObject = new JObject();
|
|
||||||
payloadObject.Add(new JProperty("reg_zip", regZipObject));
|
|
||||||
|
|
||||||
regZipObject.Add(new JProperty("id", columnNumber));
|
|
||||||
regZipObject.Add(new JProperty("zip", zipNumber));
|
|
||||||
}
|
|
||||||
|
|
||||||
var json = payloadObject.ToString();
|
|
||||||
|
|
||||||
App.Core.SendJsonMessageAsync("rank", payloadObject);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:expandable/expandable.dart';
|
import 'package:expandable/expandable.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
@@ -10,7 +8,7 @@ import 'package:badges/badges.dart' as badges;
|
|||||||
import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
|
import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
|
import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
|
||||||
import 'package:stadtbote/tools/message_service.dart';
|
import 'package:stadtbote/tools/message_service.dart';
|
||||||
import 'package:stadtbote/tools/messages/refresh_badges_message.dart';
|
import 'package:stadtbote/tools/messages/job_deleted_message.dart';
|
||||||
import 'package:stadtbote/tools/mqtt_core.dart';
|
import 'package:stadtbote/tools/mqtt_core.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
@@ -53,6 +51,8 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> {
|
|||||||
Future.delayed(const Duration(seconds: 0), () async {
|
Future.delayed(const Duration(seconds: 0), () async {
|
||||||
_entries = await _createListEntries();
|
_entries = await _createListEntries();
|
||||||
|
|
||||||
|
_initMessages();
|
||||||
|
|
||||||
_initCompleted = true;
|
_initCompleted = true;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@@ -86,6 +86,12 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> {
|
|||||||
|
|
||||||
var jobs = await MyApp.isarInstance.jobs.filter().stateEqualTo(Constants.stateAssigned).findAll();
|
var jobs = await MyApp.isarInstance.jobs.filter().stateEqualTo(Constants.stateAssigned).findAll();
|
||||||
for (var job in jobs) {
|
for (var job in jobs) {
|
||||||
|
String remarkString = '';
|
||||||
|
for (var remark in job.rem) {
|
||||||
|
remarkString += '$remark\n';
|
||||||
|
}
|
||||||
|
remarkString = remarkString.trim();
|
||||||
|
|
||||||
entries.add(ExpandableNotifier(
|
entries.add(ExpandableNotifier(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||||
@@ -119,7 +125,7 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(),
|
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.white),
|
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.white),
|
||||||
),
|
),
|
||||||
@@ -144,7 +150,7 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> {
|
|||||||
)),
|
)),
|
||||||
collapsed: const SizedBox(),
|
collapsed: const SizedBox(),
|
||||||
expanded: Column(
|
expanded: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
height: 200,
|
height: 200,
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class _FinishedJobsPageState extends State<FinishedJobsPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(),
|
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:stadtbote/content_views/accepted_jobs_page.dart';
|
import 'package:stadtbote/content_views/accepted_jobs_page.dart';
|
||||||
@@ -10,19 +11,21 @@ import 'package:stadtbote/content_views/messages_page.dart';
|
|||||||
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
||||||
import 'package:stadtbote/content_views/utils/header_info.dart';
|
import 'package:stadtbote/content_views/utils/header_info.dart';
|
||||||
import 'package:stadtbote/model/job.dart';
|
import 'package:stadtbote/model/job.dart';
|
||||||
|
import 'package:stadtbote/model/log_entry.dart';
|
||||||
import 'package:stadtbote/model/message.dart';
|
import 'package:stadtbote/model/message.dart';
|
||||||
import 'package:stadtbote/model/session_status.dart';
|
import 'package:stadtbote/model/session_status.dart';
|
||||||
import 'package:stadtbote/model/status.dart';
|
import 'package:stadtbote/model/status.dart';
|
||||||
import 'package:stadtbote/popups/infos_popup.dart';
|
import 'package:stadtbote/popups/infos_popup.dart';
|
||||||
|
import 'package:stadtbote/protocoll_messages/device_log_response.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/logout_message.dart';
|
import 'package:stadtbote/protocoll_messages/logout_message.dart';
|
||||||
import 'package:stadtbote/tools/message_service.dart';
|
import 'package:stadtbote/tools/message_service.dart';
|
||||||
import 'package:stadtbote/tools/messages/job_deleted_message.dart';
|
import 'package:stadtbote/tools/messages/job_deleted_message.dart';
|
||||||
import 'package:stadtbote/tools/messages/job_received_message.dart';
|
import 'package:stadtbote/tools/messages/job_received_message.dart';
|
||||||
import 'package:stadtbote/tools/messages/message_message.dart';
|
import 'package:stadtbote/tools/messages/message_message.dart';
|
||||||
import 'package:stadtbote/tools/messages/refresh_badges_message.dart';
|
|
||||||
import 'package:stadtbote/tools/messages/session_info_update.dart';
|
import 'package:stadtbote/tools/messages/session_info_update.dart';
|
||||||
import 'package:badges/badges.dart' as badges;
|
import 'package:badges/badges.dart' as badges;
|
||||||
import 'package:stadtbote/tools/messages/status_info_update.dart';
|
import 'package:stadtbote/tools/messages/status_info_update.dart';
|
||||||
|
import 'package:stadtbote/tools/messages/update_badges_message.dart';
|
||||||
import 'package:stadtbote/tools/mqtt_core.dart';
|
import 'package:stadtbote/tools/mqtt_core.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
@@ -30,8 +33,8 @@ import '../tools/constants.dart';
|
|||||||
import '../tools/util.dart';
|
import '../tools/util.dart';
|
||||||
|
|
||||||
class MainPage extends ContentViewWidget {
|
class MainPage extends ContentViewWidget {
|
||||||
final ValueNotifier<String> _zipValueNotifier = ValueNotifier("----");
|
final ValueNotifier<String> _zipValueNotifier = ValueNotifier("-----");
|
||||||
final ValueNotifier<String> sidValueNotifier = ValueNotifier("----");
|
final ValueNotifier<String> sidValueNotifier = ValueNotifier("-----");
|
||||||
|
|
||||||
MainPage({super.key});
|
MainPage({super.key});
|
||||||
|
|
||||||
@@ -233,7 +236,13 @@ class _MainPageState extends State<MainPage> {
|
|||||||
getDefaultButton(
|
getDefaultButton(
|
||||||
_loggedOut ? 'Anmelden' : 'Abmelden',
|
_loggedOut ? 'Anmelden' : 'Abmelden',
|
||||||
image: Image.asset(_loggedOut ? 'assets/anmelden.png' : 'assets/abmelden.png', width: 30, height: 30),
|
image: Image.asset(_loggedOut ? 'assets/anmelden.png' : 'assets/abmelden.png', width: 30, height: 30),
|
||||||
() async => {_logout()}),
|
() async {
|
||||||
|
if (!kDebugMode) {
|
||||||
|
_logout(context);
|
||||||
|
} else {
|
||||||
|
_test();
|
||||||
|
}
|
||||||
|
}),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -278,7 +287,7 @@ class _MainPageState extends State<MainPage> {
|
|||||||
_refreshBadges();
|
_refreshBadges();
|
||||||
});
|
});
|
||||||
|
|
||||||
MessageService().subscribe<RefreshBadgesMessage>(Constants.messageTopicRefreshBadges, this, (RefreshBadgesMessage refreshMessage) {
|
MessageService().subscribe<UpdateBadgesMessage>(Constants.messageTopicUpdateBadges, this, (UpdateBadgesMessage message) {
|
||||||
_refreshBadges();
|
_refreshBadges();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -312,20 +321,58 @@ class _MainPageState extends State<MainPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_logout() {
|
_logout(context) {
|
||||||
if (!_loggedOut) {
|
if (!_loggedOut) {
|
||||||
_sendLogoutMessage();
|
showLogoutAlertDialog(context);
|
||||||
|
|
||||||
Future.delayed(const Duration(seconds: 1), () async {
|
|
||||||
MqttCore.instance.diconnect();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
MqttCore.setup();
|
MqttCore.setup();
|
||||||
|
|
||||||
|
_loggedOut = false;
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_loggedOut = !_loggedOut;
|
showLogoutAlertDialog(BuildContext context) {
|
||||||
|
Widget yesButton = TextButton(
|
||||||
|
child: const Text("Ja"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
_sendLogoutMessage();
|
||||||
|
|
||||||
setState(() {});
|
Future.delayed(const Duration(seconds: 1), () async {
|
||||||
|
MqttCore.instance.diconnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
_loggedOut = true;
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget noButton = TextButton(
|
||||||
|
child: const Text("Nein"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// set up the AlertDialog
|
||||||
|
AlertDialog alert = AlertDialog(
|
||||||
|
title: const Text("Warnung"),
|
||||||
|
content: const Text("Wollen Sie sich wirklich abmelden?"),
|
||||||
|
actions: [
|
||||||
|
yesButton, noButton,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
// show the dialog
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return alert;
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_sendLogoutMessage() {
|
_sendLogoutMessage() {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:stadtbote/content_views/utils/content_view_widget.dart';
|
|||||||
import 'package:stadtbote/content_views/utils/header_info.dart';
|
import 'package:stadtbote/content_views/utils/header_info.dart';
|
||||||
import 'package:stadtbote/main.dart';
|
import 'package:stadtbote/main.dart';
|
||||||
import 'package:stadtbote/model/message.dart' as sbmessage;
|
import 'package:stadtbote/model/message.dart' as sbmessage;
|
||||||
|
import 'package:stadtbote/model/message.dart';
|
||||||
import 'package:stadtbote/model/session_status.dart';
|
import 'package:stadtbote/model/session_status.dart';
|
||||||
import 'package:stadtbote/tools/mqtt_core.dart';
|
import 'package:stadtbote/tools/mqtt_core.dart';
|
||||||
|
|
||||||
@@ -95,16 +96,17 @@ class _MessagesPageState extends State<MessagesPage> {
|
|||||||
void _handleSendPressed(types.PartialText text) async {
|
void _handleSendPressed(types.PartialText text) async {
|
||||||
var now = DateTime.now();
|
var now = DateTime.now();
|
||||||
|
|
||||||
var message = sbmessage.Message();
|
var message = MessageMessage();
|
||||||
message.text = [text.text];
|
message.mssg = sbmessage.Message();
|
||||||
message.from = _sid;
|
message.mssg.text = [text.text];
|
||||||
message.subj = '';
|
message.mssg.from = _sid;
|
||||||
message.time = now.toIso8601String();
|
message.mssg.subj = '';
|
||||||
message.read = true;
|
message.mssg.time = now.toUtc().toIso8601String();
|
||||||
message.id = await sbmessage.Message.getNextId();
|
message.mssg.read = true;
|
||||||
|
message.mssg.id = await sbmessage.Message.getNextId();
|
||||||
|
|
||||||
MyApp.isarInstance.writeTxnSync(() {
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
MyApp.isarInstance.messages.putSync(message);
|
await MyApp.isarInstance.messages.put(message.mssg);
|
||||||
});
|
});
|
||||||
|
|
||||||
var json = jsonEncode(message.toJson());
|
var json = jsonEncode(message.toJson());
|
||||||
@@ -114,7 +116,7 @@ class _MessagesPageState extends State<MessagesPage> {
|
|||||||
_messages.insert(0, types.TextMessage(
|
_messages.insert(0, types.TextMessage(
|
||||||
author: _user,
|
author: _user,
|
||||||
createdAt: now.millisecondsSinceEpoch,
|
createdAt: now.millisecondsSinceEpoch,
|
||||||
id: message.id.toString(),
|
id: message.mssg.id.toString(),
|
||||||
text: text.text,
|
text: text.text,
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -132,18 +134,18 @@ class _MessagesPageState extends State<MessagesPage> {
|
|||||||
}
|
}
|
||||||
text = text.trim();
|
text = text.trim();
|
||||||
|
|
||||||
_messages.insert(0, types.TextMessage(
|
_messages.add(types.TextMessage(
|
||||||
author: message.from == _sid ? _user : _central,
|
author: message.from == _sid ? _user : _central,
|
||||||
createdAt: DateTime
|
createdAt: DateTime.parse(message.time).toLocal().millisecondsSinceEpoch,
|
||||||
.parse(message.time)
|
|
||||||
.millisecondsSinceEpoch,
|
|
||||||
id: message.id.toString(),
|
id: message.id.toString(),
|
||||||
text: text,
|
text: text,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
_messages.sort((a, b) => b.createdAt! > a.createdAt! ? 1 : 0);
|
||||||
|
|
||||||
message.read = true;
|
message.read = true;
|
||||||
MyApp.isarInstance.writeTxnSync(() {
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
MyApp.isarInstance.messages.putSync(message);
|
await MyApp.isarInstance.messages.put(message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +183,8 @@ class _MessagesPageState extends State<MessagesPage> {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: getDefaultButton('Ja', () => {
|
child: getDefaultButton('Ja', () async => {
|
||||||
MyApp.isarInstance.writeTxnSync(() => {MyApp.isarInstance.messages.deleteSync(int.parse(message.id))}),
|
await MyApp.isarInstance.writeTxnSync(() async => { await MyApp.isarInstance.messages.delete(int.parse(message.id))}),
|
||||||
|
|
||||||
_fetchMessages(),
|
_fetchMessages(),
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import 'package:stadtbote/popups/tasks_popups/take_photos_popup.dart';
|
|||||||
import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
|
import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
|
import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/fin_tour_message.dart';
|
import 'package:stadtbote/protocoll_messages/fin_tour_message.dart';
|
||||||
|
import 'package:stadtbote/protocoll_messages/pic_message.dart';
|
||||||
import 'package:stadtbote/tools/constants.dart';
|
import 'package:stadtbote/tools/constants.dart';
|
||||||
import 'package:stadtbote/tools/message_service.dart';
|
import 'package:stadtbote/tools/message_service.dart';
|
||||||
import 'package:stadtbote/tools/mqtt_core.dart';
|
import 'package:stadtbote/tools/mqtt_core.dart';
|
||||||
@@ -64,11 +65,17 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
|
|
||||||
late List<TaskInfo> _taskList;
|
late List<TaskInfo> _taskList;
|
||||||
|
|
||||||
|
List<Uint8List> _photos = [];
|
||||||
|
|
||||||
|
late String _commisionNumber;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
Future.delayed(const Duration(seconds: 0), () async {
|
Future.delayed(const Duration(seconds: 0), () async {
|
||||||
_taskList = await _fetchTaskList();
|
_taskList = await _fetchTaskList();
|
||||||
|
|
||||||
|
_commisionNumber = widget.tour.com ?? "";
|
||||||
|
|
||||||
_initCompleted = true;
|
_initCompleted = true;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@@ -93,8 +100,21 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
child: AbsorbPointer(
|
child: AbsorbPointer(
|
||||||
absorbing: widget.readOnly,
|
absorbing: widget.readOnly,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: steps,
|
Visibility(
|
||||||
|
visible: _commisionNumber.length > 0,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text('Komm-#: $_commisionNumber', style: const TextStyle(fontSize: 20), textAlign: TextAlign.left),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: steps,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -125,7 +145,7 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
left: 16.5,
|
left: 16.5,
|
||||||
top: i == 0 ? 40 : 40,
|
top: i == 0 ? 40 : 40,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: i == widget.tour.tasks!.length - 1 ? 0 : 20,
|
height: i == widget.tour.tasks.length - 1 ? 0 : 20,
|
||||||
width: 6,
|
width: 6,
|
||||||
color: isTaskActive(i) ? Constants.colorPrimary : Constants.colorPrimaryOpaque,
|
color: isTaskActive(i) ? Constants.colorPrimary : Constants.colorPrimaryOpaque,
|
||||||
),
|
),
|
||||||
@@ -159,12 +179,16 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
Text(
|
SizedBox(
|
||||||
taskInfo.additionalText ?? '',
|
width: MediaQuery.of(context).size.width * 0.7,
|
||||||
textAlign: TextAlign.left,
|
child: Text(
|
||||||
style: TextStyle(
|
taskInfo.additionalText ?? '',
|
||||||
color: textColor,
|
textAlign: TextAlign.left,
|
||||||
fontSize: 12.0,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: textColor,
|
||||||
|
fontSize: 12.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -187,7 +211,7 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
Future<List<TaskInfo>> _fetchTaskList() async {
|
Future<List<TaskInfo>> _fetchTaskList() async {
|
||||||
List<TaskInfo> taskList = [];
|
List<TaskInfo> taskList = [];
|
||||||
|
|
||||||
for(var task in widget.tour.tasks!) {
|
for(var task in widget.tour.tasks) {
|
||||||
var taskInfo = await MyApp.isarInstance.taskInfos.filter().sIdEqualTo(task.sId).findFirst();
|
var taskInfo = await MyApp.isarInstance.taskInfos.filter().sIdEqualTo(task.sId).findFirst();
|
||||||
if (taskInfo == null) {
|
if (taskInfo == null) {
|
||||||
taskInfo = TaskInfo();
|
taskInfo = TaskInfo();
|
||||||
@@ -268,6 +292,8 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
taskInfo.additionalText = comissionNumber;
|
taskInfo.additionalText = comissionNumber;
|
||||||
taskInfo.completed = true;
|
taskInfo.completed = true;
|
||||||
|
|
||||||
|
_commisionNumber = comissionNumber;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
_finishTaskProcessing(taskInfo);
|
||||||
@@ -282,6 +308,7 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
answer.codes!.add(barcode);
|
answer.codes!.add(barcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taskInfo.answer = jsonEncode(answer.toJson());
|
||||||
taskInfo.additionalText = "Barcodes gescannt";
|
taskInfo.additionalText = "Barcodes gescannt";
|
||||||
taskInfo.completed = true;
|
taskInfo.completed = true;
|
||||||
|
|
||||||
@@ -292,13 +319,17 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_processTakePhotos(TaskInfo taskInfo) {
|
_processTakePhotos(TaskInfo taskInfo) {
|
||||||
showTakePhotosPopup(context, taskInfo, () {
|
showTakePhotosPopup(context, taskInfo, (List<Uint8List>? photos) {
|
||||||
taskInfo.additionalText = "Fotos aufgenommen";
|
if (photos != null) {
|
||||||
taskInfo.completed = true;
|
_photos = photos;
|
||||||
|
|
||||||
setState(() {});
|
taskInfo.additionalText = "Fotos aufgenommen";
|
||||||
|
taskInfo.completed = true;
|
||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
setState(() {});
|
||||||
|
|
||||||
|
_finishTaskProcessing(taskInfo);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,6 +339,7 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
answer.val = notice;
|
answer.val = notice;
|
||||||
|
|
||||||
taskInfo.answer = jsonEncode(answer.toJson());
|
taskInfo.answer = jsonEncode(answer.toJson());
|
||||||
|
taskInfo.additionalText = notice;
|
||||||
taskInfo.completed = true;
|
taskInfo.completed = true;
|
||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
_finishTaskProcessing(taskInfo);
|
||||||
@@ -349,23 +381,29 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _processSignature(TaskInfo taskInfo) {
|
void _processSignature(TaskInfo taskInfo) {
|
||||||
|
MyApp.suppressAcceptDialog = true;
|
||||||
|
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
|
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
|
||||||
|
|
||||||
Future.delayed(const Duration(seconds: 1), () async {
|
Future.delayed(const Duration(seconds: 1), () async {
|
||||||
showSignaturePopup(context, taskInfo, () {
|
showSignaturePopup(context, taskInfo, (String? signature) {
|
||||||
var answer = _createAnswerHeader(taskInfo);
|
MyApp.suppressAcceptDialog = false;
|
||||||
answer.sign = 'A110';
|
|
||||||
|
|
||||||
taskInfo.answer = jsonEncode(answer.toJson());
|
|
||||||
taskInfo.completed = true;
|
|
||||||
|
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||||
|
|
||||||
_sendFinTourMessage();
|
if (signature != null) {
|
||||||
|
var answer = _createAnswerHeader(taskInfo);
|
||||||
|
answer.sign = signature;
|
||||||
|
|
||||||
_finishTaskProcessing(taskInfo);
|
taskInfo.answer = jsonEncode(answer.toJson());
|
||||||
|
taskInfo.completed = true;
|
||||||
|
|
||||||
MessageService().publish<PopContentViewMessage>(Constants.messageTopicPopContentView, arguments: PopContentViewMessage(count: 2));
|
_sendFinTourMessage();
|
||||||
|
|
||||||
|
_finishTaskProcessing(taskInfo);
|
||||||
|
|
||||||
|
MessageService().publish<PopContentViewMessage>(Constants.messageTopicPopContentView, arguments: PopContentViewMessage(count: 2));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -407,7 +445,7 @@ class _TaskListPageState extends State<TaskListPage> {
|
|||||||
message.task.pos!.long = position.longitude;
|
message.task.pos!.long = position.longitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttCore.instance.publishText("fin_task", jsonEncode(message.toJson()));
|
MqttCore.instance.publishPayloadMessage("job", finTaskMessage.toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
FinTourTask _createAnswerHeader(TaskInfo taskInfo) {
|
FinTourTask _createAnswerHeader(TaskInfo taskInfo) {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class _TourListPageState extends State<TourListPage> {
|
|||||||
return Util.getWaitWidget(context);
|
return Util.getWaitWidget(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
late List<Widget> jobWidgets = _createjobWidgets();
|
late List<Widget> jobWidgets = _createTourWidgets();
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(18.0),
|
padding: const EdgeInsets.all(18.0),
|
||||||
@@ -124,14 +124,26 @@ class _TourListPageState extends State<TourListPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _createjobWidgets() {
|
List<Widget> _createTourWidgets() {
|
||||||
List<Widget> jobWidgets = [];
|
List<Widget> tourWidgets = [];
|
||||||
|
|
||||||
|
JobTour? lastTour;
|
||||||
|
|
||||||
for (var tour in _tours) {
|
for (var tour in _tours) {
|
||||||
|
bool tourActive = false;
|
||||||
|
|
||||||
|
if (lastTour == null) {
|
||||||
|
tourActive = true;
|
||||||
|
} else {
|
||||||
|
if (lastTour.state != 0) {
|
||||||
|
tourActive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Color color = Colors.transparent;
|
Color color = Colors.transparent;
|
||||||
switch (tour.state) {
|
switch (tour.state) {
|
||||||
case 0:
|
case 0:
|
||||||
color = Colors.white;
|
color = tourActive ? Colors.white : Colors.grey;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@@ -143,11 +155,17 @@ class _TourListPageState extends State<TourListPage> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
jobWidgets.add(
|
lastTour = tour;
|
||||||
|
|
||||||
|
tourWidgets.add(
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.all(0),
|
contentPadding: const EdgeInsets.all(0),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_clicked(tour);
|
if (tourActive) {
|
||||||
|
_clicked(tour, false);
|
||||||
|
} else {
|
||||||
|
_clicked(tour, true);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
title: Container(
|
title: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -179,11 +197,10 @@ class _TourListPageState extends State<TourListPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return jobWidgets;
|
return tourWidgets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _clicked(JobTour tour) {
|
void _clicked(JobTour tour, bool readOnly) {
|
||||||
MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView,
|
MessageService().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourDetailsPage(job: widget.job, tour: tour, readOnly: readOnly));
|
||||||
arguments: TourDetailsPage(job: widget.job, tour: tour, readOnly: tour.state != 0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,10 @@ import 'package:geolocator/geolocator.dart';
|
|||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:stadtbote/messages/pop_content_view_message.dart';
|
import 'package:stadtbote/messages/pop_content_view_message.dart';
|
||||||
|
import 'package:stadtbote/model/enqueued_message.dart';
|
||||||
|
import 'package:stadtbote/model/log_entry.dart';
|
||||||
import 'package:stadtbote/model/message.dart';
|
import 'package:stadtbote/model/message.dart';
|
||||||
import 'package:stadtbote/model/rank.dart';
|
import 'package:stadtbote/model/ranking.dart';
|
||||||
import 'package:stadtbote/model/status.dart';
|
import 'package:stadtbote/model/status.dart';
|
||||||
import 'package:stadtbote/model/task_info.dart';
|
import 'package:stadtbote/model/task_info.dart';
|
||||||
import 'package:stadtbote/popups/accept_jobs_popup.dart';
|
import 'package:stadtbote/popups/accept_jobs_popup.dart';
|
||||||
@@ -15,8 +17,9 @@ import 'package:stadtbote/model/session_status.dart';
|
|||||||
import 'package:stadtbote/tools/connection_status.dart';
|
import 'package:stadtbote/tools/connection_status.dart';
|
||||||
import 'package:stadtbote/tools/message_service.dart';
|
import 'package:stadtbote/tools/message_service.dart';
|
||||||
import 'package:stadtbote/tools/messages/job_received_message.dart';
|
import 'package:stadtbote/tools/messages/job_received_message.dart';
|
||||||
|
import 'package:stadtbote/tools/messages/update_badges_message.dart';
|
||||||
|
import 'package:stadtbote/tools/mqtt_core.dart';
|
||||||
|
|
||||||
import 'tools/mqtt_core.dart';
|
|
||||||
import 'content_views/main_page.dart';
|
import 'content_views/main_page.dart';
|
||||||
import 'content_views/utils/content_view_widget.dart';
|
import 'content_views/utils/content_view_widget.dart';
|
||||||
import 'content_views/utils/widget_stack.dart';
|
import 'content_views/utils/widget_stack.dart';
|
||||||
@@ -34,7 +37,9 @@ Future<void> main() async {
|
|||||||
JobSchema,
|
JobSchema,
|
||||||
TaskInfoSchema,
|
TaskInfoSchema,
|
||||||
MessageSchema,
|
MessageSchema,
|
||||||
RankSchema
|
RankingSchema,
|
||||||
|
EnqueuedMessageSchema,
|
||||||
|
LogEntrySchema
|
||||||
], directory: dir.path);
|
], directory: dir.path);
|
||||||
|
|
||||||
runZonedGuarded(() {}, (error, stackTrace) {
|
runZonedGuarded(() {}, (error, stackTrace) {
|
||||||
@@ -60,6 +65,8 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
static Position? currentPosition;
|
static Position? currentPosition;
|
||||||
|
|
||||||
|
static bool suppressAcceptDialog = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
@@ -149,6 +156,8 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
|
|||||||
late AnimationController _animationController;
|
late AnimationController _animationController;
|
||||||
late Animation<double> _animation;
|
late Animation<double> _animation;
|
||||||
|
|
||||||
|
bool _dialogOpened = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -417,8 +426,18 @@ class _MainState extends State<Main> with SingleTickerProviderStateMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _jobReceived(Job job) async {
|
void _jobReceived(Job job) async {
|
||||||
if (job.state == 0) {
|
if (!MyApp.suppressAcceptDialog) {
|
||||||
await showAcceptJobsPopup(context, await MyApp.isarInstance.jobs.filter().stateEqualTo(0).findAll());
|
if (job.state == 0) {
|
||||||
|
if (!_dialogOpened) {
|
||||||
|
_dialogOpened = true;
|
||||||
|
|
||||||
|
await showAcceptJobsPopup(context, await MyApp.isarInstance.jobs.filter().stateEqualTo(0).findAll(), () {
|
||||||
|
_dialogOpened = false;
|
||||||
|
|
||||||
|
MessageService().publish(Constants.messageTopicUpdateBadges, arguments: UpdateBadgesMessage());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
|
part 'enqueued_message.g.dart';
|
||||||
|
|
||||||
|
@collection
|
||||||
|
class EnqueuedMessage {
|
||||||
|
Id id = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
|
||||||
|
late String topic;
|
||||||
|
|
||||||
|
late String payload;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,631 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'enqueued_message.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// IsarCollectionGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||||
|
|
||||||
|
extension GetEnqueuedMessageCollection on Isar {
|
||||||
|
IsarCollection<EnqueuedMessage> get enqueuedMessages => this.collection();
|
||||||
|
}
|
||||||
|
|
||||||
|
const EnqueuedMessageSchema = CollectionSchema(
|
||||||
|
name: r'EnqueuedMessage',
|
||||||
|
id: 884922652682878785,
|
||||||
|
properties: {
|
||||||
|
r'payload': PropertySchema(
|
||||||
|
id: 0,
|
||||||
|
name: r'payload',
|
||||||
|
type: IsarType.string,
|
||||||
|
),
|
||||||
|
r'topic': PropertySchema(
|
||||||
|
id: 1,
|
||||||
|
name: r'topic',
|
||||||
|
type: IsarType.string,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
estimateSize: _enqueuedMessageEstimateSize,
|
||||||
|
serialize: _enqueuedMessageSerialize,
|
||||||
|
deserialize: _enqueuedMessageDeserialize,
|
||||||
|
deserializeProp: _enqueuedMessageDeserializeProp,
|
||||||
|
idName: r'id',
|
||||||
|
indexes: {},
|
||||||
|
links: {},
|
||||||
|
embeddedSchemas: {},
|
||||||
|
getId: _enqueuedMessageGetId,
|
||||||
|
getLinks: _enqueuedMessageGetLinks,
|
||||||
|
attach: _enqueuedMessageAttach,
|
||||||
|
version: '3.1.0+1',
|
||||||
|
);
|
||||||
|
|
||||||
|
int _enqueuedMessageEstimateSize(
|
||||||
|
EnqueuedMessage object,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
var bytesCount = offsets.last;
|
||||||
|
bytesCount += 3 + object.payload.length * 3;
|
||||||
|
bytesCount += 3 + object.topic.length * 3;
|
||||||
|
return bytesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _enqueuedMessageSerialize(
|
||||||
|
EnqueuedMessage object,
|
||||||
|
IsarWriter writer,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
writer.writeString(offsets[0], object.payload);
|
||||||
|
writer.writeString(offsets[1], object.topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnqueuedMessage _enqueuedMessageDeserialize(
|
||||||
|
Id id,
|
||||||
|
IsarReader reader,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
final object = EnqueuedMessage();
|
||||||
|
object.id = id;
|
||||||
|
object.payload = reader.readString(offsets[0]);
|
||||||
|
object.topic = reader.readString(offsets[1]);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
P _enqueuedMessageDeserializeProp<P>(
|
||||||
|
IsarReader reader,
|
||||||
|
int propertyId,
|
||||||
|
int offset,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
switch (propertyId) {
|
||||||
|
case 0:
|
||||||
|
return (reader.readString(offset)) as P;
|
||||||
|
case 1:
|
||||||
|
return (reader.readString(offset)) as P;
|
||||||
|
default:
|
||||||
|
throw IsarError('Unknown property with id $propertyId');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Id _enqueuedMessageGetId(EnqueuedMessage object) {
|
||||||
|
return object.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IsarLinkBase<dynamic>> _enqueuedMessageGetLinks(EnqueuedMessage object) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _enqueuedMessageAttach(
|
||||||
|
IsarCollection<dynamic> col, Id id, EnqueuedMessage object) {
|
||||||
|
object.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQueryWhereSort
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QWhere> {
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterWhere> anyId() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(const IdWhereClause.any());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQueryWhere
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QWhereClause> {
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterWhereClause> idEqualTo(
|
||||||
|
Id id) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(IdWhereClause.between(
|
||||||
|
lower: id,
|
||||||
|
upper: id,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterWhereClause>
|
||||||
|
idNotEqualTo(Id id) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
if (query.whereSort == Sort.asc) {
|
||||||
|
return query
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: id, includeUpper: false),
|
||||||
|
)
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: id, includeLower: false),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return query
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: id, includeLower: false),
|
||||||
|
)
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: id, includeUpper: false),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterWhereClause>
|
||||||
|
idGreaterThan(Id id, {bool include = false}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: id, includeLower: include),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterWhereClause> idLessThan(
|
||||||
|
Id id,
|
||||||
|
{bool include = false}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: id, includeUpper: include),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterWhereClause> idBetween(
|
||||||
|
Id lowerId,
|
||||||
|
Id upperId, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(IdWhereClause.between(
|
||||||
|
lower: lowerId,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upperId,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQueryFilter
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QFilterCondition> {
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
idEqualTo(Id value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
idGreaterThan(
|
||||||
|
Id value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
idLessThan(
|
||||||
|
Id value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
idBetween(
|
||||||
|
Id lower,
|
||||||
|
Id upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'id',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadEqualTo(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'payload',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadGreaterThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'payload',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadLessThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'payload',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadBetween(
|
||||||
|
String lower,
|
||||||
|
String upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'payload',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadStartsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.startsWith(
|
||||||
|
property: r'payload',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadEndsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.endsWith(
|
||||||
|
property: r'payload',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadContains(String value, {bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.contains(
|
||||||
|
property: r'payload',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadMatches(String pattern, {bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.matches(
|
||||||
|
property: r'payload',
|
||||||
|
wildcard: pattern,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadIsEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'payload',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
payloadIsNotEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
property: r'payload',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicEqualTo(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'topic',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicGreaterThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'topic',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicLessThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'topic',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicBetween(
|
||||||
|
String lower,
|
||||||
|
String upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'topic',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicStartsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.startsWith(
|
||||||
|
property: r'topic',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicEndsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.endsWith(
|
||||||
|
property: r'topic',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicContains(String value, {bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.contains(
|
||||||
|
property: r'topic',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicMatches(String pattern, {bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.matches(
|
||||||
|
property: r'topic',
|
||||||
|
wildcard: pattern,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicIsEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'topic',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterFilterCondition>
|
||||||
|
topicIsNotEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
property: r'topic',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQueryObject
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QFilterCondition> {}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQueryLinks
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QFilterCondition> {}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQuerySortBy
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QSortBy> {
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy> sortByPayload() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'payload', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy>
|
||||||
|
sortByPayloadDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'payload', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy> sortByTopic() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'topic', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy>
|
||||||
|
sortByTopicDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'topic', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQuerySortThenBy
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QSortThenBy> {
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy> thenById() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'id', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy> thenByIdDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'id', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy> thenByPayload() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'payload', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy>
|
||||||
|
thenByPayloadDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'payload', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy> thenByTopic() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'topic', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QAfterSortBy>
|
||||||
|
thenByTopicDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'topic', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQueryWhereDistinct
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QDistinct> {
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QDistinct> distinctByPayload(
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'payload', caseSensitive: caseSensitive);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, EnqueuedMessage, QDistinct> distinctByTopic(
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'topic', caseSensitive: caseSensitive);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnqueuedMessageQueryProperty
|
||||||
|
on QueryBuilder<EnqueuedMessage, EnqueuedMessage, QQueryProperty> {
|
||||||
|
QueryBuilder<EnqueuedMessage, int, QQueryOperations> idProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, String, QQueryOperations> payloadProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'payload');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EnqueuedMessage, String, QQueryOperations> topicProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'topic');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,10 +14,10 @@ class JobTour {
|
|||||||
late String mode;
|
late String mode;
|
||||||
late String comp;
|
late String comp;
|
||||||
late String person;
|
late String person;
|
||||||
late String phone;
|
late String? phone;
|
||||||
late String street;
|
late String street;
|
||||||
late String city;
|
late String city;
|
||||||
late String com;
|
late String? com;
|
||||||
late TourPosition? pos;
|
late TourPosition? pos;
|
||||||
late String rem;
|
late String rem;
|
||||||
late List<TourTask>? tasks;
|
late List<TourTask>? tasks;
|
||||||
|
|||||||
@@ -94,11 +94,21 @@ int _jobTourEstimateSize(
|
|||||||
) {
|
) {
|
||||||
var bytesCount = offsets.last;
|
var bytesCount = offsets.last;
|
||||||
bytesCount += 3 + object.city.length * 3;
|
bytesCount += 3 + object.city.length * 3;
|
||||||
bytesCount += 3 + object.com.length * 3;
|
{
|
||||||
|
final value = object.com;
|
||||||
|
if (value != null) {
|
||||||
|
bytesCount += 3 + value.length * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
bytesCount += 3 + object.comp.length * 3;
|
bytesCount += 3 + object.comp.length * 3;
|
||||||
bytesCount += 3 + object.mode.length * 3;
|
bytesCount += 3 + object.mode.length * 3;
|
||||||
bytesCount += 3 + object.person.length * 3;
|
bytesCount += 3 + object.person.length * 3;
|
||||||
bytesCount += 3 + object.phone.length * 3;
|
{
|
||||||
|
final value = object.phone;
|
||||||
|
if (value != null) {
|
||||||
|
bytesCount += 3 + value.length * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
{
|
{
|
||||||
final value = object.pos;
|
final value = object.pos;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
@@ -164,12 +174,12 @@ JobTour _jobTourDeserialize(
|
|||||||
) {
|
) {
|
||||||
final object = JobTour();
|
final object = JobTour();
|
||||||
object.city = reader.readString(offsets[0]);
|
object.city = reader.readString(offsets[0]);
|
||||||
object.com = reader.readString(offsets[1]);
|
object.com = reader.readStringOrNull(offsets[1]);
|
||||||
object.comp = reader.readString(offsets[2]);
|
object.comp = reader.readString(offsets[2]);
|
||||||
object.id = reader.readLong(offsets[3]);
|
object.id = reader.readLong(offsets[3]);
|
||||||
object.mode = reader.readString(offsets[4]);
|
object.mode = reader.readString(offsets[4]);
|
||||||
object.person = reader.readString(offsets[5]);
|
object.person = reader.readString(offsets[5]);
|
||||||
object.phone = reader.readString(offsets[6]);
|
object.phone = reader.readStringOrNull(offsets[6]);
|
||||||
object.pos = reader.readObjectOrNull<TourPosition>(
|
object.pos = reader.readObjectOrNull<TourPosition>(
|
||||||
offsets[7],
|
offsets[7],
|
||||||
TourPositionSchema.deserialize,
|
TourPositionSchema.deserialize,
|
||||||
@@ -198,7 +208,7 @@ P _jobTourDeserializeProp<P>(
|
|||||||
case 0:
|
case 0:
|
||||||
return (reader.readString(offset)) as P;
|
return (reader.readString(offset)) as P;
|
||||||
case 1:
|
case 1:
|
||||||
return (reader.readString(offset)) as P;
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
case 2:
|
case 2:
|
||||||
return (reader.readString(offset)) as P;
|
return (reader.readString(offset)) as P;
|
||||||
case 3:
|
case 3:
|
||||||
@@ -208,7 +218,7 @@ P _jobTourDeserializeProp<P>(
|
|||||||
case 5:
|
case 5:
|
||||||
return (reader.readString(offset)) as P;
|
return (reader.readString(offset)) as P;
|
||||||
case 6:
|
case 6:
|
||||||
return (reader.readString(offset)) as P;
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
case 7:
|
case 7:
|
||||||
return (reader.readObjectOrNull<TourPosition>(
|
return (reader.readObjectOrNull<TourPosition>(
|
||||||
offset,
|
offset,
|
||||||
@@ -367,8 +377,24 @@ extension JobTourQueryFilter
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comIsNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
property: r'com',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comIsNotNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||||
|
property: r'com',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comEqualTo(
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comEqualTo(
|
||||||
String value, {
|
String? value, {
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
}) {
|
}) {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
@@ -381,7 +407,7 @@ extension JobTourQueryFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comGreaterThan(
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comGreaterThan(
|
||||||
String value, {
|
String? value, {
|
||||||
bool include = false,
|
bool include = false,
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
}) {
|
}) {
|
||||||
@@ -396,7 +422,7 @@ extension JobTourQueryFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comLessThan(
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comLessThan(
|
||||||
String value, {
|
String? value, {
|
||||||
bool include = false,
|
bool include = false,
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
}) {
|
}) {
|
||||||
@@ -411,8 +437,8 @@ extension JobTourQueryFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comBetween(
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> comBetween(
|
||||||
String lower,
|
String? lower,
|
||||||
String upper, {
|
String? upper, {
|
||||||
bool includeLower = true,
|
bool includeLower = true,
|
||||||
bool includeUpper = true,
|
bool includeUpper = true,
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
@@ -939,8 +965,24 @@ extension JobTourQueryFilter
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneIsNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
property: r'phone',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneIsNotNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||||
|
property: r'phone',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneEqualTo(
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneEqualTo(
|
||||||
String value, {
|
String? value, {
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
}) {
|
}) {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
@@ -953,7 +995,7 @@ extension JobTourQueryFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneGreaterThan(
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneGreaterThan(
|
||||||
String value, {
|
String? value, {
|
||||||
bool include = false,
|
bool include = false,
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
}) {
|
}) {
|
||||||
@@ -968,7 +1010,7 @@ extension JobTourQueryFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneLessThan(
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneLessThan(
|
||||||
String value, {
|
String? value, {
|
||||||
bool include = false,
|
bool include = false,
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
}) {
|
}) {
|
||||||
@@ -983,8 +1025,8 @@ extension JobTourQueryFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneBetween(
|
QueryBuilder<JobTour, JobTour, QAfterFilterCondition> phoneBetween(
|
||||||
String lower,
|
String? lower,
|
||||||
String upper, {
|
String? upper, {
|
||||||
bool includeLower = true,
|
bool includeLower = true,
|
||||||
bool includeUpper = true,
|
bool includeUpper = true,
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
@@ -1579,10 +1621,10 @@ JobTour _$JobTourFromJson(Map<String, dynamic> json) => JobTour()
|
|||||||
..mode = json['mode'] as String
|
..mode = json['mode'] as String
|
||||||
..comp = json['comp'] as String
|
..comp = json['comp'] as String
|
||||||
..person = json['person'] as String
|
..person = json['person'] as String
|
||||||
..phone = json['phone'] as String
|
..phone = json['phone'] as String?
|
||||||
..street = json['street'] as String
|
..street = json['street'] as String
|
||||||
..city = json['city'] as String
|
..city = json['city'] as String
|
||||||
..com = json['com'] as String
|
..com = json['com'] as String?
|
||||||
..pos = json['pos'] == null
|
..pos = json['pos'] == null
|
||||||
? null
|
? null
|
||||||
: TourPosition.fromJson(json['pos'] as Map<String, dynamic>)
|
: TourPosition.fromJson(json['pos'] as Map<String, dynamic>)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'log_entry.g.dart';
|
||||||
|
|
||||||
|
enum LogEntrySeverityEnum {
|
||||||
|
info,
|
||||||
|
debug,
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
@collection
|
||||||
|
@JsonSerializable()
|
||||||
|
class LogEntry {
|
||||||
|
late Id id = Isar.autoIncrement;
|
||||||
|
|
||||||
|
late DateTime time;
|
||||||
|
|
||||||
|
@enumerated
|
||||||
|
late LogEntrySeverityEnum severity;
|
||||||
|
|
||||||
|
late String text;
|
||||||
|
|
||||||
|
LogEntry();
|
||||||
|
|
||||||
|
factory LogEntry.fromJson(Map<String, dynamic> json) => _$LogEntryFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$LogEntryToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,662 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'log_entry.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// IsarCollectionGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||||
|
|
||||||
|
extension GetLogEntryCollection on Isar {
|
||||||
|
IsarCollection<LogEntry> get logEntrys => this.collection();
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogEntrySchema = CollectionSchema(
|
||||||
|
name: r'LogEntry',
|
||||||
|
id: -8268688274231935295,
|
||||||
|
properties: {
|
||||||
|
r'severity': PropertySchema(
|
||||||
|
id: 0,
|
||||||
|
name: r'severity',
|
||||||
|
type: IsarType.byte,
|
||||||
|
enumMap: _LogEntryseverityEnumValueMap,
|
||||||
|
),
|
||||||
|
r'text': PropertySchema(
|
||||||
|
id: 1,
|
||||||
|
name: r'text',
|
||||||
|
type: IsarType.string,
|
||||||
|
),
|
||||||
|
r'time': PropertySchema(
|
||||||
|
id: 2,
|
||||||
|
name: r'time',
|
||||||
|
type: IsarType.dateTime,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
estimateSize: _logEntryEstimateSize,
|
||||||
|
serialize: _logEntrySerialize,
|
||||||
|
deserialize: _logEntryDeserialize,
|
||||||
|
deserializeProp: _logEntryDeserializeProp,
|
||||||
|
idName: r'id',
|
||||||
|
indexes: {},
|
||||||
|
links: {},
|
||||||
|
embeddedSchemas: {},
|
||||||
|
getId: _logEntryGetId,
|
||||||
|
getLinks: _logEntryGetLinks,
|
||||||
|
attach: _logEntryAttach,
|
||||||
|
version: '3.1.0+1',
|
||||||
|
);
|
||||||
|
|
||||||
|
int _logEntryEstimateSize(
|
||||||
|
LogEntry object,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
var bytesCount = offsets.last;
|
||||||
|
bytesCount += 3 + object.text.length * 3;
|
||||||
|
return bytesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _logEntrySerialize(
|
||||||
|
LogEntry object,
|
||||||
|
IsarWriter writer,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
writer.writeByte(offsets[0], object.severity.index);
|
||||||
|
writer.writeString(offsets[1], object.text);
|
||||||
|
writer.writeDateTime(offsets[2], object.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogEntry _logEntryDeserialize(
|
||||||
|
Id id,
|
||||||
|
IsarReader reader,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
final object = LogEntry();
|
||||||
|
object.id = id;
|
||||||
|
object.severity =
|
||||||
|
_LogEntryseverityValueEnumMap[reader.readByteOrNull(offsets[0])] ??
|
||||||
|
LogEntrySeverityEnum.info;
|
||||||
|
object.text = reader.readString(offsets[1]);
|
||||||
|
object.time = reader.readDateTime(offsets[2]);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
P _logEntryDeserializeProp<P>(
|
||||||
|
IsarReader reader,
|
||||||
|
int propertyId,
|
||||||
|
int offset,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
switch (propertyId) {
|
||||||
|
case 0:
|
||||||
|
return (_LogEntryseverityValueEnumMap[reader.readByteOrNull(offset)] ??
|
||||||
|
LogEntrySeverityEnum.info) as P;
|
||||||
|
case 1:
|
||||||
|
return (reader.readString(offset)) as P;
|
||||||
|
case 2:
|
||||||
|
return (reader.readDateTime(offset)) as P;
|
||||||
|
default:
|
||||||
|
throw IsarError('Unknown property with id $propertyId');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _LogEntryseverityEnumValueMap = {
|
||||||
|
'info': 0,
|
||||||
|
'debug': 1,
|
||||||
|
'error': 2,
|
||||||
|
};
|
||||||
|
const _LogEntryseverityValueEnumMap = {
|
||||||
|
0: LogEntrySeverityEnum.info,
|
||||||
|
1: LogEntrySeverityEnum.debug,
|
||||||
|
2: LogEntrySeverityEnum.error,
|
||||||
|
};
|
||||||
|
|
||||||
|
Id _logEntryGetId(LogEntry object) {
|
||||||
|
return object.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IsarLinkBase<dynamic>> _logEntryGetLinks(LogEntry object) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _logEntryAttach(IsarCollection<dynamic> col, Id id, LogEntry object) {
|
||||||
|
object.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LogEntryQueryWhereSort on QueryBuilder<LogEntry, LogEntry, QWhere> {
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterWhere> anyId() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(const IdWhereClause.any());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LogEntryQueryWhere on QueryBuilder<LogEntry, LogEntry, QWhereClause> {
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterWhereClause> idEqualTo(Id id) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(IdWhereClause.between(
|
||||||
|
lower: id,
|
||||||
|
upper: id,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterWhereClause> idNotEqualTo(Id id) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
if (query.whereSort == Sort.asc) {
|
||||||
|
return query
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: id, includeUpper: false),
|
||||||
|
)
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: id, includeLower: false),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return query
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: id, includeLower: false),
|
||||||
|
)
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: id, includeUpper: false),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterWhereClause> idGreaterThan(Id id,
|
||||||
|
{bool include = false}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: id, includeLower: include),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterWhereClause> idLessThan(Id id,
|
||||||
|
{bool include = false}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: id, includeUpper: include),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterWhereClause> idBetween(
|
||||||
|
Id lowerId,
|
||||||
|
Id upperId, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(IdWhereClause.between(
|
||||||
|
lower: lowerId,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upperId,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LogEntryQueryFilter
|
||||||
|
on QueryBuilder<LogEntry, LogEntry, QFilterCondition> {
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> idEqualTo(Id value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> idGreaterThan(
|
||||||
|
Id value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> idLessThan(
|
||||||
|
Id value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> idBetween(
|
||||||
|
Id lower,
|
||||||
|
Id upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'id',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> severityEqualTo(
|
||||||
|
LogEntrySeverityEnum value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'severity',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> severityGreaterThan(
|
||||||
|
LogEntrySeverityEnum value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'severity',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> severityLessThan(
|
||||||
|
LogEntrySeverityEnum value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'severity',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> severityBetween(
|
||||||
|
LogEntrySeverityEnum lower,
|
||||||
|
LogEntrySeverityEnum upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'severity',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textEqualTo(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'text',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textGreaterThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'text',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textLessThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'text',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textBetween(
|
||||||
|
String lower,
|
||||||
|
String upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'text',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textStartsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.startsWith(
|
||||||
|
property: r'text',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textEndsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.endsWith(
|
||||||
|
property: r'text',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textContains(
|
||||||
|
String value,
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.contains(
|
||||||
|
property: r'text',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textMatches(
|
||||||
|
String pattern,
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.matches(
|
||||||
|
property: r'text',
|
||||||
|
wildcard: pattern,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textIsEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'text',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> textIsNotEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
property: r'text',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> timeEqualTo(
|
||||||
|
DateTime value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'time',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> timeGreaterThan(
|
||||||
|
DateTime value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'time',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> timeLessThan(
|
||||||
|
DateTime value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'time',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterFilterCondition> timeBetween(
|
||||||
|
DateTime lower,
|
||||||
|
DateTime upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'time',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LogEntryQueryObject
|
||||||
|
on QueryBuilder<LogEntry, LogEntry, QFilterCondition> {}
|
||||||
|
|
||||||
|
extension LogEntryQueryLinks
|
||||||
|
on QueryBuilder<LogEntry, LogEntry, QFilterCondition> {}
|
||||||
|
|
||||||
|
extension LogEntryQuerySortBy on QueryBuilder<LogEntry, LogEntry, QSortBy> {
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> sortBySeverity() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'severity', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> sortBySeverityDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'severity', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> sortByText() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'text', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> sortByTextDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'text', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> sortByTime() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'time', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> sortByTimeDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'time', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LogEntryQuerySortThenBy
|
||||||
|
on QueryBuilder<LogEntry, LogEntry, QSortThenBy> {
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> thenById() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'id', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> thenByIdDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'id', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> thenBySeverity() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'severity', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> thenBySeverityDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'severity', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> thenByText() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'text', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> thenByTextDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'text', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> thenByTime() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'time', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QAfterSortBy> thenByTimeDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'time', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LogEntryQueryWhereDistinct
|
||||||
|
on QueryBuilder<LogEntry, LogEntry, QDistinct> {
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QDistinct> distinctBySeverity() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'severity');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QDistinct> distinctByText(
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'text', caseSensitive: caseSensitive);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntry, QDistinct> distinctByTime() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'time');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LogEntryQueryProperty
|
||||||
|
on QueryBuilder<LogEntry, LogEntry, QQueryProperty> {
|
||||||
|
QueryBuilder<LogEntry, int, QQueryOperations> idProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, LogEntrySeverityEnum, QQueryOperations>
|
||||||
|
severityProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'severity');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, String, QQueryOperations> textProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'text');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<LogEntry, DateTime, QQueryOperations> timeProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'time');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
LogEntry _$LogEntryFromJson(Map<String, dynamic> json) => LogEntry()
|
||||||
|
..id = json['id'] as int
|
||||||
|
..time = DateTime.parse(json['time'] as String)
|
||||||
|
..severity = $enumDecode(_$LogEntrySeverityEnumEnumMap, json['severity'])
|
||||||
|
..text = json['text'] as String;
|
||||||
|
|
||||||
|
Map<String, dynamic> _$LogEntryToJson(LogEntry instance) => <String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'time': instance.time.toIso8601String(),
|
||||||
|
'severity': _$LogEntrySeverityEnumEnumMap[instance.severity]!,
|
||||||
|
'text': instance.text,
|
||||||
|
};
|
||||||
|
|
||||||
|
const _$LogEntrySeverityEnumEnumMap = {
|
||||||
|
LogEntrySeverityEnum.info: 'info',
|
||||||
|
LogEntrySeverityEnum.debug: 'debug',
|
||||||
|
LogEntrySeverityEnum.error: 'error',
|
||||||
|
};
|
||||||
@@ -5,6 +5,17 @@ import 'package:stadtbote/tools/util.dart';
|
|||||||
|
|
||||||
part 'message.g.dart';
|
part 'message.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class MessageMessage {
|
||||||
|
late Message mssg;
|
||||||
|
|
||||||
|
MessageMessage();
|
||||||
|
|
||||||
|
factory MessageMessage.fromJson(Map<String, dynamic> json) => _$MessageMessageFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$MessageMessageToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
@collection
|
@collection
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class Message {
|
class Message {
|
||||||
|
|||||||
@@ -1098,6 +1098,15 @@ extension MessageQueryProperty
|
|||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
|
MessageMessage _$MessageMessageFromJson(Map<String, dynamic> json) =>
|
||||||
|
MessageMessage()
|
||||||
|
..mssg = Message.fromJson(json['mssg'] as Map<String, dynamic>);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$MessageMessageToJson(MessageMessage instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'mssg': instance.mssg,
|
||||||
|
};
|
||||||
|
|
||||||
Message _$MessageFromJson(Map<String, dynamic> json) => Message()
|
Message _$MessageFromJson(Map<String, dynamic> json) => Message()
|
||||||
..id = json['id'] as int
|
..id = json['id'] as int
|
||||||
..time = json['time'] as String
|
..time = json['time'] as String
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:expandable/expandable.dart';
|
import 'package:expandable/expandable.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
@@ -8,8 +6,6 @@ import 'package:stadtbote/protocoll_messages/accept_job_message.dart';
|
|||||||
import 'package:stadtbote/model/job.dart';
|
import 'package:stadtbote/model/job.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
|
import 'package:stadtbote/protocoll_messages/fin_task_message.dart';
|
||||||
import 'package:stadtbote/tools/constants.dart';
|
import 'package:stadtbote/tools/constants.dart';
|
||||||
import 'package:stadtbote/tools/message_service.dart';
|
|
||||||
import 'package:stadtbote/tools/messages/refresh_badges_message.dart';
|
|
||||||
import 'package:stadtbote/tools/mqtt_core.dart';
|
import 'package:stadtbote/tools/mqtt_core.dart';
|
||||||
import 'package:stadtbote/tools/util.dart';
|
import 'package:stadtbote/tools/util.dart';
|
||||||
import 'package:badges/badges.dart' as badges;
|
import 'package:badges/badges.dart' as badges;
|
||||||
@@ -20,138 +16,192 @@ Future<void> showAcceptJobsPopup(BuildContext context, List<Job> jobs) async {
|
|||||||
await showDialog<void>(
|
await showDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return WillPopScope(
|
||||||
contentPadding: EdgeInsets.zero,
|
onWillPop: () async {
|
||||||
shadowColor: Colors.transparent,
|
MessageService().unsubscribe(Constants.messageTopicJobDeleted, jobsMap);
|
||||||
backgroundColor: Colors.white,
|
MessageService().unsubscribe(Constants.messageTopicJobReceived, jobsMap);
|
||||||
content: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
|
||||||
if (jobsSet.isEmpty) {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return SizedBox(
|
Navigator.of(context).pop();
|
||||||
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: jobsSet.length,
|
|
||||||
itemBuilder: (_, i) {
|
|
||||||
var job = jobsSet.toList()[i];
|
|
||||||
|
|
||||||
return ExpandableNotifier(
|
onFinished();
|
||||||
child: ListTile(
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
return true;
|
||||||
title: Container(
|
},
|
||||||
decoration: BoxDecoration(
|
child: AlertDialog(
|
||||||
borderRadius: BorderRadius.circular(10),
|
contentPadding: EdgeInsets.zero,
|
||||||
border: Border.all(
|
shadowColor: Colors.transparent,
|
||||||
color: Constants.colorPrimary,
|
backgroundColor: Colors.white,
|
||||||
width: 1,
|
content: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||||
),
|
if (jobsMap.isEmpty) {
|
||||||
),
|
Navigator.of(context).pop();
|
||||||
child: badges.Badge(
|
|
||||||
position: badges.BadgePosition.topEnd(top: -13, end: -5),
|
onFinished();
|
||||||
showBadge: false,
|
}
|
||||||
badgeContent: const Text(
|
|
||||||
'Neu',
|
MessageService().unsubscribe(Constants.messageTopicJobDeleted, jobsMap);
|
||||||
style: TextStyle(
|
MessageService().unsubscribe(Constants.messageTopicJobReceived, jobsMap);
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18.0,
|
MessageService().subscribe<JobDeletedMessage>(Constants.messageTopicJobDeleted, jobsMap, (jobDeletedMessage) async {
|
||||||
|
jobsMap.removeWhere((key, value) => key == jobDeletedMessage.jobId);
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, jobsMap, (jobdMessage) async {
|
||||||
|
if (jobsMap.containsKey(jobdMessage.job.id)) {
|
||||||
|
jobsMap.removeWhere((key, value) => key == jobdMessage.job.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobsMap[jobdMessage.job.id] = jobdMessage.job;
|
||||||
|
|
||||||
|
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(
|
||||||
|
height: 100,
|
||||||
|
padding: const EdgeInsets.all(5),
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: jobsMap.length,
|
||||||
|
itemBuilder: (_, i) {
|
||||||
|
var job = jobsMap.values.toList()[i];
|
||||||
|
|
||||||
|
String remarkString = '';
|
||||||
|
for (var remark in job.rem) {
|
||||||
|
remarkString += '$remark\n';
|
||||||
|
}
|
||||||
|
remarkString = remarkString.trim();
|
||||||
|
|
||||||
|
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(
|
||||||
badgeStyle: badges.BadgeStyle(
|
position: badges.BadgePosition.topEnd(top: -13, end: -5),
|
||||||
shape: badges.BadgeShape.square,
|
showBadge: false,
|
||||||
badgeColor: Constants.colorPrimary,
|
badgeContent: const Text(
|
||||||
padding: const EdgeInsets.all(5),
|
'Neu',
|
||||||
borderRadius: BorderRadius.circular(5),
|
style: TextStyle(
|
||||||
borderSide: const BorderSide(color: Constants.colorPrimary, width: 0),
|
color: Colors.white,
|
||||||
),
|
fontSize: 18.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)).toString(),
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.white),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
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)),
|
badgeStyle: badges.BadgeStyle(
|
||||||
SizedBox(width: double.infinity, child: Text(job.tours[0].street, textAlign: TextAlign.left)),
|
shape: badges.BadgeShape.square,
|
||||||
SizedBox(width: double.infinity, child: Text(job.tours[0].city, textAlign: TextAlign.left)),
|
badgeColor: Constants.colorPrimary,
|
||||||
Row(
|
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: [
|
children: [
|
||||||
Image.asset("assets/${mapVehicleTypeToImageName(job.vhtId)}", width: 60, height: 60),
|
SizedBox(
|
||||||
const SizedBox(width: 10),
|
width: double.infinity,
|
||||||
Text(mapVehicleTypeToText(job.vhtId)),
|
child: Text(
|
||||||
],
|
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime).toLocal()).toString(),
|
||||||
),
|
textAlign: TextAlign.left,
|
||||||
const SizedBox(height: 10),
|
style: TextStyle(backgroundColor: isJobInFuture(job) ? Colors.yellow : Colors.transparent),
|
||||||
ScrollOnExpand(
|
),
|
||||||
scrollOnExpand: true,
|
|
||||||
scrollOnCollapse: false,
|
|
||||||
child: ExpandablePanel(
|
|
||||||
theme: const ExpandableThemeData(
|
|
||||||
headerAlignment: ExpandablePanelHeaderAlignment.center,
|
|
||||||
tapBodyToCollapse: true,
|
|
||||||
),
|
),
|
||||||
header: const Padding(
|
SizedBox(width: double.infinity, child: Text('Auftragsnummer: ${job.id}', textAlign: TextAlign.left)),
|
||||||
padding: EdgeInsets.all(0),
|
SizedBox(width: double.infinity, child: Text(job.tours[0].comp, textAlign: TextAlign.left)),
|
||||||
child: Text(
|
SizedBox(width: double.infinity, child: Text(job.tours[0].street, textAlign: TextAlign.left)),
|
||||||
"Weitere Infos....",
|
SizedBox(width: double.infinity, child: Text(job.tours[0].city, textAlign: TextAlign.left)),
|
||||||
style: TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.bold),
|
Row(
|
||||||
)),
|
children: [
|
||||||
collapsed: const SizedBox(),
|
Image.asset("assets/${mapVehicleTypeToImageName(job.vhtId)}", width: 60, height: 60),
|
||||||
expanded: Column(
|
const SizedBox(width: 10),
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
Text(mapVehicleTypeToText(job.vhtId)),
|
||||||
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: 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(remarkString),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(children: [
|
||||||
|
Expanded(
|
||||||
|
child: getDefaultButton(!job.global ? 'Ablehnen' : 'Ignorieren',
|
||||||
|
() {
|
||||||
|
_sendAnswer(job, !job.global ? 2 : 3);
|
||||||
|
|
||||||
|
jobsMap.removeWhere((key, value) => key == job.id);
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
Expanded(
|
||||||
|
child: getDefaultButton('Annehmen', () {
|
||||||
|
_sendAnswer(job, 1);
|
||||||
|
|
||||||
|
jobsMap.removeWhere((key, value) => key == job.id);
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
])
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
),
|
||||||
Row(children: [
|
|
||||||
Expanded(
|
|
||||||
child: getDefaultButton(!job.global ? 'Ablehnen' : 'Ignorieren',
|
|
||||||
() => {_sendAnswer(job, !job.global ? 2 : 3), jobsSet.remove(job), setState(() {})}),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 20),
|
|
||||||
Expanded(
|
|
||||||
child: getDefaultButton('Annehmen', () => {_sendAnswer(job, 1), jobsSet.remove(job), setState(() {})}),
|
|
||||||
)
|
|
||||||
])
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
),
|
},
|
||||||
);
|
)),
|
||||||
},
|
);
|
||||||
)),
|
})));
|
||||||
);
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import 'package:stadtbote/tools/mqtt_core.dart';
|
|||||||
import 'package:stadtbote/tools/util.dart';
|
import 'package:stadtbote/tools/util.dart';
|
||||||
|
|
||||||
void showInfosPopup(BuildContext context, SessionStatus? status) async {
|
void showInfosPopup(BuildContext context, SessionStatus? status) async {
|
||||||
var text = "Versionsnummer: a203\n";
|
var version = await Util.getAppVersion();
|
||||||
|
|
||||||
|
var text = "Versionsnummer: a$version\n";
|
||||||
text += "Verbindungsstatus: ${MqttCore.instance.connectionState == ConnectionStateEnum.connected ? "Verbunden" : "NICHT verbunden"}\n";
|
text += "Verbindungsstatus: ${MqttCore.instance.connectionState == ConnectionStateEnum.connected ? "Verbunden" : "NICHT verbunden"}\n";
|
||||||
text += "GPS-Status: ${MyApp.currentPosition != null ? MyApp.currentPosition!.timestamp.toString() : "Unbekannt"}\n";
|
text += "GPS-Status: ${MyApp.currentPosition != null ? MyApp.currentPosition!.timestamp.toString() : "Unbekannt"}\n";
|
||||||
text += "\n";
|
text += "\n";
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:animated_toggle_switch/animated_toggle_switch.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_map/flutter_map.dart';
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
|
import 'package:stadtbote/tools/util.dart';
|
||||||
|
|
||||||
import '../model/job_tour.dart';
|
import '../model/job_tour.dart';
|
||||||
|
|
||||||
@@ -27,12 +28,16 @@ showMapPopup(BuildContext context, JobTour currentTour, List<JobTour> tourList)
|
|||||||
tourWidgets.add(
|
tourWidgets.add(
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
mapController.move(LatLng(tour.pos!.lat, tour.pos!.long), mapController.zoom);
|
if (tour.pos != null) {
|
||||||
|
mapController.move(LatLng(tour.pos!.lat, tour.pos!.long), mapController.zoom);
|
||||||
|
|
||||||
streamController[currentTour.sort]!.sink.add(false);
|
streamController[currentTour.sort]!.sink.add(false);
|
||||||
|
|
||||||
currentTour = tour;
|
currentTour = tour;
|
||||||
streamController[tour.sort]!.sink.add(true);
|
streamController[tour.sort]!.sink.add(true);
|
||||||
|
} else {
|
||||||
|
showAlertDialog(context, 'Information', 'Es liegt keine Position für diese Station vor');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 70,
|
width: 70,
|
||||||
@@ -87,17 +92,20 @@ showMapPopup(BuildContext context, JobTour currentTour, List<JobTour> tourList)
|
|||||||
|
|
||||||
List<Marker> markers = [];
|
List<Marker> markers = [];
|
||||||
for (var tour in tourList) {
|
for (var tour in tourList) {
|
||||||
markers.add(Marker(
|
if (tour.pos != null) {
|
||||||
builder: (context) => const Icon(Icons.person_pin_circle, size: 56, color: Colors.blue),
|
markers.add(Marker(
|
||||||
point: LatLng(tour.pos!.lat, tour.pos!.long)));
|
builder: (context) => const Icon(Icons.person_pin_circle, size: 56, color: Colors.blue),
|
||||||
|
point: LatLng(tour.pos!.lat, tour.pos!.long)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.fromLTRB(30, 0, 30, 0),
|
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||||
key: GlobalKey(),
|
key: GlobalKey(),
|
||||||
height: MediaQuery.of(context).size.height * 0.6,
|
height: MediaQuery.of(context).size.height * 0.6,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 100,
|
height: 100,
|
||||||
|
width: MediaQuery.of(context).size.width * 1,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
|||||||
@@ -40,10 +40,15 @@ showReceiptGiverPopup(BuildContext context, TaskInfo taskInfo, Function(String)
|
|||||||
controller: textEditingController,
|
controller: textEditingController,
|
||||||
autofocus: true),
|
autofocus: true),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
getDefaultButton('Übernehmen', () => {
|
getDefaultButton('Übernehmen', () {
|
||||||
Navigator.of(context).pop(),
|
if (textEditingController.text.isNotEmpty) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
onFinished(textEditingController.text)})
|
onFinished(textEditingController.text);
|
||||||
|
} else {
|
||||||
|
showAlertDialog(context, "Fehler", "Sie müssen einen Text eingeben");
|
||||||
|
}
|
||||||
|
})
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,11 +3,19 @@ import 'package:signature/signature.dart';
|
|||||||
import 'package:stadtbote/model/task_info.dart';
|
import 'package:stadtbote/model/task_info.dart';
|
||||||
import 'package:stadtbote/tools/util.dart';
|
import 'package:stadtbote/tools/util.dart';
|
||||||
|
|
||||||
showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function() onFinished) async {
|
showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function(String?) onFinished) async {
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return WillPopScope(
|
||||||
|
onWillPop: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
|
onFinished(null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},// False will prevent and true will allow to dismiss
|
||||||
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
shadowColor: Colors.transparent,
|
shadowColor: Colors.transparent,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
@@ -18,6 +26,24 @@ showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function() onFinishe
|
|||||||
var popupHeight = MediaQuery.of(context).size.height * 0.85;
|
var popupHeight = MediaQuery.of(context).size.height * 0.85;
|
||||||
var popupWidth = MediaQuery.of(context).size.width * 0.85;
|
var popupWidth = MediaQuery.of(context).size.width * 0.85;
|
||||||
|
|
||||||
|
String convertPoints(List<Point> points) {
|
||||||
|
if (points.isNotEmpty) {
|
||||||
|
String result = "";
|
||||||
|
|
||||||
|
for (var point in points) {
|
||||||
|
if (point.type != PointType.tap) {
|
||||||
|
result += "${point.offset.dx.toInt()},${point.offset.dy.toInt()};";
|
||||||
|
} else {
|
||||||
|
result += "A";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.replaceAll("AA", "A");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
key: GlobalKey(),
|
key: GlobalKey(),
|
||||||
height: popupHeight,
|
height: popupHeight,
|
||||||
@@ -46,14 +72,19 @@ showSignaturePopup(BuildContext context, TaskInfo taskInfo, Function() onFinishe
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
getDefaultButton('Übernehmen', buttonHeight: 50, () => {
|
getDefaultButton('Übernehmen', buttonHeight: 50, () => {
|
||||||
Navigator.of(context).pop(),
|
if (controller.points.length > 50) {
|
||||||
|
Navigator.of(context).pop(),
|
||||||
|
|
||||||
onFinished()})
|
onFinished(convertPoints(controller.points))
|
||||||
|
} else {
|
||||||
|
showAlertDialog(context, "Fehler", "Die Unterschrift ist zu kurz.")
|
||||||
|
}
|
||||||
|
})
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
));
|
)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import 'package:carousel_slider/carousel_slider.dart';
|
import 'package:carousel_slider/carousel_slider.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:image/image.dart' as imageLib;
|
||||||
import 'package:stadtbote/model/task_info.dart';
|
import 'package:stadtbote/model/task_info.dart';
|
||||||
import 'package:stadtbote/tools/util.dart';
|
import 'package:stadtbote/tools/util.dart';
|
||||||
|
|
||||||
Future<void> showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Function() onFinished) async {
|
Future<void> showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Function(List<Uint8List>) onFinished) async {
|
||||||
List<Uint8List> imageDataList = [];
|
List<Uint8List> imageDataList = [];
|
||||||
List<Widget> imageWidgetsList = [];
|
List<Widget> imageWidgetsList = [];
|
||||||
|
|
||||||
@@ -19,22 +20,35 @@ Future<void> showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Functi
|
|||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
content: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
content: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||||
void capturePhoto() async {
|
void capturePhoto() async {
|
||||||
var photo = await Util.capturePhoto();
|
try {
|
||||||
|
var photo = await Util.capturePhoto();
|
||||||
|
|
||||||
if (photo != null) {
|
if (photo != null) {
|
||||||
var imageData = await photo.readAsBytes();
|
var fullsizeImageData = await photo.readAsBytes();
|
||||||
photo.delete();
|
|
||||||
|
|
||||||
imageDataList.add(imageData);
|
imageLib.Image? image = imageLib.decodeImage(fullsizeImageData);
|
||||||
|
|
||||||
imageWidgetsList.add(GestureDetector(
|
if (image != null) {
|
||||||
onTap: () {},
|
var thumbnail = imageLib.copyResize(image, width: 800);
|
||||||
child: Image.memory(imageData),
|
|
||||||
));
|
|
||||||
|
|
||||||
imageWidgetsListNotifier.value = imageWidgetsList;
|
var resizedImageData = imageLib.encodeJpg(thumbnail, quality: 75);
|
||||||
|
|
||||||
setState(() {});
|
photo.delete();
|
||||||
|
|
||||||
|
imageDataList.add(resizedImageData);
|
||||||
|
|
||||||
|
imageWidgetsList.add(GestureDetector(
|
||||||
|
onTap: () {},
|
||||||
|
child: Image.memory(resizedImageData),
|
||||||
|
));
|
||||||
|
|
||||||
|
imageWidgetsListNotifier.value = imageWidgetsList;
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
Util.logException(ex.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +104,7 @@ Future<void> showTakePhotosPopup(BuildContext context, TaskInfo taskInfo, Functi
|
|||||||
buttonHeight: 50,
|
buttonHeight: 50,
|
||||||
() => {
|
() => {
|
||||||
if (imageDataList.length == taskInfo.task.min! && imageDataList.length <= taskInfo.task.max!)
|
if (imageDataList.length == taskInfo.task.min! && imageDataList.length <= taskInfo.task.max!)
|
||||||
{Navigator.of(context).pop(), onFinished()}
|
{Navigator.of(context).pop(), onFinished(imageDataList)}
|
||||||
else
|
else
|
||||||
{showAlertDialog(context, 'Fehler', 'Sie müssen mindestens ${taskInfo.task.min} Foto(s) aufnehmen')}
|
{showAlertDialog(context, 'Fehler', 'Sie müssen mindestens ${taskInfo.task.min} Foto(s) aufnehmen')}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ class Reaction {
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
@JsonSerializable()class Track {
|
@JsonSerializable()class Track {
|
||||||
late String time;
|
late String time;
|
||||||
late FinTaskPos pos;
|
|
||||||
|
FinTaskPos? pos;
|
||||||
|
|
||||||
Track();
|
Track();
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ Map<String, dynamic> _$ReactionToJson(Reaction instance) => <String, dynamic>{
|
|||||||
|
|
||||||
Track _$TrackFromJson(Map<String, dynamic> json) => Track()
|
Track _$TrackFromJson(Map<String, dynamic> json) => Track()
|
||||||
..time = json['time'] as String
|
..time = json['time'] as String
|
||||||
..pos = FinTaskPos.fromJson(json['pos'] as Map<String, dynamic>);
|
..pos = json['pos'] == null
|
||||||
|
? null
|
||||||
|
: FinTaskPos.fromJson(json['pos'] as Map<String, dynamic>);
|
||||||
|
|
||||||
Map<String, dynamic> _$TrackToJson(Track instance) => <String, dynamic>{
|
Map<String, dynamic> _$TrackToJson(Track instance) => <String, dynamic>{
|
||||||
'time': instance.time,
|
'time': instance.time,
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'acknowledge_job.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class AcknowledgeJob {
|
||||||
|
late AcknowledgeJobReceived received;
|
||||||
|
|
||||||
|
AcknowledgeJob();
|
||||||
|
|
||||||
|
factory AcknowledgeJob.fromJson(Map<String, dynamic> json) => _$AcknowledgeJobFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$AcknowledgeJobToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class AcknowledgeJobReceived {
|
||||||
|
late int id;
|
||||||
|
|
||||||
|
late int state;
|
||||||
|
|
||||||
|
late int ver;
|
||||||
|
|
||||||
|
late int utc;
|
||||||
|
|
||||||
|
AcknowledgeJobReceived();
|
||||||
|
|
||||||
|
factory AcknowledgeJobReceived.fromJson(Map<String, dynamic> json) => _$AcknowledgeJobReceivedFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$AcknowledgeJobReceivedToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'acknowledge_job.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
AcknowledgeJob _$AcknowledgeJobFromJson(Map<String, dynamic> json) =>
|
||||||
|
AcknowledgeJob()
|
||||||
|
..received = AcknowledgeJobReceived.fromJson(
|
||||||
|
json['received'] as Map<String, dynamic>);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$AcknowledgeJobToJson(AcknowledgeJob instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'received': instance.received,
|
||||||
|
};
|
||||||
|
|
||||||
|
AcknowledgeJobReceived _$AcknowledgeJobReceivedFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
AcknowledgeJobReceived()
|
||||||
|
..id = json['id'] as int
|
||||||
|
..state = json['state'] as int
|
||||||
|
..ver = json['ver'] as int
|
||||||
|
..utc = json['utc'] as int;
|
||||||
|
|
||||||
|
Map<String, dynamic> _$AcknowledgeJobReceivedToJson(
|
||||||
|
AcknowledgeJobReceived instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'state': instance.state,
|
||||||
|
'ver': instance.ver,
|
||||||
|
'utc': instance.utc,
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import 'dart:core';
|
||||||
|
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'device_log_request.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class DeviceLogRequest {
|
||||||
|
late DateTime startDateTime;
|
||||||
|
|
||||||
|
late DateTime endDateTime;
|
||||||
|
|
||||||
|
DeviceLogRequest();
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$DeviceLogRequestToJson(this);
|
||||||
|
|
||||||
|
factory DeviceLogRequest.fromJson(Map<String, dynamic> json) => _$DeviceLogRequestFromJson(json);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'device_log_request.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
DeviceLogRequest _$DeviceLogRequestFromJson(Map<String, dynamic> json) =>
|
||||||
|
DeviceLogRequest()
|
||||||
|
..startDateTime = DateTime.parse(json['startDateTime'] as String)
|
||||||
|
..endDateTime = DateTime.parse(json['endDateTime'] as String);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$DeviceLogRequestToJson(DeviceLogRequest instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'startDateTime': instance.startDateTime.toIso8601String(),
|
||||||
|
'endDateTime': instance.endDateTime.toIso8601String(),
|
||||||
|
};
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:stadtbote/model/log_entry.dart';
|
||||||
|
|
||||||
|
part 'device_log_response.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class DeviceLogResponse {
|
||||||
|
late List<LogEntry> entries;
|
||||||
|
|
||||||
|
DeviceLogResponse();
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$DeviceLogResponseToJson(this);
|
||||||
|
|
||||||
|
factory DeviceLogResponse.fromJson(Map<String, dynamic> json) => _$DeviceLogResponseFromJson(json);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'device_log_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
DeviceLogResponse _$DeviceLogResponseFromJson(Map<String, dynamic> json) =>
|
||||||
|
DeviceLogResponse()
|
||||||
|
..entries = (json['entries'] as List<dynamic>)
|
||||||
|
.map((e) => LogEntry.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Map<String, dynamic> _$DeviceLogResponseToJson(DeviceLogResponse instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'entries': instance.entries,
|
||||||
|
};
|
||||||
@@ -35,7 +35,7 @@ class Task {
|
|||||||
|
|
||||||
late String time;
|
late String time;
|
||||||
|
|
||||||
late FinTaskPos? pos;
|
FinTaskPos? pos;
|
||||||
|
|
||||||
Task();
|
Task();
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class FinTour {
|
|||||||
|
|
||||||
late String com;
|
late String com;
|
||||||
|
|
||||||
late Track track;
|
Track? track;
|
||||||
|
|
||||||
late List<FinTourTask> tasks;
|
late List<FinTourTask> tasks;
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ class FinTourTask {
|
|||||||
|
|
||||||
List<String>? codes;
|
List<String>? codes;
|
||||||
|
|
||||||
late FinTaskPos pos;
|
FinTaskPos? pos;
|
||||||
|
|
||||||
FinTourTask();
|
FinTourTask();
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ Map<String, dynamic> _$FinTourMessageToJson(FinTourMessage instance) =>
|
|||||||
FinTour _$FinTourFromJson(Map<String, dynamic> json) => FinTour()
|
FinTour _$FinTourFromJson(Map<String, dynamic> json) => FinTour()
|
||||||
..trId = json['tr_id'] as int
|
..trId = json['tr_id'] as int
|
||||||
..com = json['com'] as String
|
..com = json['com'] as String
|
||||||
..track = Track.fromJson(json['track'] as Map<String, dynamic>)
|
..track = json['track'] == null
|
||||||
|
? null
|
||||||
|
: Track.fromJson(json['track'] as Map<String, dynamic>)
|
||||||
..tasks = (json['tasks'] as List<dynamic>)
|
..tasks = (json['tasks'] as List<dynamic>)
|
||||||
.map((e) => FinTourTask.fromJson(e as Map<String, dynamic>))
|
.map((e) => FinTourTask.fromJson(e as Map<String, dynamic>))
|
||||||
.toList();
|
.toList();
|
||||||
@@ -37,7 +39,9 @@ FinTourTask _$FinTourTaskFromJson(Map<String, dynamic> json) => FinTourTask()
|
|||||||
..code = json['code'] as int?
|
..code = json['code'] as int?
|
||||||
..sign = json['sign'] as String?
|
..sign = json['sign'] as String?
|
||||||
..codes = (json['codes'] as List<dynamic>?)?.map((e) => e as String).toList()
|
..codes = (json['codes'] as List<dynamic>?)?.map((e) => e as String).toList()
|
||||||
..pos = FinTaskPos.fromJson(json['pos'] as Map<String, dynamic>);
|
..pos = json['pos'] == null
|
||||||
|
? null
|
||||||
|
: FinTaskPos.fromJson(json['pos'] as Map<String, dynamic>);
|
||||||
|
|
||||||
Map<String, dynamic> _$FinTourTaskToJson(FinTourTask instance) =>
|
Map<String, dynamic> _$FinTourTaskToJson(FinTourTask instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
|
|||||||
@@ -4,13 +4,9 @@ part 'logout_message.g.dart';
|
|||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class LogoutMessage {
|
class LogoutMessage {
|
||||||
late String time;
|
late bool logout;
|
||||||
|
|
||||||
late double lat;
|
LogoutMessagePosition? pos;
|
||||||
|
|
||||||
late double long;
|
|
||||||
|
|
||||||
late int acc;
|
|
||||||
|
|
||||||
LogoutMessage();
|
LogoutMessage();
|
||||||
|
|
||||||
@@ -19,3 +15,20 @@ class LogoutMessage {
|
|||||||
Map<String, dynamic> toJson() => _$LogoutMessageToJson(this);
|
Map<String, dynamic> toJson() => _$LogoutMessageToJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class LogoutMessagePosition {
|
||||||
|
late String time;
|
||||||
|
|
||||||
|
late double lat;
|
||||||
|
|
||||||
|
late double long;
|
||||||
|
|
||||||
|
late int acc;
|
||||||
|
|
||||||
|
LogoutMessagePosition();
|
||||||
|
|
||||||
|
factory LogoutMessagePosition.fromJson(Map<String, dynamic> json) => _$LogoutMessagePositionFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$LogoutMessagePositionToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'pic_message.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PicMessage {
|
||||||
|
late PicData pic;
|
||||||
|
|
||||||
|
PicMessagePos? pos;
|
||||||
|
|
||||||
|
PicMessage();
|
||||||
|
|
||||||
|
factory PicMessage.fromJson(Map<String, dynamic> json) => _$PicMessageFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$PicMessageToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PicData
|
||||||
|
{
|
||||||
|
@JsonKey(name: "tr_id")
|
||||||
|
late int trId;
|
||||||
|
|
||||||
|
late int num;
|
||||||
|
|
||||||
|
late int time;
|
||||||
|
|
||||||
|
late String data;
|
||||||
|
|
||||||
|
PicData();
|
||||||
|
|
||||||
|
factory PicData.fromJson(Map<String, dynamic> json) => _$PicDataFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$PicDataToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PicMessagePos {
|
||||||
|
late double lat;
|
||||||
|
|
||||||
|
late double long;
|
||||||
|
|
||||||
|
late int acc = 0;
|
||||||
|
|
||||||
|
PicMessagePos();
|
||||||
|
|
||||||
|
factory PicMessagePos.fromJson(Map<String, dynamic> json) => _$PicMessagePosFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$PicMessagePosToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'pic_message.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
PicMessage _$PicMessageFromJson(Map<String, dynamic> json) => PicMessage()
|
||||||
|
..pic = PicData.fromJson(json['pic'] as Map<String, dynamic>)
|
||||||
|
..pos = json['pos'] == null
|
||||||
|
? null
|
||||||
|
: PicMessagePos.fromJson(json['pos'] as Map<String, dynamic>);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$PicMessageToJson(PicMessage instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'pic': instance.pic,
|
||||||
|
'pos': instance.pos,
|
||||||
|
};
|
||||||
|
|
||||||
|
PicData _$PicDataFromJson(Map<String, dynamic> json) => PicData()
|
||||||
|
..trId = json['tr_id'] as int
|
||||||
|
..num = json['num'] as int
|
||||||
|
..time = json['time'] as int
|
||||||
|
..data = json['data'] as String;
|
||||||
|
|
||||||
|
Map<String, dynamic> _$PicDataToJson(PicData instance) => <String, dynamic>{
|
||||||
|
'tr_id': instance.trId,
|
||||||
|
'num': instance.num,
|
||||||
|
'time': instance.time,
|
||||||
|
'data': instance.data,
|
||||||
|
};
|
||||||
|
|
||||||
|
PicMessagePos _$PicMessagePosFromJson(Map<String, dynamic> json) =>
|
||||||
|
PicMessagePos()
|
||||||
|
..lat = (json['lat'] as num).toDouble()
|
||||||
|
..long = (json['long'] as num).toDouble()
|
||||||
|
..acc = json['acc'] as int;
|
||||||
|
|
||||||
|
Map<String, dynamic> _$PicMessagePosToJson(PicMessagePos instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'lat': instance.lat,
|
||||||
|
'long': instance.long,
|
||||||
|
'acc': instance.acc,
|
||||||
|
};
|
||||||
@@ -4,7 +4,7 @@ part 'track_message.g.dart';
|
|||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class TrackMessage {
|
class TrackMessage {
|
||||||
late TrackPosition pos;
|
TrackPosition? pos;
|
||||||
|
|
||||||
TrackMessage();
|
TrackMessage();
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ part of 'track_message.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
TrackMessage _$TrackMessageFromJson(Map<String, dynamic> json) => TrackMessage()
|
TrackMessage _$TrackMessageFromJson(Map<String, dynamic> json) => TrackMessage()
|
||||||
..pos = TrackPosition.fromJson(json['pos'] as Map<String, dynamic>);
|
..pos = json['pos'] == null
|
||||||
|
? null
|
||||||
|
: TrackPosition.fromJson(json['pos'] as Map<String, dynamic>);
|
||||||
|
|
||||||
Map<String, dynamic> _$TrackMessageToJson(TrackMessage instance) =>
|
Map<String, dynamic> _$TrackMessageToJson(TrackMessage instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class TrackStationMessage {
|
|||||||
|
|
||||||
late String time;
|
late String time;
|
||||||
|
|
||||||
late FinTaskPos? pos;
|
FinTaskPos? pos;
|
||||||
|
|
||||||
TrackStationMessage();
|
TrackStationMessage();
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class ZipReqZip {
|
|||||||
class ZipSetPos {
|
class ZipSetPos {
|
||||||
late String zip;
|
late String zip;
|
||||||
|
|
||||||
late ZipTrack track;
|
ZipTrack? track;
|
||||||
|
|
||||||
ZipSetPos();
|
ZipSetPos();
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ class ZipSetPos {
|
|||||||
class ZipTrack {
|
class ZipTrack {
|
||||||
late String time;
|
late String time;
|
||||||
|
|
||||||
late ZipTrackPos? pos;
|
ZipTrackPos? pos;
|
||||||
|
|
||||||
ZipTrack();
|
ZipTrack();
|
||||||
|
|
||||||
|
|||||||
@@ -298,9 +298,13 @@ int _zipSetPosEstimateSize(
|
|||||||
Map<Type, List<int>> allOffsets,
|
Map<Type, List<int>> allOffsets,
|
||||||
) {
|
) {
|
||||||
var bytesCount = offsets.last;
|
var bytesCount = offsets.last;
|
||||||
bytesCount += 3 +
|
{
|
||||||
ZipTrackSchema.estimateSize(
|
final value = object.track;
|
||||||
object.track, allOffsets[ZipTrack]!, allOffsets);
|
if (value != null) {
|
||||||
|
bytesCount += 3 +
|
||||||
|
ZipTrackSchema.estimateSize(value, allOffsets[ZipTrack]!, allOffsets);
|
||||||
|
}
|
||||||
|
}
|
||||||
bytesCount += 3 + object.zip.length * 3;
|
bytesCount += 3 + object.zip.length * 3;
|
||||||
return bytesCount;
|
return bytesCount;
|
||||||
}
|
}
|
||||||
@@ -328,11 +332,10 @@ ZipSetPos _zipSetPosDeserialize(
|
|||||||
) {
|
) {
|
||||||
final object = ZipSetPos();
|
final object = ZipSetPos();
|
||||||
object.track = reader.readObjectOrNull<ZipTrack>(
|
object.track = reader.readObjectOrNull<ZipTrack>(
|
||||||
offsets[0],
|
offsets[0],
|
||||||
ZipTrackSchema.deserialize,
|
ZipTrackSchema.deserialize,
|
||||||
allOffsets,
|
allOffsets,
|
||||||
) ??
|
);
|
||||||
ZipTrack();
|
|
||||||
object.zip = reader.readString(offsets[1]);
|
object.zip = reader.readString(offsets[1]);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
@@ -346,11 +349,10 @@ P _zipSetPosDeserializeProp<P>(
|
|||||||
switch (propertyId) {
|
switch (propertyId) {
|
||||||
case 0:
|
case 0:
|
||||||
return (reader.readObjectOrNull<ZipTrack>(
|
return (reader.readObjectOrNull<ZipTrack>(
|
||||||
offset,
|
offset,
|
||||||
ZipTrackSchema.deserialize,
|
ZipTrackSchema.deserialize,
|
||||||
allOffsets,
|
allOffsets,
|
||||||
) ??
|
)) as P;
|
||||||
ZipTrack()) as P;
|
|
||||||
case 1:
|
case 1:
|
||||||
return (reader.readString(offset)) as P;
|
return (reader.readString(offset)) as P;
|
||||||
default:
|
default:
|
||||||
@@ -360,6 +362,22 @@ P _zipSetPosDeserializeProp<P>(
|
|||||||
|
|
||||||
extension ZipSetPosQueryFilter
|
extension ZipSetPosQueryFilter
|
||||||
on QueryBuilder<ZipSetPos, ZipSetPos, QFilterCondition> {
|
on QueryBuilder<ZipSetPos, ZipSetPos, QFilterCondition> {
|
||||||
|
QueryBuilder<ZipSetPos, ZipSetPos, QAfterFilterCondition> trackIsNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
property: r'track',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ZipSetPos, ZipSetPos, QAfterFilterCondition> trackIsNotNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||||
|
property: r'track',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<ZipSetPos, ZipSetPos, QAfterFilterCondition> zipEqualTo(
|
QueryBuilder<ZipSetPos, ZipSetPos, QAfterFilterCondition> zipEqualTo(
|
||||||
String value, {
|
String value, {
|
||||||
bool caseSensitive = true,
|
bool caseSensitive = true,
|
||||||
@@ -1046,7 +1064,9 @@ Map<String, dynamic> _$ZipReqZipToJson(ZipReqZip instance) => <String, dynamic>{
|
|||||||
|
|
||||||
ZipSetPos _$ZipSetPosFromJson(Map<String, dynamic> json) => ZipSetPos()
|
ZipSetPos _$ZipSetPosFromJson(Map<String, dynamic> json) => ZipSetPos()
|
||||||
..zip = json['zip'] as String
|
..zip = json['zip'] as String
|
||||||
..track = ZipTrack.fromJson(json['track'] as Map<String, dynamic>);
|
..track = json['track'] == null
|
||||||
|
? null
|
||||||
|
: ZipTrack.fromJson(json['track'] as Map<String, dynamic>);
|
||||||
|
|
||||||
Map<String, dynamic> _$ZipSetPosToJson(ZipSetPos instance) => <String, dynamic>{
|
Map<String, dynamic> _$ZipSetPosToJson(ZipSetPos instance) => <String, dynamic>{
|
||||||
'zip': instance.zip,
|
'zip': instance.zip,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Constants {
|
|||||||
static const String messageTopicRankingUpdated = "ranking_updated";
|
static const String messageTopicRankingUpdated = "ranking_updated";
|
||||||
static const String messageTopicJobReceived = "job_received";
|
static const String messageTopicJobReceived = "job_received";
|
||||||
static const String messageTopicJobDeleted = "job_deleted";
|
static const String messageTopicJobDeleted = "job_deleted";
|
||||||
static const String messageTopicRefreshBadges = "refresh_badges";
|
static const String messageTopicUpdateBadges = "update_badges";
|
||||||
static const String messageTopicMessageReceived = "message_received";
|
static const String messageTopicMessageReceived = "message_received";
|
||||||
static const String messageTopicPushContentView = "push_content_view";
|
static const String messageTopicPushContentView = "push_content_view";
|
||||||
static const String messageTopicPopContentView = "pop_content_view";
|
static const String messageTopicPopContentView = "pop_content_view";
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
class UpdateBadgesMessage {
|
||||||
|
UpdateBadgesMessage();
|
||||||
|
}
|
||||||
@@ -1,19 +1,25 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:archive/archive.dart';
|
||||||
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:mqtt_client/mqtt_client.dart';
|
import 'package:mqtt_client/mqtt_client.dart';
|
||||||
import 'package:mqtt_client/mqtt_server_client.dart';
|
import 'package:mqtt_client/mqtt_server_client.dart';
|
||||||
import 'package:stadtbote/model/rank.dart';
|
import 'package:stadtbote/model/enqueued_message.dart';
|
||||||
|
import 'package:stadtbote/model/log_entry.dart';
|
||||||
|
import 'package:stadtbote/model/ranking.dart';
|
||||||
import 'package:stadtbote/model/status.dart';
|
import 'package:stadtbote/model/status.dart';
|
||||||
|
import 'package:stadtbote/protocoll_messages/acknowledge_job.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/bootstrap_request.dart';
|
import 'package:stadtbote/protocoll_messages/bootstrap_request.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/bootstrap_response_payload.dart';
|
import 'package:stadtbote/protocoll_messages/bootstrap_response_payload.dart';
|
||||||
|
import 'package:stadtbote/protocoll_messages/device_log_request.dart';
|
||||||
|
import 'package:stadtbote/protocoll_messages/device_log_response.dart';
|
||||||
|
import 'package:stadtbote/protocoll_messages/device_object.dart';
|
||||||
import 'package:stadtbote/model/job.dart';
|
import 'package:stadtbote/model/job.dart';
|
||||||
import 'package:stadtbote/model/message.dart';
|
import 'package:stadtbote/model/message.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/device_object.dart';
|
import 'package:stadtbote/protocoll_messages/payload_container.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/job_del_message.dart';
|
|
||||||
import 'package:stadtbote/protocoll_messages/start_session_message.dart';
|
import 'package:stadtbote/protocoll_messages/start_session_message.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/sync_jobs_message.dart';
|
import 'package:stadtbote/protocoll_messages/sync_jobs_message.dart';
|
||||||
import 'package:stadtbote/protocoll_messages/track_message.dart';
|
import 'package:stadtbote/protocoll_messages/track_message.dart';
|
||||||
@@ -28,6 +34,7 @@ import 'package:stadtbote/tools/messages/status_info_update.dart';
|
|||||||
// ignore: depend_on_referenced_packages
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:typed_data/typed_buffers.dart';
|
import 'package:typed_data/typed_buffers.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
import '../model/session_status.dart';
|
import '../model/session_status.dart';
|
||||||
@@ -49,7 +56,6 @@ class MqttCore {
|
|||||||
late String _brokerUri;
|
late String _brokerUri;
|
||||||
late int _brokerPort;
|
late int _brokerPort;
|
||||||
late String _fromServerTopic;
|
late String _fromServerTopic;
|
||||||
late String _clientId;
|
|
||||||
late String _toServerTopic;
|
late String _toServerTopic;
|
||||||
|
|
||||||
late MqttServerClient _mqttClient;
|
late MqttServerClient _mqttClient;
|
||||||
@@ -94,7 +100,6 @@ class MqttCore {
|
|||||||
_mqttClient.keepAlivePeriod = 20;
|
_mqttClient.keepAlivePeriod = 20;
|
||||||
_mqttClient.autoReconnect = false;
|
_mqttClient.autoReconnect = false;
|
||||||
_mqttClient.onDisconnected = _clientDisconnected;
|
_mqttClient.onDisconnected = _clientDisconnected;
|
||||||
|
|
||||||
_mqttClient.connectionMessage = MqttConnectMessage()
|
_mqttClient.connectionMessage = MqttConnectMessage()
|
||||||
.withClientIdentifier(await Util.getAppUuid())
|
.withClientIdentifier(await Util.getAppUuid())
|
||||||
.withWillQos(MqttQos.atMostOnce)
|
.withWillQos(MqttQos.atMostOnce)
|
||||||
@@ -129,73 +134,96 @@ class MqttCore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
publishText(String subtopic, String text) {
|
publishBinary(String topic, List<int> data) {
|
||||||
|
var buffer = Uint8Buffer();
|
||||||
|
buffer.addAll(data);
|
||||||
|
|
||||||
|
_mqttClient.publishMessage(topic, MqttQos.exactlyOnce, buffer);
|
||||||
|
|
||||||
|
Util.logInfo("binary message send to $topic");
|
||||||
|
}
|
||||||
|
|
||||||
|
publishText(String topic, String text) {
|
||||||
|
var buffer = Uint8Buffer();
|
||||||
|
buffer.addAll(utf8.encode(text));
|
||||||
|
|
||||||
|
_mqttClient.publishMessage(topic, MqttQos.exactlyOnce, buffer);
|
||||||
|
|
||||||
|
Util.logInfo("message\n$text\nsend to $topic");
|
||||||
|
}
|
||||||
|
|
||||||
|
publishPayloadMessage(String topic, Map<String, dynamic> payload) {
|
||||||
|
var payloadContainer = PayloadContainer();
|
||||||
|
payloadContainer.id = const Uuid().v4().toString();
|
||||||
|
payloadContainer.recv = topic;
|
||||||
|
payloadContainer.store = true;
|
||||||
|
payloadContainer.payload = payload;
|
||||||
|
|
||||||
|
var json = jsonEncode(payloadContainer.toJson());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var buffer = Uint8Buffer();
|
publishText(_toServerTopic, json);
|
||||||
buffer.addAll(utf8.encode(text));
|
|
||||||
|
|
||||||
_mqttClient.publishMessage(subtopic, MqttQos.exactlyOnce, buffer);
|
|
||||||
|
|
||||||
var topic = "$_toServerTopic$subtopic/$_clientId";
|
|
||||||
|
|
||||||
_mqttClient.publishMessage( topic, MqttQos.exactlyOnce, buffer);
|
|
||||||
|
|
||||||
Util.logInfo("send message $text to $topic");
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Util.logException(e.toString());
|
_enqueueMessage(_toServerTopic, jsonEncode(payloadContainer.toJson()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setupSubscriptions() async {
|
void _setupSubscriptions() async {
|
||||||
Util.logInfo('_setupSubscriptions called');
|
Util.logInfo('_setupSubscriptions called');
|
||||||
|
|
||||||
_mqttClient.updates?.listen((List<MqttReceivedMessage<MqttMessage>> messages) {
|
_mqttClient.updates?.listen((List<MqttReceivedMessage<MqttMessage>> c) {
|
||||||
try {
|
try {
|
||||||
for (var mqttMessage in messages) {
|
final MqttPublishMessage message = c[0].payload as MqttPublishMessage;
|
||||||
final MqttPublishMessage message = mqttMessage.payload as MqttPublishMessage;
|
String payload = utf8.decode(MqttPublishPayload.bytesToStringAsString(message.payload.message).codeUnits);
|
||||||
String payload = utf8.decode(MqttPublishPayload.bytesToStringAsString(message.payload.message).codeUnits);
|
var topic = message.variableHeader?.topicName;
|
||||||
var topic = message.variableHeader?.topicName;
|
|
||||||
|
|
||||||
if (topic!.endsWith(_clientId)) {
|
Util.logInfo('message received\ntopic: $topic\nmessage: $payload');
|
||||||
Util.logInfo('message received');
|
|
||||||
Util.logInfo('topic: $topic');
|
|
||||||
Util.logInfo('mesage: $payload');
|
|
||||||
|
|
||||||
var topicArray = topic.split('/');
|
Map<String, dynamic> messageData = jsonDecode(payload);
|
||||||
var messageType = topicArray[3];
|
|
||||||
|
|
||||||
switch(messageType) {
|
for (var entry in messageData.keys) {
|
||||||
case 'session':
|
if (entry == 'payload') {
|
||||||
_sessionMessageReceived(jsonDecode(payload));
|
var payload = messageData[entry];
|
||||||
break;
|
for (var payloadEntry in payload.keys) {
|
||||||
|
var payloadData = payload[payloadEntry];
|
||||||
|
|
||||||
case 'status':
|
switch(payloadEntry) {
|
||||||
_statusMessageReceived(jsonDecode(payload));
|
case 'session':
|
||||||
break;
|
_sessionMessageReceived(payloadData);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'ranking':
|
case 'status':
|
||||||
_rankingMessageReceived(jsonDecode(payload));
|
_statusMessageReceived(payloadData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'job':
|
case 'ranks':
|
||||||
_jobMessageReceived(jsonDecode(payload));
|
_rankingMessageReceived(payloadData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'job_del':
|
case 'jobs':
|
||||||
_jobDeleteReceived(jsonDecode(payload));
|
_jobMessageReceived(payloadData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sync_request':
|
case 'job_del':
|
||||||
_syncRequestReceived(jsonDecode(payload));
|
_jobDeleteReceived(payloadData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "mssg":
|
case 'sync_request':
|
||||||
_messageMessageReceived(payload);
|
_syncRequestReceived(payloadData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case "mssg":
|
||||||
Util.logInfo('Unknown topic: $messageType');
|
_messageMessageReceived(payloadData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "upload_device_log":
|
||||||
|
_messageUploadDeviceLogReceived(payloadData);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Util.logInfo('Unknown topic: $payloadEntry');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,9 +232,8 @@ class MqttCore {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var topic = "$_fromServerTopic#";
|
_mqttClient.subscribe(_fromServerTopic, MqttQos.exactlyOnce);
|
||||||
_mqttClient.subscribe(topic, MqttQos.exactlyOnce);
|
Util.logInfo('subscribed to topic: $_fromServerTopic');
|
||||||
Util.logInfo('subscribed to topic: $topic');
|
|
||||||
|
|
||||||
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
|
MessageService().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
|
||||||
}
|
}
|
||||||
@@ -216,7 +243,9 @@ class MqttCore {
|
|||||||
|
|
||||||
await _sendSyncMessage();
|
await _sendSyncMessage();
|
||||||
|
|
||||||
var sessionStatusMessage = SessionStatus.fromJson(payloadData);
|
await _sendEnqueuedMessages();
|
||||||
|
|
||||||
|
var sessionStatusMessage = SessionStatus.fromJson(payloadData['status']);
|
||||||
|
|
||||||
await MyApp.isarInstance.writeTxn(() async {
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
await MyApp.isarInstance.sessionStatus.clear();
|
await MyApp.isarInstance.sessionStatus.clear();
|
||||||
@@ -240,42 +269,52 @@ class MqttCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _rankingMessageReceived(List<dynamic> payloadData) async {
|
void _rankingMessageReceived(List<dynamic> payloadData) async {
|
||||||
for (var entry in payloadData) {
|
Map<String, dynamic> rankingMap = {};
|
||||||
var rank = Rank.fromJson(entry);
|
rankingMap["ranks"] = payloadData;
|
||||||
|
var ranking = Ranking.fromJson(rankingMap);
|
||||||
await MyApp.isarInstance.writeTxn(() async {
|
|
||||||
await MyApp.isarInstance.ranks.put(rank);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
|
await MyApp.isarInstance.rankings.put(ranking);
|
||||||
|
});
|
||||||
|
|
||||||
MessageService().publish<RankingUpdated>(Constants.messageTopicRankingUpdated, arguments: RankingUpdated());
|
MessageService().publish<RankingUpdated>(Constants.messageTopicRankingUpdated, arguments: RankingUpdated());
|
||||||
}
|
}
|
||||||
|
|
||||||
void _jobMessageReceived(payloadData) async {
|
void _jobMessageReceived(payloadData) async {
|
||||||
Job newJob = Job.fromJson(payloadData);
|
for (var foundJobData in payloadData) {
|
||||||
|
Job newJob = Job.fromJson(foundJobData);
|
||||||
|
|
||||||
MyApp.isarInstance.writeTxnSync(() async {
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
MyApp.isarInstance.jobs.putSync(newJob);
|
await MyApp.isarInstance.jobs.put(newJob);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (newJob.state == Constants.stateAssigned) {
|
if (newJob.state == Constants.stateAssigned) {
|
||||||
if (newJob.global) {
|
if (newJob.global) {
|
||||||
await Util.playMp3('aaa.mp3');
|
await Util.playMp3('aaa.mp3');
|
||||||
} else {
|
} else {
|
||||||
await Util.playMp3('job_received.mp3');
|
await Util.playMp3('job_received.mp3');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MessageService().publish<JobReceivedMessage>(Constants.messageTopicJobReceived, arguments: JobReceivedMessage(job: newJob));
|
try {
|
||||||
|
MessageService().publish<JobReceivedMessage>(Constants.messageTopicJobReceived, arguments: JobReceivedMessage(job: newJob));
|
||||||
|
} catch (ex) {
|
||||||
|
Util.logException("publish messageTopicJobReceived failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
_acknowlegdeJob(newJob);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _jobDeleteReceived(payloadData) async {
|
void _jobDeleteReceived(List<dynamic> payloadData) async {
|
||||||
var jobDelMessage = JobDelMessage.fromJson(payloadData);
|
Map<String, dynamic> map = {};
|
||||||
|
map["jobDel"] = payloadData;
|
||||||
|
var jobDelMessage = JobDelMessage.fromJson(map);
|
||||||
|
|
||||||
await MyApp.isarInstance.writeTxn(() async {
|
for(var jobId in jobDelMessage.jobDel) {
|
||||||
await MyApp.isarInstance.jobs.delete(jobDelMessage.id);
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
});
|
await MyApp.isarInstance.jobs.delete(jobId);
|
||||||
|
});
|
||||||
|
|
||||||
MessageService().publish<JobDeletedMessage>(Constants.messageTopicJobDeleted, arguments: JobDeletedMessage(id: jobDelMessage.id));
|
MessageService().publish<JobDeletedMessage>(Constants.messageTopicJobDeleted, arguments: JobDeletedMessage(id: jobDelMessage.id));
|
||||||
}
|
}
|
||||||
@@ -334,19 +373,22 @@ class MqttCore {
|
|||||||
|
|
||||||
void _processBootstrap() async {
|
void _processBootstrap() async {
|
||||||
try {
|
try {
|
||||||
String? responseText = "";
|
var deviceInfoPlugin = DeviceInfoPlugin();
|
||||||
|
|
||||||
|
AndroidDeviceInfo androidInfo = await deviceInfoPlugin.androidInfo;
|
||||||
|
BaseDeviceInfo deviceInfo = await deviceInfoPlugin.deviceInfo;
|
||||||
|
|
||||||
var deviceObject = DeviceObject();
|
var deviceObject = DeviceObject();
|
||||||
deviceObject.manufacturer = "sven";
|
deviceObject.manufacturer = deviceInfo.data['manufacturer'];
|
||||||
deviceObject.model = "emulator";
|
deviceObject.model = deviceInfo.data['model'];
|
||||||
deviceObject.os = "hat es";
|
deviceObject.os = androidInfo.version.release;
|
||||||
deviceObject.osVer = "0.0";
|
deviceObject.osVer = androidInfo.version.sdkInt.toString();
|
||||||
|
|
||||||
var handshakeMessage = BootstrapRequest();
|
var handshakeMessage = BootstrapRequest();
|
||||||
handshakeMessage.app = "sb";
|
handshakeMessage.app = "sb";
|
||||||
handshakeMessage.mqttClientId = await Util.getAppUuid();
|
handshakeMessage.mqttClientId = await Util.getAppUuid();
|
||||||
handshakeMessage.deviceObject = deviceObject;
|
handshakeMessage.deviceObject = deviceObject;
|
||||||
handshakeMessage.ver = 200;
|
handshakeMessage.ver = await Util.getAppVersion();
|
||||||
|
|
||||||
//var jsonMap = handshakeMessage.toJson();
|
//var jsonMap = handshakeMessage.toJson();
|
||||||
//var json = jsonEncode(jsonMap);
|
//var json = jsonEncode(jsonMap);
|
||||||
@@ -405,12 +447,12 @@ class MqttCore {
|
|||||||
if (answer != null) {
|
if (answer != null) {
|
||||||
var trackMessage = TrackMessage();
|
var trackMessage = TrackMessage();
|
||||||
trackMessage.pos = TrackPosition();
|
trackMessage.pos = TrackPosition();
|
||||||
trackMessage.pos.time = answer.timestamp.toIso8601String();
|
trackMessage.pos!.time = position.timestamp.toIso8601String();
|
||||||
trackMessage.pos.lat = answer.latitude;
|
trackMessage.pos!.lat = position.latitude;
|
||||||
trackMessage.pos.long = answer.longitude;
|
trackMessage.pos!.long = position.longitude;
|
||||||
trackMessage.pos.acc = answer.accuracy.toInt();
|
trackMessage.pos!.acc = position.accuracy.toInt();
|
||||||
|
|
||||||
publishText("track", jsonEncode(answer.toJson()));
|
publishPayloadMessage("track", trackMessage.toJson());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -421,4 +463,42 @@ class MqttCore {
|
|||||||
_trackTimer = null;
|
_trackTimer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _enqueueMessage(String receiver, String payload) async {
|
||||||
|
var enqueuedMessage = EnqueuedMessage();
|
||||||
|
enqueuedMessage.topic = receiver;
|
||||||
|
enqueuedMessage.payload = payload;
|
||||||
|
|
||||||
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
|
await MyApp.isarInstance.enqueuedMessages.put(enqueuedMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendEnqueuedMessages() async {
|
||||||
|
var enqueuedMessages = await MyApp.isarInstance.enqueuedMessages.where().findAll();
|
||||||
|
if (enqueuedMessages.isNotEmpty) {
|
||||||
|
for (var enqueuedMessage in enqueuedMessages) {
|
||||||
|
try {
|
||||||
|
publishText(enqueuedMessage.topic, enqueuedMessage.payload);
|
||||||
|
|
||||||
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
|
await MyApp.isarInstance.enqueuedMessages.delete(enqueuedMessage.id);
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
Util.logInfo("resend enqueued message failed: $ex");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _acknowlegdeJob(Job job) {
|
||||||
|
var message = AcknowledgeJob();
|
||||||
|
message.received = AcknowledgeJobReceived();
|
||||||
|
message.received.id = job.id;
|
||||||
|
message.received.state = job.state;
|
||||||
|
message.received.ver = job.ver;
|
||||||
|
message.received.utc = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
|
||||||
|
MqttCore.instance.publishPayloadMessage('job', message.toJson());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:audioplayers/audioplayers.dart';
|
import 'package:audioplayers/audioplayers.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:package_info/package_info.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:stadtbote/main.dart';
|
||||||
import 'package:stadtbote/model/job.dart';
|
import 'package:stadtbote/model/job.dart';
|
||||||
|
import 'package:stadtbote/model/log_entry.dart';
|
||||||
import 'package:stadtbote/tools/constants.dart';
|
import 'package:stadtbote/tools/constants.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
@@ -73,12 +75,44 @@ class Util {
|
|||||||
return currentUuid;
|
return currentUuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<int> getAppVersion() async {
|
||||||
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
|
||||||
|
return int.parse(packageInfo.version.replaceAll(".0.0", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
static _printLongText(String text) {
|
||||||
|
final pattern = RegExp('.{1,800}'); // 800 is the size of each chunk
|
||||||
|
pattern.allMatches(text).forEach((match) => debugPrint(match.group(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _persistLogMessage(String text, LogEntrySeverityEnum severity) async {
|
||||||
|
var logEntry = LogEntry();
|
||||||
|
logEntry.time = DateTime.now();
|
||||||
|
logEntry.text = text;
|
||||||
|
logEntry.severity = severity;
|
||||||
|
|
||||||
|
await MyApp.isarInstance.writeTxn(() async {
|
||||||
|
await MyApp.isarInstance.logEntrys.put(logEntry);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static logInfo(String message) {
|
static logInfo(String message) {
|
||||||
log(message);
|
_printLongText(message);
|
||||||
|
|
||||||
|
_persistLogMessage(message, LogEntrySeverityEnum.info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static logDebug(String message) {
|
||||||
|
_printLongText(message);
|
||||||
|
|
||||||
|
_persistLogMessage(message, LogEntrySeverityEnum.debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
static logException(String message) {
|
static logException(String message) {
|
||||||
log('Exception: $message');
|
_printLongText(message);
|
||||||
|
|
||||||
|
_persistLogMessage(message, LogEntrySeverityEnum.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fastHash(String string) {
|
static int fastHash(String string) {
|
||||||
@@ -197,7 +231,11 @@ Widget getDefaultButton(String text, Function() onPressed, {Image? image, double
|
|||||||
Radius.circular(15),
|
Radius.circular(15),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: onPressed,
|
onPressed: () {
|
||||||
|
Util.logInfo("Button \"$text\" clicked");
|
||||||
|
|
||||||
|
onPressed();
|
||||||
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|||||||