ObjectBox

This commit is contained in:
Sven committed 2025-10-23 11:28:03 +02:00
1 parent e548f62bde
commit f8317be627
60 files changed
+2367 -15049

No files matched your search

+6 -5
View File
@@ -1,13 +1,13 @@
import 'package:dart_mq/dart_mq.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' show DateFormat;
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/tour_list_page.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/messages/pop_content_view_message.dart';
import '../main.dart';
import '../model/job.dart';
import '../objectbox.g.dart';
import '../tools/constants.dart';
import '../tools/util.dart';
@@ -34,10 +34,11 @@ class _AcceptedJobsPageState extends State<AcceptedJobsPage>
@override
void initState() {
Future.delayed(const Duration(seconds: 0), () async {
_jobs = await MyApp.isarInstance.jobs
.filter()
.stateEqualTo(Constants.stateAccepted)
.findAll();
final box = MyApp.objectBoxStore.box<Job>();
final query = box.query(Job_.state.equals(Constants.stateAccepted)).build();
_jobs = query.find();
query.close();
_jobs.sort((job1, job2) {
var date1 = DateTime.fromMillisecondsSinceEpoch(job1.ordertime * 1000, isUtc: true).millisecondsSinceEpoch;
var date2 = DateTime.fromMillisecondsSinceEpoch(job2.ordertime * 1000, isUtc: true).millisecondsSinceEpoch;
+6 -3
View File
@@ -1,6 +1,5 @@
import 'package:dart_mq/dart_mq.dart';
import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/main.dart';
import 'package:stadtbote/messages/pop_content_view_message.dart';
@@ -38,7 +37,9 @@ class _ApproachAreaPageState extends State<ApproachAreaPage>
super.initState();
Future.delayed(const Duration(seconds: 0), () async {
_ranking = await MyApp.isarInstance.rankings.where().findFirst();
final box = MyApp.objectBoxStore.box<Ranking>();
final rankings = box.getAll();
_ranking = rankings.isNotEmpty ? rankings.first : null;
_initCompleted = true;
@@ -224,7 +225,9 @@ class _ApproachAreaPageState extends State<ApproachAreaPage>
subscribe(
queueId: Constants.messageTopicRankingUpdated,
callback: (message) async {
_ranking = await MyApp.isarInstance.rankings.where().findFirst();
final box = MyApp.objectBoxStore.box<Ranking>();
final rankings = box.getAll();
_ranking = rankings.isNotEmpty ? rankings.first : null;
if (mounted) {
setState(() {});
+6 -2
View File
@@ -2,8 +2,8 @@
import 'package:dart_mq/dart_mq.dart';
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/objectbox.g.dart';
import 'package:intl/intl.dart';
import 'package:badges/badges.dart' as badges;
import 'package:stadtbote/messages/pop_content_view_message.dart';
@@ -82,7 +82,11 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> with ProducerMixin,
}
Future<List<Job>> _fetchState0Jobs() async {
return await MyApp.isarInstance.jobs.filter().stateEqualTo(Constants.stateAssigned).findAll();
final box = MyApp.objectBoxStore.box<Job>();
final query = box.query(Job_.state.equals(Constants.stateAssigned)).build();
final jobs = query.find();
query.close();
return jobs;
}
List<Widget> _createWidgets() {
+5 -5
View File
@@ -1,8 +1,8 @@
import 'package:dart_mq/dart_mq.dart';
import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/tour_list_page.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/objectbox.g.dart';
import 'package:intl/intl.dart';
import 'package:stadtbote/messages/pop_content_view_message.dart';
@@ -34,10 +34,10 @@ class _FinishedJobsPageState extends State<FinishedJobsPage>
@override
void initState() {
Future.delayed(const Duration(seconds: 0), () async {
_jobs = await MyApp.isarInstance.jobs
.filter()
.stateEqualTo(Constants.stateFinished)
.findAll();
final box = MyApp.objectBoxStore.box<Job>();
final query = box.query(Job_.state.equals(Constants.stateFinished)).build();
_jobs = query.find();
query.close();
_initCompleted = true;
+27 -17
View File
@@ -1,8 +1,8 @@
import 'package:dart_mq/dart_mq.dart';
import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/accepted_jobs_page.dart';
import 'package:stadtbote/content_views/approach_area_page.dart';
import 'package:stadtbote/objectbox.g.dart';
import 'package:stadtbote/content_views/assigned_jobs_page.dart';
import 'package:stadtbote/content_views/finished_jobs_page.dart';
import 'package:stadtbote/content_views/messages_page.dart';
@@ -322,14 +322,19 @@ class _MainPageState extends State<MainPage> with ConsumerMixin, ProducerMixin {
}
void _refreshBadges() async {
_assignedJobsValueNotifier.value =
await MyApp.isarInstance.jobs.filter().stateEqualTo(0).count();
_acceptedJobsValueNotifier.value =
await MyApp.isarInstance.jobs.filter().stateEqualTo(1).count();
_messagesValueNotifier.value = await MyApp.isarInstance.chatMessages
.filter()
.readEqualTo(false)
.count();
final jobBox = MyApp.objectBoxStore.box<Job>();
final assignedQuery = jobBox.query(Job_.state.equals(0)).build();
_assignedJobsValueNotifier.value = assignedQuery.count();
assignedQuery.close();
final acceptedQuery = jobBox.query(Job_.state.equals(1)).build();
_acceptedJobsValueNotifier.value = acceptedQuery.count();
acceptedQuery.close();
final messageBox = MyApp.objectBoxStore.box<ChatMessage>();
final messageQuery = messageBox.query(ChatMessage_.read.equals(false)).build();
_messagesValueNotifier.value = messageQuery.count();
messageQuery.close();
}
void _jobReceived(Job job) {
@@ -512,10 +517,9 @@ class _HeaderWidgetState extends State<_HeaderWidget> with ConsumerMixin {
child: FittedBox(
child: GestureDetector(
onTap: () async {
var sessionStatus = await MyApp
.isarInstance.sessionStatus
.where()
.findFirst();
final box = MyApp.objectBoxStore.box<SessionStatus>();
final sessions = box.getAll();
var sessionStatus = sessions.isNotEmpty ? sessions.first : null;
showInfosPopup(sessionStatus);
},
@@ -643,9 +647,13 @@ class _HeaderWidgetState extends State<_HeaderWidget> with ConsumerMixin {
}
_updateHeader() async {
var status = await MyApp.isarInstance.locationStatus.where().findFirst();
var sessionStatus =
await MyApp.isarInstance.sessionStatus.where().findFirst();
final locationBox = MyApp.objectBoxStore.box<LocationStatus>();
final locations = locationBox.getAll();
var status = locations.isNotEmpty ? locations.first : null;
final sessionBox = MyApp.objectBoxStore.box<SessionStatus>();
final sessions = sessionBox.getAll();
var sessionStatus = sessions.isNotEmpty ? sessions.first : null;
if (status != null) {
_zipValueNotifier.value = status.zip;
@@ -664,7 +672,9 @@ class _HeaderWidgetState extends State<_HeaderWidget> with ConsumerMixin {
/*
rightButtonImage: Util.fetchFutureIcon(const Icon(Icons.info_outline, size: 20.0, color: Colors.white)),
rightButtonOnPressed: () async {
showInfosPopup(await MyApp.isarInstance.sessionStatus.where().findFirst());
final box = MyApp.objectBoxStore.box<SessionStatus>();
final sessions = box.getAll();
showInfosPopup(sessions.isNotEmpty ? sessions.first : null);
});
*/
}
+16 -21
View File
@@ -2,13 +2,12 @@ import 'package:dart_mq/dart_mq.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/main.dart';
import 'package:stadtbote/messages/pop_content_view_message.dart';
import 'package:stadtbote/model/chat_message.dart' as sbmessage;
import 'package:stadtbote/model/chat_message.dart';
import 'package:stadtbote/model/session_status.dart';
import 'package:stadtbote/objectbox.g.dart';
import 'package:stadtbote/network_messages/messages_showed.dart';
import 'package:stadtbote/tools/constants.dart';
import 'package:stadtbote/tools/messages/publish_payload_message.dart';
@@ -49,7 +48,9 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
super.initState();
Future.delayed(const Duration(seconds: 0), () async {
var status = await MyApp.isarInstance.sessionStatus.where().findFirst();
final box = MyApp.objectBoxStore.box<SessionStatus>();
final sessions = box.getAll();
var status = sessions.isNotEmpty ? sessions.first : null;
_sid = status != null ? status.sid : 'Unbekannt';
_sendMessagesReadMessage();
@@ -97,9 +98,8 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
message.read = true;
message.id = await sbmessage.ChatMessage.getNextId();
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.chatMessages.put(message);
});
final box = MyApp.objectBoxStore.box<sbmessage.ChatMessage>();
box.put(message);
sendMessage(
routingKey: Constants.messageTopicPublishPayload,
@@ -124,7 +124,9 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
Future<void> _fetchMessages() async {
_messages.clear();
var messages = await MyApp.isarInstance.chatMessages.where().findAll();
final box = MyApp.objectBoxStore.box<sbmessage.ChatMessage>();
var messages = box.getAll();
for (var message in messages) {
_messages.add(types.TextMessage(
author: message.from == _sid ? _user : _central,
@@ -136,9 +138,7 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
_messages.sort((a, b) => b.createdAt! > a.createdAt! ? 1 : 0);
message.read = true;
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.chatMessages.put(message);
});
box.put(message);
}
setState(() {});
@@ -177,13 +177,8 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
child: getDefaultButton(
'Ja',
() async => {
await MyApp.isarInstance.writeTxn(
() async => {
await MyApp.isarInstance
.chatMessages
.delete(int.parse(
message.id))
}),
MyApp.objectBoxStore.box<sbmessage.ChatMessage>()
.remove(int.parse(message.id)),
_fetchMessages(),
setState(() {}),
Navigator.of(MyApp.appNavigatorKey
@@ -201,10 +196,10 @@ class _MessagesPageState extends State<MessagesPage> with ProducerMixin {
}
void _sendMessagesReadMessage() async {
var unreadChatMessages = await MyApp.isarInstance.chatMessages
.filter()
.readEqualTo(false)
.findAll();
final box = MyApp.objectBoxStore.box<sbmessage.ChatMessage>();
final query = box.query(ChatMessage_.read.equals(false)).build();
var unreadChatMessages = query.find();
query.close();
if (unreadChatMessages.isNotEmpty) {
List<String> chatMessageIds = [];
+50 -43
View File
@@ -4,12 +4,12 @@ import 'package:dart_mq/dart_mq.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/messages/pop_content_view_message.dart';
import 'package:stadtbote/model/job.dart';
import 'package:stadtbote/model/job_tour.dart';
import 'package:stadtbote/model/pictures.dart';
import 'package:stadtbote/objectbox.g.dart';
import 'package:stadtbote/network_messages/accept_job_message.dart';
import 'package:stadtbote/network_messages/fin_task_message.dart';
import 'package:stadtbote/network_messages/fin_tour_message.dart';
@@ -116,7 +116,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
var textColor = isTaskActive(i) ? Colors.black : const Color(0x33000000);
var optional = taskInfo.task.opt != null && taskInfo.task.opt == true;
var optional = (taskInfo.task?.opt ?? false) == true;
steps.add(
ListTile(
minVerticalPadding: 0,
@@ -159,7 +159,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
taskInfo.task.topic + (optional ? "" : " *"),
(taskInfo.task?.topic ?? '') + (optional ? "" : " *"),
textAlign: TextAlign.left,
style: TextStyle(
color: textColor,
@@ -200,7 +200,10 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
List<TaskInfo> taskList = [];
for(var task in widget.tour.tasks!) {
var taskInfo = await MyApp.isarInstance.taskInfos.filter().sIdEqualTo(task.sId).findFirst();
final box = MyApp.objectBoxStore.box<TaskInfo>();
final query = box.query(TaskInfo_.sId.equals(task.sId)).build();
var taskInfo = query.findFirst();
query.close();
if (taskInfo == null) {
taskInfo = TaskInfo();
taskInfo.id = await TaskInfo.getNextId();
@@ -218,7 +221,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
void _processTask(TaskInfo taskInfo) {
switch(taskInfo.task.type) {
switch(taskInfo.task?.type ?? 0) {
case 2:
_processSignature(taskInfo);
break;
@@ -255,7 +258,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
_processTaskArrivedOrFinished(TaskInfo taskInfo) {
Util.logInfo('Task ${taskInfo.task.sId} called');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} called');
if (!mounted) return;
final currentContext = context;
@@ -279,7 +282,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
_processCommissionNumber(TaskInfo taskInfo) {
Util.logInfo('Task ${taskInfo.task.sId} called');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} called');
if (!mounted) return;
final currentContext = context;
@@ -302,7 +305,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
/*_processScanBarcodes(TaskInfo taskInfo) {
Util.logInfo('Task ${taskInfo.task.sId} called');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} called');
showScanBarcodesPopup(context, taskInfo, (List<String> barcodes) async {
var answer = await _createAnswerHeader(taskInfo);
@@ -322,25 +325,30 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}*/
_processTakePhotos(TaskInfo taskInfo) {
Util.logInfo('Task ${taskInfo.task.sId} called');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} called');
if (!mounted) return;
final currentContext = context;
showTakePhotosPopup(currentContext, taskInfo, (List<Uint8List>? photos) async {
if (photos != null) {
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.pictures.filter().tourIdEqualTo(widget.tour.id).deleteAll();
final box = MyApp.objectBoxStore.box<Picture>();
for (int i = 0; i < photos.length; i++) {
var pictureData = photos[i];
// Delete existing pictures for this tour
final query = box.query(Picture_.tourId.equals(widget.tour.id)).build();
final existingPictures = query.find();
query.close();
box.removeMany(existingPictures.map((e) => e.id).toList());
var picture = Picture();
picture.number = i;
picture.tourId = widget.tour.id;
picture.data = base64Encode(pictureData);
await MyApp.isarInstance.pictures.put(picture);
}
});
// Add new pictures
for (int i = 0; i < photos.length; i++) {
var pictureData = photos[i];
var picture = Picture();
picture.number = i;
picture.tourId = widget.tour.id;
picture.data = base64Encode(pictureData);
box.put(picture);
}
taskInfo.additionalText = "Fotos aufgenommen";
taskInfo.completed = true;
@@ -355,7 +363,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
void _processStationNotice(TaskInfo taskInfo) {
Util.logInfo('Task ${taskInfo.task.sId} called');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} called');
if (!mounted) return;
final currentContext = context;
@@ -376,7 +384,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
void _processReceiptGiver(TaskInfo taskInfo) {
Util.logInfo('Task ${taskInfo.task.sId} called');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} called');
if (!mounted) return;
final currentContext = context;
@@ -398,7 +406,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
void _processPickupDeliveryStatusTask(TaskInfo taskInfo) {
Util.logInfo('Task ${taskInfo.task.sId} called');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} called');
Future.delayed(const Duration(seconds: 1), () async {
if (!context.mounted) return;
@@ -421,7 +429,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
void _processSignature(TaskInfo taskInfo) {
Util.logInfo('Task ${taskInfo.task.sId} called');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} called');
MyApp.suppressAcceptDialog = true;
@@ -456,27 +464,26 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
}
_finishTaskProcessing(TaskInfo taskInfo) async {
Util.logInfo('Task ${taskInfo.task.sId} finished');
Util.logInfo('Task ${taskInfo.task?.sId ?? 0} finished');
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.taskInfos.put(taskInfo);
});
final box = MyApp.objectBoxStore.box<TaskInfo>();
box.put(taskInfo);
}
bool isTaskActive(int index) {
if (!widget.readOnly) {
var currentTaskInfo = _taskList[index];
if (currentTaskInfo.completed && !currentTaskInfo.task.reenter!) return false;
if (currentTaskInfo.completed && !(currentTaskInfo.task?.reenter ?? false)) return false;
for (var taskInfo in _taskList)
{
if (taskInfo == currentTaskInfo) break;
if (!taskInfo.task.opt! && !taskInfo.completed) return false;
if (!(taskInfo.task?.opt ?? false) && !taskInfo.completed) return false;
}
if (currentTaskInfo.task.reenter!) return true;
if (currentTaskInfo.task?.reenter ?? false) return true;
return true;
}
@@ -488,7 +495,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
var message = FinTask();
message.trId = widget.tour.id;
message.task = Task();
message.task.sId = taskInfo.task.sId;
message.task.sId = taskInfo.task?.sId ?? 0;
message.task.time = Util.nowUnixSecondsUtc();
var position = await MyApp.getCurrentPosition();
@@ -511,7 +518,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
var position = await MyApp.getCurrentPosition();
var finTourTask = FinTourTask();
finTourTask.sId = taskInfo.task.sId;
finTourTask.sId = taskInfo.task?.sId ?? 0;
finTourTask.time = Util.nowUnixSecondsUtc();
if (position != null) {
finTourTask.pos = FinTaskPos();
@@ -557,9 +564,8 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
widget.tour.state = Constants.stateFinishedNotConfirmed;
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.put(widget.job);
});
final jobBox = MyApp.objectBoxStore.box<Job>();
jobBox.put(widget.job);
_sendImages();
@@ -568,7 +574,10 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
_sendImages() {
Future.delayed(const Duration(seconds: 1), () async {
var pictures = await MyApp.isarInstance.pictures.where().filter().tourIdEqualTo(widget.tour.id).findAll();
final box = MyApp.objectBoxStore.box<Picture>();
final query = box.query(Picture_.tourId.equals(widget.tour.id)).build();
var pictures = query.find();
query.close();
if (pictures.isNotEmpty) {
for (var picture in pictures) {
@@ -583,9 +592,8 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
payload: PublishPayloadMessage(topic: "pic", message: message.toJson(), acknowledgeRequired: true),
);
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.pictures.delete(picture.id);
});
final box = MyApp.objectBoxStore.box<Picture>();
box.remove(picture.id);
}
}
});
@@ -604,9 +612,8 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
if (jobFinished) {
widget.job.state = 2;
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.put(widget.job);
});
final box = MyApp.objectBoxStore.box<Job>();
box.put(widget.job);
}
}
}