Erweiterungen

This commit is contained in:
Sven committed 2024-02-10 09:12:51 +01:00
1 parent 20a1309946
commit 25a2455ce1
18 files changed
+2272 -1261

No files matched your search

+26 -11
View File
@@ -10,6 +10,7 @@ import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:stadtbote/model/job.dart';
import 'package:stadtbote/model/message.dart';
import 'package:stadtbote/model/session_status.dart';
import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/popups/accept_jobs_popup.dart';
import 'package:stadtbote/popups/infos_popup.dart';
@@ -19,6 +20,7 @@ import 'package:stadtbote/tools/messages/job_received_message.dart';
import 'package:stadtbote/tools/messages/message_message.dart';
import 'package:stadtbote/tools/messages/session_info_update.dart';
import 'package:badges/badges.dart' as badges;
import 'package:stadtbote/tools/messages/status_info_update.dart';
import '../main.dart';
import '../tools/constants.dart';
@@ -28,13 +30,7 @@ class MainPage extends ContentViewWidget {
final ValueNotifier<String> _zipValueNotifier = ValueNotifier("----");
final ValueNotifier<String> sidValueNotifier = ValueNotifier("----");
MainPage({super.key}) {
Status? status = MyApp.isarInstance.status.where().findFirstSync();
if (status != null) {
_zipValueNotifier.value = status.locZip;
sidValueNotifier.value = status.sid;
}
}
MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
@@ -77,7 +73,7 @@ class MainPage extends ContentViewWidget {
rightButtonVisible: true,
rightButtonImage: Util.fetchFutureIcon(const Icon(Icons.info_outline, size: 20.0, color: Colors.white)),
rightButtonOnPressed: () async {
showInfosPopup(context, await MyApp.isarInstance.status.where().findFirst());
showInfosPopup(context, await MyApp.isarInstance.sessionStatus.where().findFirst());
});
}
}
@@ -91,6 +87,8 @@ class _MainPageState extends State<MainPage> {
void initState() {
super.initState();
_updateHeader();
_refreshBadges();
_initMessages();
@@ -240,8 +238,12 @@ class _MainPageState extends State<MainPage> {
}
_initMessages() {
MessageService().subscribe<SessionStatusInfoUpdate>(Constants.messageTopicSessionStatusInfoUpdate, this, (sessionStatusInfoUpdateMessage) {
widget.sidValueNotifier.value = sessionStatusInfoUpdateMessage.status.sid;
});
MessageService().subscribe<StatusInfoUpdate>(Constants.messageTopicStatusInfoUpdate, this, (statusInfoUpdateMessage) {
widget.sidValueNotifier.value = statusInfoUpdateMessage.status.sid;
_updateHeader();
});
MessageService().subscribe<JobReceivedMessage>(Constants.messageTopicJobReceived, this, (JobReceivedMessage jobReceivedMessage) {
@@ -258,9 +260,9 @@ class _MainPageState extends State<MainPage> {
}
void _exitMessages() {
MessageService().unsubscribe<StatusInfoUpdate>(Constants.messageTopicStatusInfoUpdate, this);
MessageService().unsubscribe<SessionStatusInfoUpdate>(Constants.messageTopicSessionStatusInfoUpdate, this);
MessageService().unsubscribe<StatusInfoUpdate>(Constants.messageTopicJobReceived, this);
MessageService().unsubscribe<SessionStatusInfoUpdate>(Constants.messageTopicJobReceived, this);
}
void _refreshBadges() async {
@@ -272,4 +274,17 @@ class _MainPageState extends State<MainPage> {
void _jobReceived(Job job) {
_refreshBadges();
}
void _updateHeader() async {
var status = await MyApp.isarInstance.status.where().findFirst();
var sessionStatus = await MyApp.isarInstance.sessionStatus.where().findFirst();
if (status != null) {
widget._zipValueNotifier.value = '${status.pos.zip} (${status.pos.zipReal})';
} else if (sessionStatus != null) {
widget._zipValueNotifier.value = sessionStatus.sid;
} else {
widget._zipValueNotifier.value = "---";
}
}
}
+2 -2
View File
@@ -7,7 +7,7 @@ import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:stadtbote/main.dart';
import 'package:stadtbote/model/message.dart' as sbmessage;
import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/model/session_status.dart';
import 'package:stadtbote/popups/infos_popup.dart';
import 'package:stadtbote/tools/mqtt_core.dart';
import 'package:uuid/uuid.dart';
@@ -59,7 +59,7 @@ class _MessagesPageState extends State<MessagesPage> {
super.initState();
Future.delayed(const Duration(seconds: 0), () async {
var status = await MyApp.isarInstance.status.where().findFirst();
var status = await MyApp.isarInstance.sessionStatus.where().findFirst();
_sid = status != null ? status.sid : 'Unbekannt';
await _fetchMessages();
+5 -1
View File
@@ -116,7 +116,11 @@ class _TourDetailsPageState extends State<TourDetailsPage> {
const SizedBox(height: 10),
getDefaultButton('Karte', () =>
{
showMapPopup(context, widget.tour, widget.job.tours)
if (widget.tour.pos != null) {
showMapPopup(context, widget.tour, widget.job.tours)
} else {
showAlertDialog(context, 'Information', 'Es liegt keine Position für diese Station vor')
}
}),
],
),
+4 -2
View File
@@ -5,10 +5,11 @@ import 'package:geolocator/geolocator.dart';
import 'package:isar/isar.dart';
import 'package:path_provider/path_provider.dart';
import 'package:stadtbote/model/message.dart';
import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/model/task_info.dart';
import 'package:stadtbote/popups/accept_jobs_popup.dart';
import 'package:stadtbote/tools/colored_safe_area.dart';
import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/model/session_status.dart';
import 'package:stadtbote/tools/connection_status.dart';
import 'package:stadtbote/tools/message_service.dart';
import 'package:stadtbote/tools/messages/job_received_message.dart';
@@ -26,6 +27,7 @@ Future<void> main() async {
final dir = await getApplicationDocumentsDirectory();
MyApp.isarInstance = await Isar.open([
SessionStatusSchema,
StatusSchema,
JobSchema,
TaskInfoSchema,
@@ -72,7 +74,7 @@ class MyApp extends StatelessWidget {
if (result) {
LocationSettings locationSettings = const LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 50,
distanceFilter: 0,
);
Geolocator.getPositionStream(locationSettings: locationSettings).listen((Position? position) {
+35
View File
@@ -0,0 +1,35 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
part 'session_status.g.dart';
@collection
@JsonSerializable()
class SessionStatus {
final Id id = 0;
@JsonKey(name: 'cust_id')
late int custId;
@JsonKey(name: 'hq_id')
late int hqId;
@JsonKey(name: 'usr_id')
late int usrId;
@JsonKey(name: 'cr_id')
late int crId;
@JsonKey(name: 'sid')
late String sid;
@JsonKey(name: 'vht_id')
late int vhtId;
@JsonKey(name: 'loc_zip')
late String locZip;
@JsonKey(name: 'server_version')
late String serverVersion;
@JsonKey(name: 'server_instance')
late String serverInstance;
SessionStatus();
factory SessionStatus.fromJson(Map<String, dynamic> json) => _$SessionStatusFromJson(json);
Map<String, dynamic> toJson() => _$SessionStatusToJson(this);
}
File diff suppressed because it is too large. Load diff
+19 -19
View File
@@ -6,26 +6,9 @@ part 'status.g.dart';
@collection
@JsonSerializable()
class Status {
final Id id = 0;
late Id? id;
@JsonKey(name: 'cust_id')
late int custId;
@JsonKey(name: 'hq_id')
late int hqId;
@JsonKey(name: 'usr_id')
late int usrId;
@JsonKey(name: 'cr_id')
late int crId;
@JsonKey(name: 'sid')
late String sid;
@JsonKey(name: 'vht_id')
late int vhtId;
@JsonKey(name: 'loc_zip')
late String locZip;
@JsonKey(name: 'server_version')
late String serverVersion;
@JsonKey(name: 'server_instance')
late String serverInstance;
late StatusPos pos;
Status();
@@ -33,3 +16,20 @@ class Status {
Map<String, dynamic> toJson() => _$StatusToJson(this);
}
@embedded
@JsonSerializable()
class StatusPos {
late String zip;
late String area;
@JsonKey(name:'zip_real')
late String zipReal;
StatusPos();
factory StatusPos.fromJson(Map<String, dynamic> json) => _$StatusPosFromJson(json);
Map<String, dynamic> toJson() => _$StatusPosToJson(this);
}
+550 -1204
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:kumi_popup_window/kumi_popup_window.dart';
import 'package:stadtbote/main.dart';
import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/model/session_status.dart';
import 'package:stadtbote/tools/mqtt_core.dart';
import 'package:stadtbote/tools/util.dart';
void showInfosPopup(BuildContext context, Status? status) {
void showInfosPopup(BuildContext context, SessionStatus? status) {
var text = "Versionsnummer: a203\n";
text += "Verbindungsstatus: ${MqttCore.instance.connectionState == ConnectionStateEnum.connected ? "Verbunden" : "NICHT verbunden"}\n";
text += "GPS-Status: ${MyApp.currentPosition != null ? "Position gefunden" : "Position NICHT gefunden"}\n";
@@ -4,6 +4,9 @@ part 'sync_jobs_message.g.dart';
@JsonSerializable()
class SyncJobsMessage {
@JsonKey(name: 'utc_unix_time')
late int utcUnixTime;
late SyncJobMessageSync sync;
SyncJobsMessage();
@@ -15,8 +18,6 @@ class SyncJobsMessage {
@JsonSerializable()
class SyncJobMessageSync {
late int utcUnixTime;
late List<SyncJobMessageJob> jobs;
SyncJobMessageSync();
@@ -30,7 +31,7 @@ class SyncJobMessageSync {
class SyncJobMessageJob {
late int id;
late int ver;
late String ver;
late int state;
@@ -8,31 +8,31 @@ part of 'sync_jobs_message.dart';
SyncJobsMessage _$SyncJobsMessageFromJson(Map<String, dynamic> json) =>
SyncJobsMessage()
..utcUnixTime = json['utc_unix_time'] as int
..sync =
SyncJobMessageSync.fromJson(json['sync'] as Map<String, dynamic>);
Map<String, dynamic> _$SyncJobsMessageToJson(SyncJobsMessage instance) =>
<String, dynamic>{
'utc_unix_time': instance.utcUnixTime,
'sync': instance.sync,
};
SyncJobMessageSync _$SyncJobMessageSyncFromJson(Map<String, dynamic> json) =>
SyncJobMessageSync()
..utcUnixTime = json['utcUnixTime'] as int
..jobs = (json['jobs'] as List<dynamic>)
.map((e) => SyncJobMessageJob.fromJson(e as Map<String, dynamic>))
.toList();
Map<String, dynamic> _$SyncJobMessageSyncToJson(SyncJobMessageSync instance) =>
<String, dynamic>{
'utcUnixTime': instance.utcUnixTime,
'jobs': instance.jobs,
};
SyncJobMessageJob _$SyncJobMessageJobFromJson(Map<String, dynamic> json) =>
SyncJobMessageJob()
..id = json['id'] as int
..ver = json['ver'] as int
..ver = json['ver'] as String
..state = json['state'] as int;
Map<String, dynamic> _$SyncJobMessageJobToJson(SyncJobMessageJob instance) =>
+18 -1
View File
@@ -5,7 +5,7 @@ part 'track_message.g.dart';
@JsonSerializable()
class TrackMessage {
late FinTaskPos pos;
late TrackPosition pos;
TrackMessage();
@@ -14,3 +14,20 @@ class TrackMessage {
Map<String, dynamic> toJson() => _$TrackMessageToJson(this);
}
@JsonSerializable()
class TrackPosition {
late String time;
late double lat;
late double long;
late int acc;
TrackPosition();
factory TrackPosition.fromJson(Map<String, dynamic> json) => _$TrackPositionFromJson(json);
Map<String, dynamic> toJson() => _$TrackPositionToJson(this);
}
+16 -1
View File
@@ -7,9 +7,24 @@ part of 'track_message.dart';
// **************************************************************************
TrackMessage _$TrackMessageFromJson(Map<String, dynamic> json) => TrackMessage()
..pos = FinTaskPos.fromJson(json['pos'] as Map<String, dynamic>);
..pos = TrackPosition.fromJson(json['pos'] as Map<String, dynamic>);
Map<String, dynamic> _$TrackMessageToJson(TrackMessage instance) =>
<String, dynamic>{
'pos': instance.pos,
};
TrackPosition _$TrackPositionFromJson(Map<String, dynamic> json) =>
TrackPosition()
..time = json['time'] as String
..lat = (json['lat'] as num).toDouble()
..long = (json['long'] as num).toDouble()
..acc = json['acc'] as int;
Map<String, dynamic> _$TrackPositionToJson(TrackPosition instance) =>
<String, dynamic>{
'time': instance.time,
'lat': instance.lat,
'long': instance.long,
'acc': instance.acc,
};
+2 -1
View File
@@ -6,7 +6,8 @@ class Constants {
static const String messageTopicConnectionStatusChanged = "connection_status_changed";
static const String messageTopicSessionInfoUpdate = "status_info_updated";
static const String messageTopicStatusInfoUpdate = "session_info_updated";
static const String messageTopicSessionStatusInfoUpdate = "session_status_info_updated";
static const String messageTopicStatusInfoUpdate = "status_info_updated";
static const String messageTopicJobReceived = "job_received";
static const String messageTopicJobDeleted = "job_deleted";
static const String messageTopicMessageReceived = "message_received";
+4 -4
View File
@@ -1,8 +1,8 @@
import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/model/session_status.dart';
class StatusInfoUpdate {
StatusInfoUpdate({required this.status});
class SessionStatusInfoUpdate {
SessionStatusInfoUpdate({required this.status});
final Status status;
final SessionStatus status;
}
@@ -0,0 +1,7 @@
import 'package:stadtbote/model/status.dart';
class StatusInfoUpdate {
StatusInfoUpdate({required this.status});
final Status status;
}
+26 -7
View File
@@ -6,6 +6,7 @@ import 'package:isar/isar.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
import 'package:stadtbote/model/job_tour.dart';
import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/protocoll_messages/bootstrap_request.dart';
import 'package:stadtbote/protocoll_messages/bootstrap_response_payload.dart';
import 'package:stadtbote/protocoll_messages/device_object.dart';
@@ -23,13 +24,14 @@ import 'package:stadtbote/tools/messages/job_deleted_message.dart';
import 'package:stadtbote/tools/messages/job_received_message.dart';
import 'package:stadtbote/tools/messages/message_message.dart';
import 'package:stadtbote/tools/messages/session_info_update.dart';
import 'package:stadtbote/tools/messages/status_info_update.dart';
// ignore: depend_on_referenced_packages
import 'package:typed_data/typed_buffers.dart';
import 'package:http/http.dart' as http;
import 'package:uuid/uuid.dart';
import '../main.dart';
import '../model/status.dart';
import '../model/session_status.dart';
import 'constants.dart';
import 'util.dart';
@@ -164,6 +166,10 @@ class MqttCore {
_sessionMessageReceived(payloadData);
break;
case 'status':
_statusMessageReceived(payloadData);
break;
case 'ranks':
_rankingMessageReceived(payloadData);
break;
@@ -207,15 +213,27 @@ class MqttCore {
await _sendSyncMessage();
var statusMessage = Status.fromJson(payloadData['status']);
var sessionStatusMessage = SessionStatus.fromJson(payloadData['status']);
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.sessionStatus.clear();
await MyApp.isarInstance.sessionStatus.put(sessionStatusMessage);
});
MessageService().publish<SessionStatusInfoUpdate>(Constants.messageTopicSessionStatusInfoUpdate, arguments: SessionStatusInfoUpdate(status: sessionStatusMessage));
_startTrackTimer();
}
void _statusMessageReceived(payloadData) async {
var statusMessage = Status.fromJson(payloadData);
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.status.clear();
await MyApp.isarInstance.status.put(statusMessage);
});
MessageService().publish<StatusInfoUpdate>(Constants.messageTopicStatusInfoUpdate, arguments: StatusInfoUpdate(status: statusMessage));
_startTrackTimer();
}
void _rankingMessageReceived(payloadData) async {
@@ -372,14 +390,14 @@ class MqttCore {
var jobs = await MyApp.isarInstance.jobs.filter().stateGreaterThan(-1).findAll();
var answer = SyncJobsMessage();
answer.utcUnixTime = DateTime.now().toUtc().millisecondsSinceEpoch ~/ 1000;
answer.sync = SyncJobMessageSync();
answer.sync.jobs = [];
answer.sync.utcUnixTime = DateTime.now().toUtc().millisecondsSinceEpoch ~/ 1000;
for (var job in jobs) {
SyncJobMessageJob syncJob = SyncJobMessageJob();
syncJob.state = job.state;
syncJob.id = job.id;
syncJob.ver = job.ver;
syncJob.ver = job.ver.toString();
answer.sync.jobs.add(syncJob);
}
@@ -391,7 +409,8 @@ class MqttCore {
var position = MyApp.currentPosition;
if (position != null) {
var trackMessage = TrackMessage();
trackMessage.pos = FinTaskPos();
trackMessage.pos = TrackPosition();
trackMessage.pos.time = position.timestamp.toIso8601String();
trackMessage.pos.lat = position.latitude;
trackMessage.pos.long = position.longitude;
trackMessage.pos.acc = position.accuracy.toInt();
+18
View File
@@ -320,3 +320,21 @@ String mapTourMode(String mode) {
return text;
}
Future<void> showAlertDialog(BuildContext context, String title, String message) async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(title),
content: Text(message),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'),
),
],
);
}
);
}