1. Import

This commit is contained in:
Sven committed 2023-11-14 11:38:44 +01:00
commit cb4525a774
165 files changed
+14763

No files matched your search

+136
View File
@@ -0,0 +1,136 @@
import 'package:flutter/material.dart';
import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart';
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/tour_list_page.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:intl/intl.dart';
import '../main.dart';
import '../model/job.dart';
import '../tools/constants.dart';
import '../tools/util.dart';
class AcceptedJobsPage extends ContentViewWidget {
const AcceptedJobsPage({super.key});
@override
State<AcceptedJobsPage> createState() => _AcceptedJobsPageState();
@override
Future<HeaderInfo> getHeaderInfo(BuildContext context) async {
return HeaderInfo(
titleWidget: const Text(
'Angenommene Aufträge',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
),
),
rightButtonEnabled: false,
rightButtonVisible: false,
rightButtonImage: null,
rightButtonOnPressed: () async {
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: EmployeeEditProfileWidget());
});
}
}
class _AcceptedJobsPageState extends State<AcceptedJobsPage> {
late List<Job> _jobs;
late bool _initCompleted = false;
@override
void initState() {
Future.delayed(const Duration(seconds: 0), () async {
_jobs = await MyApp.isarInstance.jobs.filter().stateEqualTo(1).findAll();
_initCompleted = true;
setState(() {});
});
super.initState();
}
@override
Widget build(BuildContext context) {
if (!_initCompleted) {
return Util.getWaitWidget(context);
}
late List<Widget> jobWidgets = _createjobWidgets();
return ListView(
children: jobWidgets
);
}
List<Widget> _createjobWidgets() {
List<Widget> jobWidgets = [];
for (var job in _jobs) {
jobWidgets.add(
ListTile(
onTap: () {
_clicked(job);
},
title: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey, width: 0.5),
borderRadius: const BorderRadius.all(Radius.circular(13))
),
padding: const EdgeInsets.all(15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(),
textAlign: TextAlign.left,
),
Text(
job.crFilter != null ? job.crFilter.toString() : "Kein CR-Filter vorhanden",
textAlign: TextAlign.left,
),
Row(
children: [
const Icon(Icons.arrow_back, size: 30.0, color: Colors.black),
const SizedBox(width: 10),
Text(
job.vhtId.toString()
),
],
),
Text(
job.id.toString(),
textAlign: TextAlign.left,
),
Text(
job.tours[0].comp,
textAlign: TextAlign.left,
),
Text(
job.tours[0].street,
textAlign: TextAlign.left,
),
Text(
job.tours[0].city,
textAlign: TextAlign.left,
),
],
),
)
),
);
}
return jobWidgets;
}
void _clicked(Job job) {
BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourListPage(job: job));
}
}
+69
View File
@@ -0,0 +1,69 @@
import 'package:flutter/material.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
class AssignedJobsPage extends ContentViewWidget {
const AssignedJobsPage({super.key});
@override
State<AssignedJobsPage> createState() => _AssignedJobsPageState();
@override
Future<HeaderInfo> getHeaderInfo(BuildContext context) async {
return HeaderInfo(
titleWidget: const Text(
'Startseite',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
),
),
rightButtonEnabled: false,
rightButtonVisible: false,
rightButtonImage: null,
rightButtonOnPressed: () async {
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: EmployeeEditProfileWidget());
});
}
}
class _AssignedJobsPageState extends State<AssignedJobsPage> {
void sendMessage(Widget message) {
//Messaging.instance.sendMessage(message);
}
void _clicked() {
//sendMessage(const InfoDetailsWidget());
}
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
ListTile(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
'Dies ist ein linksbündigerText',
textAlign: TextAlign.left,
),
Text(
'Dies ist ein linksbündiger Text',
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 24.0,
),
),
],
),
onTap: () {
_clicked();
},
),
],
);
}
}
+69
View File
@@ -0,0 +1,69 @@
import 'package:flutter/material.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
class FinishedJobsPage extends ContentViewWidget {
const FinishedJobsPage({super.key});
@override
State<FinishedJobsPage> createState() => _FinishedJobsPageState();
@override
Future<HeaderInfo> getHeaderInfo(BuildContext context) async {
return HeaderInfo(
titleWidget: const Text(
'Startseite',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
),
),
rightButtonEnabled: false,
rightButtonVisible: false,
rightButtonImage: null,
rightButtonOnPressed: () async {
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: EmployeeEditProfileWidget());
});
}
}
class _FinishedJobsPageState extends State<FinishedJobsPage> {
void sendMessage(Widget message) {
//Messaging.instance.sendMessage(message);
}
void _clicked() {
//sendMessage(const InfoDetailsWidget());
}
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
ListTile(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
'Dies ist ein linksbündigerText',
textAlign: TextAlign.left,
),
Text(
'Dies ist ein linksbündiger Text',
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 24.0,
),
),
],
),
onTap: () {
_clicked();
},
),
],
);
}
}
+142
View File
@@ -0,0 +1,142 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart';
import 'package:stadtbote/content_views/accepted_jobs_page.dart';
import 'package:stadtbote/content_views/assigned_jobs_page.dart';
import 'package:stadtbote/content_views/finished_jobs_page.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:stadtbote/popups/infos_popup.dart';
import '../main.dart';
import '../model/job.dart';
import '../tools/constants.dart';
import '../tools/util.dart';
class MainPage extends ContentViewWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
@override
Future<HeaderInfo> getHeaderInfo(BuildContext context) async {
return HeaderInfo(
titleWidget: Container(
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 3),
child: Column(children: const [
Text(
'Zeile 1',
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
),
),
SizedBox(height: 5),
Text(
'Zeile 2',
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
),
),
]),
),
rightButtonEnabled: true,
rightButtonVisible: true,
rightButtonImage: Util.fetchFutureIcon(const Icon(Icons.info_outline, size: 20.0, color: Colors.white)),
rightButtonOnPressed: () async {
showInfosPopup(context);
});
}
}
class _MainPageState extends State<MainPage> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
getDefaultButton(
'Zugewiesene Aufträge',
image: Image.asset('assets/zugewiesene_auftraege.png', width: 30, height: 30),
() => {BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const AssignedJobsPage())}),
const SizedBox(height: 10),
getDefaultButton(
'Angenommene Aufträge',
image: Image.asset('assets/angenommene_auftraege.png', width: 30, height: 30),
() => {BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const AcceptedJobsPage())}),
const SizedBox(height: 10),
getDefaultButton(
'Erledigte Aufträge',
image: Image.asset('assets/erledigte_auftraege.png', width: 30, height: 30),
() => {BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage())}),
const SizedBox(height: 10),
getDefaultButton(
'Nachrichten',
image: Image.asset('assets/nachrichten.png', width: 30, height: 30),
() => {
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage())
}),
const SizedBox(height: 10),
getDefaultButton(
'Anfahrtsbereich',
image: Image.asset('assets/anfahrtsbereich.png', width: 30, height: 30),
() => {
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage())
}),
const SizedBox(height: 10),
getDefaultButton(
'Abmelden',
image: Image.asset('assets/abmelden.png', width: 30, height: 30),
() => {
_test()
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage())
}),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
color: Colors.transparent,
width: 2.0,
),
),
),
),
Image.asset(
'assets/sb_logo.png',
width: 100,
height: 100,
),
],
),
),
],
);
}
void _test() async {
var json = await rootBundle.loadString('assets/job.json');
var jsonMap = jsonDecode(json);
var payload = jsonMap["payload"];
var jobsPayload = JobsPayload.fromJson(payload);
if (jobsPayload.jobs != null) {
MyApp.isarInstance.writeTxnSync(() {
for (var job in jobsPayload.jobs as List<Job>) {
MyApp.isarInstance.jobs.putSync(job);
}
});
}
}
}
+169
View File
@@ -0,0 +1,169 @@
import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:stadtbote/model/job_tour.dart';
import '../main.dart';
import '../model/task_info.dart';
import '../tools/util.dart';
class TaskListPage extends ContentViewWidget {
const TaskListPage({super.key, required this.tour});
final JobTour tour;
@override
State<TaskListPage> createState() => _TaskListPageState();
@override
Future<HeaderInfo> getHeaderInfo(BuildContext context) async {
return HeaderInfo(
titleWidget: const Text(
'Liste der Aufgaben',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
),
),
rightButtonEnabled: false,
rightButtonVisible: false,
rightButtonImage: null,
rightButtonOnPressed: () async {
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: EmployeeEditProfileWidget());
});
}
}
class _TaskListPageState extends State<TaskListPage> {
late bool _initCompleted = false;
late List<TaskInfo> _taskList;
@override
void initState() {
Future.delayed(const Duration(seconds: 0), () async {
_taskList = await _fetchTaskList();
_initCompleted = true;
setState(() {});
});
super.initState();
}
@override
Widget build(BuildContext context) {
if (!_initCompleted) {
return Util.getWaitWidget(context);
}
var steps = _initSteps();
return Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
padding: const EdgeInsets.all(0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: steps,
),
),
);
}
List<Widget> _initSteps() {
List<Widget> steps = [];
for (int i=0; i<_taskList.length; i++) {
var taskInfo = _taskList[i];
steps.add(
ListTile(
minVerticalPadding: 0,
title: Container(
padding: const EdgeInsets.all(0),
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Stack(
children: [
Positioned(
left: 16.5,
top: i == 0 ? 5 : 0,
child: Container(
height: i == widget.tour.tasks.length - 1 ? 1: 60,
width: 6,
color: Colors.green
),
),
Column(
children: [
Container(
width: 40,
height: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey,
),
child: const Icon(Icons.check, size: 30.0, color: Colors.white),
),
],
),
],
),
const SizedBox(width: 20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
taskInfo.task.topic,
textAlign: TextAlign.left,
style: const TextStyle(
color: Colors.blue,
fontSize: 15.0,
),
),
Text(
taskInfo.additionalText ?? '',
textAlign: TextAlign.left,
style: const TextStyle(
color: Colors.blue,
fontSize: 12.0,
),
),
],
),
],
),
),
onTap: () {
print('1');
},
),
);
}
return steps;
}
Future<List<TaskInfo>> _fetchTaskList() async {
List<TaskInfo> taskList = [];
for(var task in widget.tour.tasks) {
var taskInfo = await MyApp.isarInstance.taskInfos.filter().sIdEqualTo(task.sId).findFirst();
taskInfo ??= TaskInfo();
taskInfo.task = task;
taskInfo.answer = null;
taskInfo.additionalText = null;
taskList.add(taskInfo);
}
return taskList;
}
}
+148
View File
@@ -0,0 +1,148 @@
import 'package:flutter/material.dart';
import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart';
import 'package:stadtbote/content_views/task_list_page.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:stadtbote/model/job_tour.dart';
import '../model/job.dart';
import '../popups/map_popup.dart';
import '../tools/constants.dart';
import '../tools/util.dart';
class TourDetailsPage extends ContentViewWidget {
const TourDetailsPage({super.key, required this.job, required this.tour});
final Job job;
final JobTour tour;
@override
State<TourDetailsPage> createState() => _TourDetailsPageState();
@override
Future<HeaderInfo> getHeaderInfo(BuildContext context) async {
return HeaderInfo(
titleWidget: const Text(
'Details der Station',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
),
),
rightButtonEnabled: false,
rightButtonVisible: false,
rightButtonImage: null,
rightButtonOnPressed: () async {
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: EmployeeEditProfileWidget());
});
}
}
class _TourDetailsPageState extends State<TourDetailsPage> {
late bool _initCompleted = false;
@override
void initState() {
Future.delayed(const Duration(seconds: 0), () async {
_initCompleted = true;
setState(() {});
});
super.initState();
}
@override
Widget build(BuildContext context) {
if (!_initCompleted) {
return Util.getWaitWidget(context);
}
var remark = "";
if (widget.tour.rem.isNotEmpty) {
for (var remRow in widget.tour.rem) {
remark += "$remRow\n";
}
} else {
remark = "* Keine Bemerkung vorhanden *";
}
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded(
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey, width: 0.5),
color: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(13))
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"${"Station ${widget.tour.sort}"} ${mapTourMode(widget.tour.mode)}",
textAlign: TextAlign.left,
),
Text(
widget.tour.comp,
textAlign: TextAlign.left,
),
Text(
widget.tour.person,
textAlign: TextAlign.left,
),
Text(
widget.tour.street,
textAlign: TextAlign.left,
),
Text(
widget.tour.city,
textAlign: TextAlign.left,
),
Text(
"Tel.: ${widget.tour.phone}",
textAlign: TextAlign.left,
),
Text(
"Komm-#: ${widget.tour.com}",
textAlign: TextAlign.left,
),
const SizedBox(height: 10),
getDefaultButton('Karte', () =>
{
showMapPopup(context, widget.tour, widget.job.tours)
}),
],
),
)
),
const SizedBox(height: 10),
Expanded(
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey, width: 0.5),
color: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(13))
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(remark),
]
),
),
),
const SizedBox(height: 10),
getDefaultButton('Weiter', () =>
{
BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TaskListPage(tour: widget.tour))
}),
],
),
);
}
}
+170
View File
@@ -0,0 +1,170 @@
import 'package:flutter/material.dart';
import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart';
import 'package:stadtbote/content_views/tour_details_page.dart';
import 'package:stadtbote/content_views/utils/content_view_widget.dart';
import 'package:stadtbote/content_views/utils/header_info.dart';
import 'package:stadtbote/model/job_tour.dart';
import '../model/job.dart';
import '../tools/constants.dart';
import '../tools/util.dart';
class TourListPage extends ContentViewWidget {
const TourListPage({super.key, required this.job});
final Job job;
@override
State<TourListPage> createState() => _TourListPageState();
@override
Future<HeaderInfo> getHeaderInfo(BuildContext context) async {
return HeaderInfo(
titleWidget: const Text(
'Liste der Stationen',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
),
),
rightButtonEnabled: false,
rightButtonVisible: false,
rightButtonImage: null,
rightButtonOnPressed: () async {
//BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: EmployeeEditProfileWidget());
});
}
}
class _TourListPageState extends State<TourListPage> {
late List<JobTour> _tours;
late bool _initCompleted = false;
@override
void initState() {
Future.delayed(const Duration(seconds: 0), () async {
_tours = widget.job.tours;
_initCompleted = true;
setState(() {});
});
super.initState();
}
@override
Widget build(BuildContext context) {
if (!_initCompleted) {
return Util.getWaitWidget(context);
}
late List<Widget> jobWidgets = _createjobWidgets();
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Container(
color: Colors.transparent,
child: Row(
children: [
Text(
widget.job.id.toString(),
textAlign: TextAlign.left,
),
],
),
),
Row(
children: [
Text(
widget.job.crFilter != null ? widget.job.crFilter.toString() : "Kein CR-Filter vorhanden",
textAlign: TextAlign.left,
),
],
),
Row(
children: [
const Icon(Icons.arrow_back, size: 30.0, color: Colors.black),
const SizedBox(width: 10),
Text(
widget.job.vhtId.toString()
),
],
),
Expanded(
child: ListView(
padding: const EdgeInsets.all(0),
children: jobWidgets
),
)
],
),
);
}
List<Widget> _createjobWidgets() {
List<Widget> jobWidgets = [];
for (var tour in _tours) {
Color color = Colors.transparent;
switch(tour.state) {
case 1:
color = Colors.lightGreen;
break;
default:
color = Colors.yellow;
break;
}
jobWidgets.add(
ListTile(
contentPadding: const EdgeInsets.all(0),
onTap: () {
_clicked(tour);
},
title: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey, width: 0.5),
color: color,
borderRadius: const BorderRadius.all(Radius.circular(13))
),
padding: const EdgeInsets.all(5.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"${"Station ${tour.sort}"} ${mapTourMode(tour.mode)}",
textAlign: TextAlign.left,
),
Text(
tour.comp,
textAlign: TextAlign.left,
),
Text(
tour.street,
textAlign: TextAlign.left,
),
Text(
tour.city,
textAlign: TextAlign.left,
),
],
),
)
),
);
}
return jobWidgets;
}
void _clicked(JobTour tour) {
BroadcastReceiver().publish<ContentViewWidget>(Constants.messageTopicPushContentView, arguments: TourDetailsPage(job: widget.job, tour: tour));
}
}
@@ -0,0 +1,13 @@
import 'package:flutter/cupertino.dart';
import 'header_info.dart';
abstract class ContentViewWidget extends StatefulWidget {
const ContentViewWidget({super.key});
Future<HeaderInfo> getHeaderInfo(BuildContext context);
void close() {
close();
}
}
+11
View File
@@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
class HeaderInfo {
late Widget titleWidget;
late bool rightButtonEnabled;
late bool rightButtonVisible;
late Future<Widget?>? rightButtonImage;
late Function rightButtonOnPressed;
HeaderInfo({required this.titleWidget, required this.rightButtonEnabled, required this.rightButtonVisible, this.rightButtonImage, required this.rightButtonOnPressed});
}
+17
View File
@@ -0,0 +1,17 @@
class WidgetStack<E> {
final _list = <E>[];
void push(E value) => _list.add(value);
E pop() => _list.removeLast();
E get peek => _list.last;
bool get isEmpty => _list.isEmpty;
bool get isNotEmpty => _list.isNotEmpty;
void clear() => _list.clear();
@override
String toString() => _list.toString();
}
+335
View File
@@ -0,0 +1,335 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart';
import 'package:isar/isar.dart';
import 'package:path_provider/path_provider.dart';
import 'package:stadtbote/model/task_info.dart';
import 'package:stadtbote/tools/colored_safe_area.dart';
import 'package:stadtbote/model/status.dart';
import 'package:stadtbote/tools/connection_status.dart';
import 'tools/mqtt_core.dart';
import 'content_views/main_page.dart';
import 'content_views/utils/content_view_widget.dart';
import 'content_views/utils/widget_stack.dart';
import 'model/job.dart';
import 'tools/constants.dart';
import 'tools/util.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final dir = await getApplicationDocumentsDirectory();
MyApp.isarInstance = await Isar.open([
StatusSchema,
JobSchema,
TaskInfoSchema
], directory: dir.path);
runZonedGuarded(() {
}, (error, stackTrace) {
_traceUncaughtExceptions(error, stackTrace);
});
MqttCore.setup();
runApp(const MyApp());
}
void _traceUncaughtExceptions(Object error, StackTrace stackTrace) {
Util.logException('Ein Fehler ist aufgetreten: $error');
Util.logException('Stack-Trace: $stackTrace');
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
static late Isar isarInstance;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Stadtbote',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Main(),
);
}
}
class Main extends StatefulWidget {
const Main({super.key});
@override
State<Main> createState() => _MainState();
}
class _MainState extends State<Main> {
late ContentViewWidget _currentContent;
late WidgetStack<ContentViewWidget> contentStack = WidgetStack();
late Widget _currentTitleWidget;
late Widget _leftIconButton;
late Widget _rightIconButton;
late bool _leftButtonVisible = false;
late bool _rightButtonVisible = false;
late Function _rightButtonOnPressed;
late Function _leftButtonOnPressed;
bool _initCompleted = false;
final ValueNotifier<bool> _connectionLostValueNotifier = ValueNotifier<bool>(false);
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
_initMessages();
_currentContent = const MainPage();
var headerInfo = await _currentContent.getHeaderInfo(context);
_currentTitleWidget = headerInfo.titleWidget;
_leftButtonVisible = false;
_leftIconButton = const Icon(Icons.arrow_back, size: 20.0, color: Colors.white);
_leftButtonOnPressed = () {
_popContentView();
};
_rightButtonVisible = headerInfo.rightButtonVisible;
_rightButtonOnPressed = headerInfo.rightButtonOnPressed;
if (headerInfo.rightButtonEnabled) {
_rightIconButton = await headerInfo.rightButtonImage as Widget;
}
_initCompleted = true;
setState(() {});
});
}
@override
void dispose() {
super.dispose();
//_subscription.cancel();
}
@override
Widget build(BuildContext context) {
if (!_initCompleted) {
return Util.getWaitWidget(context);
}
return ColoredSafeArea(
key: GlobalKey(),
child: WillPopScope(
onWillPop: () async {
return false;
},
child: Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(70),
child: ColoredSafeArea(
key: const Key("appBar"),
child: SizedBox(
height: 80,
child: Padding(
padding: const EdgeInsets.all(8),
child: Stack(
alignment: Alignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: _leftButtonVisible,
child: Container(
width: 40,
height: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
child: FittedBox(
child: GestureDetector(
onTap: () async {
_leftButtonOnPressed();
},
child: CircleAvatar(
radius: 15,
child: Padding(padding: const EdgeInsets.all(1.0), child: _leftIconButton),
),
),
),
),
),
Visibility(
visible: _rightButtonVisible,
child: Container(
width: 40,
height: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: FittedBox(
child: GestureDetector(
onTap: () async {
_rightButtonOnPressed();
},
child: CircleAvatar(
radius: 15,
child: Padding(padding: const EdgeInsets.all(1.0), child: _rightIconButton),
),
),
),
),
),
],
),
SizedBox(
height: 60,
width: 300,
child: Center(
heightFactor: 1,
child: _currentTitleWidget),
),
],
),
),
)),
),
body: Column(
children: [
ValueListenableBuilder<bool>(
valueListenable: _connectionLostValueNotifier,
builder: (context, value, child) {
return Visibility(
visible: value,
child: Container(
width: MediaQuery.of(context).size.width,
height: 30,
color: Colors.red,
child: const Center(
child: Text("*** OFFLINE ***",
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),),
),
),
);
},
),
Expanded(child: _currentContent),
],
),// This trailing comma makes auto-formatting nicer for build methods.
),
),
);
}
void _initMessages() {
BroadcastReceiver().subscribe<ContentViewWidget>(Constants.messageTopicPushContentView, (ContentViewWidget widget) {
_pushContentView(widget);
});
BroadcastReceiver().subscribe<ContentViewWidget>(Constants.messageTopicPopContentView, (ContentViewWidget widget) {
_popContentView();
});
BroadcastReceiver().subscribe<ContentViewWidget>(Constants.messageTopicReplaceContentView, (ContentViewWidget widget) {
_replaceContentView(widget);
});
BroadcastReceiver().subscribe<bool>(Constants.messageTopicHideRightButton, (hideButton) {
_hideRightButton(hideButton);
});
BroadcastReceiver().subscribe<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, (ConnectionStatus connectionStatus) {
_connectionStatusChanged(connectionStatus);
});
}
void _replaceContentView(ContentViewWidget widget) async {
Future.delayed(const Duration(seconds: 0), () async {
contentStack.clear();
setState(() {
_currentContent = widget;
});
var headerInfo = await _currentContent.getHeaderInfo(context);
_currentTitleWidget = headerInfo.titleWidget;
_rightButtonVisible = headerInfo.rightButtonVisible;
_rightButtonOnPressed = headerInfo.rightButtonOnPressed;
if (headerInfo.rightButtonEnabled) {
_rightIconButton = await headerInfo.rightButtonImage as Widget;
}
_leftButtonVisible = false;
setState(() {});
});
}
void _popContentView() {
Future.delayed(const Duration(seconds: 0), () async {
var previousContentView = contentStack.pop();
_currentContent = previousContentView;
var headerInfo = await _currentContent.getHeaderInfo(context);
_currentTitleWidget = headerInfo.titleWidget;
_rightButtonVisible = headerInfo.rightButtonVisible;
_rightButtonOnPressed = headerInfo.rightButtonOnPressed;
if (headerInfo.rightButtonEnabled) {
_rightIconButton = await headerInfo.rightButtonImage as Widget;
}
if (contentStack.isEmpty) {
_leftButtonVisible = false;
}
setState(() {});
});
}
void _pushContentView(ContentViewWidget widget) {
Future.delayed(const Duration(seconds: 0), () async {
contentStack.push(_currentContent);
_currentContent = widget;
var headerInfo = await _currentContent.getHeaderInfo(context);
_currentTitleWidget = headerInfo.titleWidget;
_rightButtonVisible = headerInfo.rightButtonVisible;
_rightButtonOnPressed = headerInfo.rightButtonOnPressed;
if (headerInfo.rightButtonEnabled) {
_rightIconButton = await headerInfo.rightButtonImage as Widget;
}
_leftButtonVisible = true;
setState(() {});
});
}
void _hideRightButton(bool hideButton) {
setState(() {
_rightButtonVisible = !hideButton;
});
}
void _connectionStatusChanged(ConnectionStatus connectionStatus) {
_connectionLostValueNotifier.value = connectionStatus.status == ConnectionStatusEnum.notConnected;
}
}
+22
View File
@@ -0,0 +1,22 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/device_object.dart';
part 'bootstrap_request.g.dart';
@JsonSerializable()
class BootstrapRequest {
late String app;
late int ver;
late String mqttClientId;
@JsonKey(name: 'device')
late DeviceObject deviceObject;
BootstrapRequest();
factory BootstrapRequest.fromJson(Map<String, dynamic> json) => _$BootstrapRequestFromJson(json);
Map<String, dynamic> toJson() => _$BootstrapRequestToJson(this);
}
+23
View File
@@ -0,0 +1,23 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'bootstrap_request.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
BootstrapRequest _$BootstrapRequestFromJson(Map<String, dynamic> json) =>
BootstrapRequest()
..app = json['app'] as String
..ver = json['ver'] as int
..mqttClientId = json['mqttClientId'] as String
..deviceObject =
DeviceObject.fromJson(json['device'] as Map<String, dynamic>);
Map<String, dynamic> _$BootstrapRequestToJson(BootstrapRequest instance) =>
<String, dynamic>{
'app': instance.app,
'ver': instance.ver,
'mqttClientId': instance.mqttClientId,
'device': instance.deviceObject,
};
+21
View File
@@ -0,0 +1,21 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/bootstrap_response_topics.dart';
import 'package:stadtbote/model/device_object.dart';
part 'bootstrap_response_config.g.dart';
@JsonSerializable()
class BootstrapResponseConfig
{
late String broker;
late BootstrapResponseTopics topics;
BootstrapResponseConfig();
factory BootstrapResponseConfig.fromJson(Map<String, dynamic> json) => _$BootstrapResponseConfigFromJson(json);
Map<String, dynamic> toJson() => _$BootstrapResponseConfigToJson(this);
}
@@ -0,0 +1,21 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'bootstrap_response_config.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
BootstrapResponseConfig _$BootstrapResponseConfigFromJson(
Map<String, dynamic> json) =>
BootstrapResponseConfig()
..broker = json['broker'] as String
..topics = BootstrapResponseTopics.fromJson(
json['topics'] as Map<String, dynamic>);
Map<String, dynamic> _$BootstrapResponseConfigToJson(
BootstrapResponseConfig instance) =>
<String, dynamic>{
'broker': instance.broker,
'topics': instance.topics,
};
+19
View File
@@ -0,0 +1,19 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/bootstrap_response_config.dart';
import 'package:stadtbote/model/device_object.dart';
part 'bootstrap_response_payload.g.dart';
@JsonSerializable()
class BootstrapResponsePayload
{
late BootstrapResponseConfig config;
BootstrapResponsePayload();
factory BootstrapResponsePayload.fromJson(Map<String, dynamic> json) => _$BootstrapResponsePayloadFromJson(json);
Map<String, dynamic> toJson() => _$BootstrapResponsePayloadToJson(this);
}
@@ -0,0 +1,19 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'bootstrap_response_payload.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
BootstrapResponsePayload _$BootstrapResponsePayloadFromJson(
Map<String, dynamic> json) =>
BootstrapResponsePayload()
..config = BootstrapResponseConfig.fromJson(
json['config'] as Map<String, dynamic>);
Map<String, dynamic> _$BootstrapResponsePayloadToJson(
BootstrapResponsePayload instance) =>
<String, dynamic>{
'config': instance.config,
};
+22
View File
@@ -0,0 +1,22 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/device_object.dart';
part 'bootstrap_response_topics.g.dart';
@JsonSerializable()
class BootstrapResponseTopics
{
@JsonKey(name: 'to_server')
late String toServer;
@JsonKey(name: 'from_server')
late String fromServer;
BootstrapResponseTopics();
factory BootstrapResponseTopics.fromJson(Map<String, dynamic> json) => _$BootstrapResponseTopicsFromJson(json);
Map<String, dynamic> toJson() => _$BootstrapResponseTopicsToJson(this);
}
@@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'bootstrap_response_topics.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
BootstrapResponseTopics _$BootstrapResponseTopicsFromJson(
Map<String, dynamic> json) =>
BootstrapResponseTopics()
..toServer = json['to_server'] as String
..fromServer = json['from_server'] as String;
Map<String, dynamic> _$BootstrapResponseTopicsToJson(
BootstrapResponseTopics instance) =>
<String, dynamic>{
'to_server': instance.toServer,
'from_server': instance.fromServer,
};
+18
View File
@@ -0,0 +1,18 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
part 'device_object.g.dart';
@JsonSerializable()
class DeviceObject {
late String model;
late String manufacturer;
late String os;
late String osVer;
DeviceObject();
factory DeviceObject.fromJson(Map<String, dynamic> json) => _$DeviceObjectFromJson(json);
Map<String, dynamic> toJson() => _$DeviceObjectToJson(this);
}
+21
View File
@@ -0,0 +1,21 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'device_object.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DeviceObject _$DeviceObjectFromJson(Map<String, dynamic> json) => DeviceObject()
..model = json['model'] as String
..manufacturer = json['manufacturer'] as String
..os = json['os'] as String
..osVer = json['osVer'] as String;
Map<String, dynamic> _$DeviceObjectToJson(DeviceObject instance) =>
<String, dynamic>{
'model': instance.model,
'manufacturer': instance.manufacturer,
'os': instance.os,
'osVer': instance.osVer,
};
+49
View File
@@ -0,0 +1,49 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/job_tour.dart';
import 'package:stadtbote/model/tour_position.dart';
import 'package:stadtbote/model/tour_task.dart';
part 'job.g.dart';
@JsonSerializable()
class JobsPayload {
List<Job>? jobs;
JobsPayload({this.jobs});
factory JobsPayload.fromJson(Map<String, dynamic> json) => _$JobsPayloadFromJson(json);
Map<String, dynamic> toJson() => _$JobsPayloadToJson(this);
}
@collection
@JsonSerializable()
class Job {
late Id id;
@JsonKey(name: 'ver')
late int ver;
@JsonKey(name: 'state')
late int state;
@JsonKey(name: 'cr_filter')
late String? crFilter;
@JsonKey(name: 'ordertime')
late String ordertime;
@JsonKey(name: 'offs_warn')
late int offsWarn;
@JsonKey(name: 'global')
late bool global;
@JsonKey(name: 'vht_id')
late int vhtId;
@JsonKey(name: 'rem')
late List<String> rem;
@JsonKey(name: 'tours')
late List<JobTour> tours;
Job();
factory Job.fromJson(Map<String, dynamic> json) => _$JobFromJson(json);
Map<String, dynamic> toJson() => _$JobToJson(this);
}
+1474
View File
File diff suppressed because it is too large. Load diff
+30
View File
@@ -0,0 +1,30 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:stadtbote/model/tour_position.dart';
import 'package:stadtbote/model/tour_task.dart';
part 'job_tour.g.dart';
@embedded
@JsonSerializable()
class JobTour {
late int id;
late int sort;
late int state;
late String mode;
late String comp;
late String person;
late String phone;
late String street;
late String city;
late String com;
late TourPosition? pos;
late List<String> rem;
late List<TourTask> tasks;
JobTour();
factory JobTour.fromJson(Map<String, dynamic> json) => _$JobTourFromJson(json);
Map<String, dynamic> toJson() => _$JobTourToJson(this);
}
File diff suppressed because it is too large. Load diff
+104
View File
@@ -0,0 +1,104 @@
import 'package:isar/isar.dart';
import 'package:stadtbote/model/short_poll_question.dart';
part 'short_poll.g.dart';
@collection
class ShortPoll {
late Id id;
late int type;
late String text;
late String title;
late int validFrom;
late int validTo;
late int? imageWidth;
late int? imageHeight;
late String? imageModified;
late bool? commentsAllowed;
late bool read = false;
late String? url;
late String? pdfName;
late bool voted;
late int numberOfVotes;
late List<ShortPollQuestion> questions;
ShortPoll({
required this.id,
required this.type,
required this.text,
required this.title,
required this.validFrom,
required this.validTo,
this.imageWidth,
this.imageHeight,
this.imageModified,
this.commentsAllowed,
required this.read,
this.url,
this.pdfName,
required this.voted,
required this.numberOfVotes,
required this.questions,
});
/*factory ShortPoll.fromJson(Map<String, dynamic> json) {
List<ShortPollQuestion> questions = [];
if (json["answers"] != null) {
questions = List<ShortPollQuestion>.from(
json["answers"].map((x) => ShortPollQuestion.fromJson(x)));
}
return ShortPoll(
id: json["id"],
type: json["type"],
text: json["text"],
title: json["title"],
validFrom: json["validFrom"],
validTo: json["validTo"],
imageWidth: json["imageWidth"],
imageHeight: json["imageHeight"],
imageModified: json["imageModified"],
commentsAllowed: json["commentsAllowed"],
read: json["read"],
url: json["url"],
pdfName: json["pdfName"],
voted: json["voted"],
numberOfVotes: json["numberOfVotes"],
questions: questions,
);
}
Map<String, dynamic> toJson() => {
"id": id,
"type": type,
"text": text,
"title": title,
"validFrom": validFrom,
"validTo": validTo,
"imageWidth": imageWidth,
"imageHeight": imageHeight,
"imageModified": imageModified,
"commentsAllowed": commentsAllowed,
"read": read,
"url": url,
"pdfName": pdfName,
"voted": voted,
"numberOfVotes": numberOfVotes,
};*/
}
File diff suppressed because it is too large. Load diff
+35
View File
@@ -0,0 +1,35 @@
import 'package:isar/isar.dart';
part 'short_poll_question.g.dart';
@embedded
class ShortPollQuestion {
late int questionId;
late int shortPollId;
late String text;
/*@Ignore()
late String imageName = "assets/radiobutton.png";
@Ignore()
late bool selected = false;*/
ShortPollQuestion();
/*factory ShortPollQuestion.fromJson(Map<String, dynamic> json) {
var shortPollQuestion = ShortPollQuestion();
shortPollQuestion.questionId = json['id'];
shortPollQuestion.shortPollId = json["shortPollId"];
shortPollQuestion.text = json["text"];
return shortPollQuestion;
}
Map<String, dynamic> toJson() => {
"id": questionId,
"short_poll_id": shortPollId,
"text": text,
};*/
}
+342
View File
@@ -0,0 +1,342 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'short_poll_question.dart';
// **************************************************************************
// IsarEmbeddedGenerator
// **************************************************************************
// 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
const ShortPollQuestionSchema = Schema(
name: r'ShortPollQuestion',
id: 899576032619711410,
properties: {
r'questionId': PropertySchema(
id: 0,
name: r'questionId',
type: IsarType.long,
),
r'shortPollId': PropertySchema(
id: 1,
name: r'shortPollId',
type: IsarType.long,
),
r'text': PropertySchema(
id: 2,
name: r'text',
type: IsarType.string,
)
},
estimateSize: _shortPollQuestionEstimateSize,
serialize: _shortPollQuestionSerialize,
deserialize: _shortPollQuestionDeserialize,
deserializeProp: _shortPollQuestionDeserializeProp,
);
int _shortPollQuestionEstimateSize(
ShortPollQuestion object,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
var bytesCount = offsets.last;
bytesCount += 3 + object.text.length * 3;
return bytesCount;
}
void _shortPollQuestionSerialize(
ShortPollQuestion object,
IsarWriter writer,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
writer.writeLong(offsets[0], object.questionId);
writer.writeLong(offsets[1], object.shortPollId);
writer.writeString(offsets[2], object.text);
}
ShortPollQuestion _shortPollQuestionDeserialize(
Id id,
IsarReader reader,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
final object = ShortPollQuestion();
object.questionId = reader.readLong(offsets[0]);
object.shortPollId = reader.readLong(offsets[1]);
object.text = reader.readString(offsets[2]);
return object;
}
P _shortPollQuestionDeserializeProp<P>(
IsarReader reader,
int propertyId,
int offset,
Map<Type, List<int>> allOffsets,
) {
switch (propertyId) {
case 0:
return (reader.readLong(offset)) as P;
case 1:
return (reader.readLong(offset)) as P;
case 2:
return (reader.readString(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
}
extension ShortPollQuestionQueryFilter
on QueryBuilder<ShortPollQuestion, ShortPollQuestion, QFilterCondition> {
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
questionIdEqualTo(int value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'questionId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
questionIdGreaterThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'questionId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
questionIdLessThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'questionId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
questionIdBetween(
int lower,
int upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'questionId',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
shortPollIdEqualTo(int value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'shortPollId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
shortPollIdGreaterThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'shortPollId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
shortPollIdLessThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'shortPollId',
value: value,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
shortPollIdBetween(
int lower,
int upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'shortPollId',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, 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<ShortPollQuestion, ShortPollQuestion, 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<ShortPollQuestion, ShortPollQuestion, 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<ShortPollQuestion, ShortPollQuestion, 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<ShortPollQuestion, ShortPollQuestion, 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<ShortPollQuestion, ShortPollQuestion, 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<ShortPollQuestion, ShortPollQuestion, 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<ShortPollQuestion, ShortPollQuestion, 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<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textIsEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'text',
value: '',
));
});
}
QueryBuilder<ShortPollQuestion, ShortPollQuestion, QAfterFilterCondition>
textIsNotEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
property: r'text',
value: '',
));
});
}
}
extension ShortPollQuestionQueryObject
on QueryBuilder<ShortPollQuestion, ShortPollQuestion, QFilterCondition> {}
+31
View File
@@ -0,0 +1,31 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
part 'status.g.dart';
@collection
@JsonSerializable()
class Status {
final Id id = 0;
@JsonKey(name: 'cust_id')
int? custId;
@JsonKey(name: 'hq_id')
int? hqId;
@JsonKey(name: 'usr_id')
int? usrId;
@JsonKey(name: 'cr_id')
int? crId;
@JsonKey(name: 'sid')
String? sid;
@JsonKey(name: 'vht_id')
int? vhtId;
@JsonKey(name: 'loc_zip')
String? locZip;
Status({this.hqId, this.usrId, this.crId, this.sid, this.vhtId, this.locZip, this.custId});
factory Status.fromJson(Map<String, dynamic> json) => _$StatusFromJson(json);
Map<String, dynamic> toJson() => _$StatusToJson(this);
}
File diff suppressed because it is too large. Load diff
+22
View File
@@ -0,0 +1,22 @@
import 'package:isar/isar.dart';
import 'package:stadtbote/model/tour_task.dart';
part 'task_info.g.dart';
@collection
class TaskInfo {
late Id id;
late int sId;
late String? additionalText;
late String? answer;
@ignore
late TourTask task;
TaskInfo();
}
+752
View File
@@ -0,0 +1,752 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'task_info.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 GetTaskInfoCollection on Isar {
IsarCollection<TaskInfo> get taskInfos => this.collection();
}
const TaskInfoSchema = CollectionSchema(
name: r'TaskInfo',
id: 3341968002652240051,
properties: {
r'additionalText': PropertySchema(
id: 0,
name: r'additionalText',
type: IsarType.string,
),
r'answer': PropertySchema(
id: 1,
name: r'answer',
type: IsarType.string,
),
r'sId': PropertySchema(
id: 2,
name: r'sId',
type: IsarType.long,
)
},
estimateSize: _taskInfoEstimateSize,
serialize: _taskInfoSerialize,
deserialize: _taskInfoDeserialize,
deserializeProp: _taskInfoDeserializeProp,
idName: r'id',
indexes: {},
links: {},
embeddedSchemas: {},
getId: _taskInfoGetId,
getLinks: _taskInfoGetLinks,
attach: _taskInfoAttach,
version: '3.1.0+1',
);
int _taskInfoEstimateSize(
TaskInfo object,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
var bytesCount = offsets.last;
{
final value = object.additionalText;
if (value != null) {
bytesCount += 3 + value.length * 3;
}
}
{
final value = object.answer;
if (value != null) {
bytesCount += 3 + value.length * 3;
}
}
return bytesCount;
}
void _taskInfoSerialize(
TaskInfo object,
IsarWriter writer,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
writer.writeString(offsets[0], object.additionalText);
writer.writeString(offsets[1], object.answer);
writer.writeLong(offsets[2], object.sId);
}
TaskInfo _taskInfoDeserialize(
Id id,
IsarReader reader,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
final object = TaskInfo();
object.additionalText = reader.readStringOrNull(offsets[0]);
object.answer = reader.readStringOrNull(offsets[1]);
object.id = id;
object.sId = reader.readLong(offsets[2]);
return object;
}
P _taskInfoDeserializeProp<P>(
IsarReader reader,
int propertyId,
int offset,
Map<Type, List<int>> allOffsets,
) {
switch (propertyId) {
case 0:
return (reader.readStringOrNull(offset)) as P;
case 1:
return (reader.readStringOrNull(offset)) as P;
case 2:
return (reader.readLong(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
}
Id _taskInfoGetId(TaskInfo object) {
return object.id;
}
List<IsarLinkBase<dynamic>> _taskInfoGetLinks(TaskInfo object) {
return [];
}
void _taskInfoAttach(IsarCollection<dynamic> col, Id id, TaskInfo object) {
object.id = id;
}
extension TaskInfoQueryWhereSort on QueryBuilder<TaskInfo, TaskInfo, QWhere> {
QueryBuilder<TaskInfo, TaskInfo, QAfterWhere> anyId() {
return QueryBuilder.apply(this, (query) {
return query.addWhereClause(const IdWhereClause.any());
});
}
}
extension TaskInfoQueryWhere on QueryBuilder<TaskInfo, TaskInfo, QWhereClause> {
QueryBuilder<TaskInfo, TaskInfo, QAfterWhereClause> idEqualTo(Id id) {
return QueryBuilder.apply(this, (query) {
return query.addWhereClause(IdWhereClause.between(
lower: id,
upper: id,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, 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<TaskInfo, TaskInfo, QAfterWhereClause> idGreaterThan(Id id,
{bool include = false}) {
return QueryBuilder.apply(this, (query) {
return query.addWhereClause(
IdWhereClause.greaterThan(lower: id, includeLower: include),
);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterWhereClause> idLessThan(Id id,
{bool include = false}) {
return QueryBuilder.apply(this, (query) {
return query.addWhereClause(
IdWhereClause.lessThan(upper: id, includeUpper: include),
);
});
}
QueryBuilder<TaskInfo, TaskInfo, 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 TaskInfoQueryFilter
on QueryBuilder<TaskInfo, TaskInfo, QFilterCondition> {
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'additionalText',
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'additionalText',
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> additionalTextEqualTo(
String? value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'additionalText',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextGreaterThan(
String? value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'additionalText',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextLessThan(
String? value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'additionalText',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> additionalTextBetween(
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'additionalText',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextStartsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.startsWith(
property: r'additionalText',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextEndsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.endsWith(
property: r'additionalText',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextContains(String value, {bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.contains(
property: r'additionalText',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> additionalTextMatches(
String pattern,
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.matches(
property: r'additionalText',
wildcard: pattern,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextIsEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'additionalText',
value: '',
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition>
additionalTextIsNotEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
property: r'additionalText',
value: '',
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'answer',
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'answer',
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerEqualTo(
String? value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'answer',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerGreaterThan(
String? value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'answer',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerLessThan(
String? value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'answer',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerBetween(
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'answer',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerStartsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.startsWith(
property: r'answer',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerEndsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.endsWith(
property: r'answer',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerContains(
String value,
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.contains(
property: r'answer',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerMatches(
String pattern,
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.matches(
property: r'answer',
wildcard: pattern,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerIsEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'answer',
value: '',
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> answerIsNotEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
property: r'answer',
value: '',
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> idEqualTo(Id value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'id',
value: value,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, 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<TaskInfo, TaskInfo, 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<TaskInfo, TaskInfo, 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<TaskInfo, TaskInfo, QAfterFilterCondition> sIdEqualTo(
int value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'sId',
value: value,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> sIdGreaterThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'sId',
value: value,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> sIdLessThan(
int value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'sId',
value: value,
));
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterFilterCondition> sIdBetween(
int lower,
int upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'sId',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
}
extension TaskInfoQueryObject
on QueryBuilder<TaskInfo, TaskInfo, QFilterCondition> {}
extension TaskInfoQueryLinks
on QueryBuilder<TaskInfo, TaskInfo, QFilterCondition> {}
extension TaskInfoQuerySortBy on QueryBuilder<TaskInfo, TaskInfo, QSortBy> {
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> sortByAdditionalText() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'additionalText', Sort.asc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> sortByAdditionalTextDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'additionalText', Sort.desc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> sortByAnswer() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'answer', Sort.asc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> sortByAnswerDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'answer', Sort.desc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> sortBySId() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sId', Sort.asc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> sortBySIdDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sId', Sort.desc);
});
}
}
extension TaskInfoQuerySortThenBy
on QueryBuilder<TaskInfo, TaskInfo, QSortThenBy> {
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> thenByAdditionalText() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'additionalText', Sort.asc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> thenByAdditionalTextDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'additionalText', Sort.desc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> thenByAnswer() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'answer', Sort.asc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> thenByAnswerDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'answer', Sort.desc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> thenById() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'id', Sort.asc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> thenByIdDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'id', Sort.desc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> thenBySId() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sId', Sort.asc);
});
}
QueryBuilder<TaskInfo, TaskInfo, QAfterSortBy> thenBySIdDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sId', Sort.desc);
});
}
}
extension TaskInfoQueryWhereDistinct
on QueryBuilder<TaskInfo, TaskInfo, QDistinct> {
QueryBuilder<TaskInfo, TaskInfo, QDistinct> distinctByAdditionalText(
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'additionalText',
caseSensitive: caseSensitive);
});
}
QueryBuilder<TaskInfo, TaskInfo, QDistinct> distinctByAnswer(
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'answer', caseSensitive: caseSensitive);
});
}
QueryBuilder<TaskInfo, TaskInfo, QDistinct> distinctBySId() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'sId');
});
}
}
extension TaskInfoQueryProperty
on QueryBuilder<TaskInfo, TaskInfo, QQueryProperty> {
QueryBuilder<TaskInfo, int, QQueryOperations> idProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'id');
});
}
QueryBuilder<TaskInfo, String?, QQueryOperations> additionalTextProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'additionalText');
});
}
QueryBuilder<TaskInfo, String?, QQueryOperations> answerProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'answer');
});
}
QueryBuilder<TaskInfo, int, QQueryOperations> sIdProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'sId');
});
}
}
+18
View File
@@ -0,0 +1,18 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
part 'tour_position.g.dart';
@embedded
@JsonSerializable()
class TourPosition {
late double lat;
late double long;
TourPosition();
factory TourPosition.fromJson(Map<String, dynamic> json) => _$TourPositionFromJson(json);
Map<String, dynamic> toJson() => _$TourPositionToJson(this);
}
+224
View File
@@ -0,0 +1,224 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'tour_position.dart';
// **************************************************************************
// IsarEmbeddedGenerator
// **************************************************************************
// 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
const TourPositionSchema = Schema(
name: r'TourPosition',
id: -30020497969214738,
properties: {
r'lat': PropertySchema(
id: 0,
name: r'lat',
type: IsarType.double,
),
r'long': PropertySchema(
id: 1,
name: r'long',
type: IsarType.double,
)
},
estimateSize: _tourPositionEstimateSize,
serialize: _tourPositionSerialize,
deserialize: _tourPositionDeserialize,
deserializeProp: _tourPositionDeserializeProp,
);
int _tourPositionEstimateSize(
TourPosition object,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
var bytesCount = offsets.last;
return bytesCount;
}
void _tourPositionSerialize(
TourPosition object,
IsarWriter writer,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
writer.writeDouble(offsets[0], object.lat);
writer.writeDouble(offsets[1], object.long);
}
TourPosition _tourPositionDeserialize(
Id id,
IsarReader reader,
List<int> offsets,
Map<Type, List<int>> allOffsets,
) {
final object = TourPosition();
object.lat = reader.readDouble(offsets[0]);
object.long = reader.readDouble(offsets[1]);
return object;
}
P _tourPositionDeserializeProp<P>(
IsarReader reader,
int propertyId,
int offset,
Map<Type, List<int>> allOffsets,
) {
switch (propertyId) {
case 0:
return (reader.readDouble(offset)) as P;
case 1:
return (reader.readDouble(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
}
extension TourPositionQueryFilter
on QueryBuilder<TourPosition, TourPosition, QFilterCondition> {
QueryBuilder<TourPosition, TourPosition, QAfterFilterCondition> latEqualTo(
double value, {
double epsilon = Query.epsilon,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'lat',
value: value,
epsilon: epsilon,
));
});
}
QueryBuilder<TourPosition, TourPosition, QAfterFilterCondition>
latGreaterThan(
double value, {
bool include = false,
double epsilon = Query.epsilon,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'lat',
value: value,
epsilon: epsilon,
));
});
}
QueryBuilder<TourPosition, TourPosition, QAfterFilterCondition> latLessThan(
double value, {
bool include = false,
double epsilon = Query.epsilon,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'lat',
value: value,
epsilon: epsilon,
));
});
}
QueryBuilder<TourPosition, TourPosition, QAfterFilterCondition> latBetween(
double lower,
double upper, {
bool includeLower = true,
bool includeUpper = true,
double epsilon = Query.epsilon,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'lat',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
epsilon: epsilon,
));
});
}
QueryBuilder<TourPosition, TourPosition, QAfterFilterCondition> longEqualTo(
double value, {
double epsilon = Query.epsilon,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'long',
value: value,
epsilon: epsilon,
));
});
}
QueryBuilder<TourPosition, TourPosition, QAfterFilterCondition>
longGreaterThan(
double value, {
bool include = false,
double epsilon = Query.epsilon,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'long',
value: value,
epsilon: epsilon,
));
});
}
QueryBuilder<TourPosition, TourPosition, QAfterFilterCondition> longLessThan(
double value, {
bool include = false,
double epsilon = Query.epsilon,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'long',
value: value,
epsilon: epsilon,
));
});
}
QueryBuilder<TourPosition, TourPosition, QAfterFilterCondition> longBetween(
double lower,
double upper, {
bool includeLower = true,
bool includeUpper = true,
double epsilon = Query.epsilon,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'long',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
epsilon: epsilon,
));
});
}
}
extension TourPositionQueryObject
on QueryBuilder<TourPosition, TourPosition, QFilterCondition> {}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
TourPosition _$TourPositionFromJson(Map<String, dynamic> json) => TourPosition()
..lat = (json['lat'] as num).toDouble()
..long = (json['long'] as num).toDouble();
Map<String, dynamic> _$TourPositionToJson(TourPosition instance) =>
<String, dynamic>{
'lat': instance.lat,
'long': instance.long,
};
+32
View File
@@ -0,0 +1,32 @@
import 'package:isar/isar.dart';
import 'package:json_annotation/json_annotation.dart';
part 'tour_task.g.dart';
@embedded
@JsonSerializable()
class TourTask {
@JsonKey(name: 's_id')
late int sId;
late int type;
late String topic;
late bool? opt;
late bool? reenter;
late int? min;
late int? max;
@JsonKey(name: 'max_len')
late int? maxLen;
late bool? rt;
late bool? track;
late List<String>? txt;
@JsonKey(name: 'task_arrival')
late int? taskArrival;
@JsonKey(name: 'task_fin_work')
late int? taskFinWork;
TourTask();
factory TourTask.fromJson(Map<String, dynamic> json) => _$TourTaskFromJson(json);
Map<String, dynamic> toJson() => _$TourTaskToJson(this);
}
File diff suppressed because it is too large. Load diff
+56
View File
@@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import 'package:kumi_popup_window/kumi_popup_window.dart';
void showInfosPopup(BuildContext context) {
showPopupWindow(
context,
//childSize:Size(240, MediaQuery.of(context).size.width * 0.8),
gravity: KumiPopupGravity.center,
//curve: Curves.elasticOut,
bgColor: Colors.grey.withOpacity(0.5),
clickOutDismiss: true,
clickBackDismiss: true,
customAnimation: false,
customPop: false,
customPage: false,
// targetRenderBox: (btnKey.currentContext.findRenderObject() as RenderBox),
//needSafeDisplay: true,
underStatusBar: false,
underAppBar: false,
//offsetX: -180,
//offsetY: 50,
duration: const Duration(milliseconds: 200),
onShowStart: (pop) {},
onShowFinish: (pop) {},
onDismissStart: (pop) {},
onDismissFinish: (pop) {},
onClickOut: (pop) {},
onClickBack: (pop) {},
childFun: (pop) {
return SizedBox(
key: GlobalKey(),
height: MediaQuery.of(context).size.height * 0.6,
width: MediaQuery.of(context).size.width * 0.8,
child: Container(
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.red,
border: Border.all(
color: Colors.grey,
width: 0.5,
),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
children: const [
Text('Dies sind die Infos\nBla')
],
),
),
)
);
},
);
}
+198
View File
@@ -0,0 +1,198 @@
import 'dart:async';
import 'package:animated_toggle_switch/animated_toggle_switch.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:kumi_popup_window/kumi_popup_window.dart';
import 'package:latlong2/latlong.dart';
import '../model/job_tour.dart';
void showMapPopup(BuildContext context, JobTour currentTour, List<JobTour> tourList) {
showPopupWindow(
context,
//childSize:Size(240, 800),
gravity: KumiPopupGravity.center,
//curve: Curves.elasticOut,
bgColor: Colors.grey.withOpacity(0.5),
clickOutDismiss: true,
clickBackDismiss: true,
customAnimation: false,
customPop: false,
customPage: false,
// targetRenderBox: (btnKey.currentContext.findRenderObject() as RenderBox),
//needSafeDisplay: true,
underStatusBar: false,
underAppBar: false,
//offsetX: -180,
//offsetY: 50,
duration: const Duration(milliseconds: 300),
onShowStart: (pop) {},
onShowFinish: (pop) {},
onDismissStart: (pop) {},
onDismissFinish: (pop) {},
onClickOut: (pop) {},
onClickBack: (pop) {},
childFun: (pop) {
var mapController = MapController();
Map<int, StreamController<bool>> streamController = {};
List<Widget> tourWidgets = [];
for(JobTour tour in tourList) {
var currentStreamController = StreamController<bool>();
streamController[tour.sort] = currentStreamController;
tourWidgets.add(
GestureDetector(
onTap: () async {
mapController.move(LatLng(tour.pos!.lat, tour.pos!.long), mapController.zoom);
streamController[currentTour.sort]!.sink.add(false);
currentTour = tour;
streamController[tour.sort]!.sink.add(true);
},
child: SizedBox(
width: 70,
height: 80,
child: Column(
children: [
Container(
height: 50,
width: 70,
color: Colors.transparent,
child: const Icon(
Icons.person_pin_circle,
color: Colors.blue,
size: 56,
),
),
const SizedBox(height: 2),
SizedBox(
height: 12.0,
width: 70,
child: Text(
"Tour ${tour.sort}",
softWrap: true,
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.black,
fontSize: 10.0,
),
),
),
StreamBuilder<bool>(
stream: currentStreamController.stream,
builder: (context, snapshot) {
bool tourSelected = tour.sort == currentTour.sort;
if (snapshot.hasData) {
tourSelected = snapshot.data as bool;
}
return Container(
height: 2,
color: tourSelected ? Colors.green : Colors.transparent,
);
}
),
],
),
),
),
);
}
final ValueNotifier<bool> valueNotifier = ValueNotifier<bool>(true);
return Container(
padding: const EdgeInsets.fromLTRB(30, 0, 30, 0),
key: GlobalKey(),
height: MediaQuery.of(context).size.height * 0.6,
child: Container(
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(
color: Colors.grey,
width: 0.5,
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
SizedBox(
height: 80,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: tourWidgets,
),
)
),
Row(
children: [
Expanded(
child: ValueListenableBuilder<bool>(
valueListenable: valueNotifier,
builder: (context, value, child) {
return AnimatedToggleSwitch<bool>.dual(
current: value,
first: true,
second: false,
dif: 0.0,
borderColor: Colors.transparent,
borderWidth: 5.0,
height: 25,
boxShadow: const [
BoxShadow(
color: Colors.black26,
spreadRadius: 1,
blurRadius: 2,
offset: Offset(0, 1.5),
),
],
onChanged: (b) {
valueNotifier.value = b;
mapController.move(mapController.center, b ? 14.0 : 16.0);
},
colorBuilder: (b) => b ? Colors.red : Colors.green,
textBuilder: (value) => value
? const Center(child: Text('Fern'))
: const Center(child: Text('Nah')),
);
},
),
),
],
),
const SizedBox(height: 10),
Expanded(
child:
AbsorbPointer(
absorbing: true,
child: FlutterMap(
mapController: mapController,
options: MapOptions(
center: LatLng(currentTour.pos!.lat, currentTour.pos!.long),
zoom: 14,
),
children: [
TileLayer(
urlTemplate: 'https://google-maps.assecutor.de/vt/lyrs=m@130&hl=en&x={x}&y={y}&z={z}',
userAgentPackageName: 'com.example.app',
),
],
),
),
),
],
),
),
)
);
},
);
}
+18
View File
@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';
class ColoredSafeArea extends StatelessWidget {
final Widget child;
const ColoredSafeArea({required Key key, required this.child})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).colorScheme.primaryContainer,
child: SafeArea(
child: child,
),
);
}
}
+10
View File
@@ -0,0 +1,10 @@
enum ConnectionStatusEnum {
notConnected,
connected
}
class ConnectionStatus {
ConnectionStatus({required this.status});
final ConnectionStatusEnum status;
}
+11
View File
@@ -0,0 +1,11 @@
class Constants {
static const String messageTopicConnectionStatusChanged = "connection_status_changed";
static const String messageTopicPushContentView = "push_content_view";
static const String messageTopicPopContentView = "pop_content_view";
static const String messageTopicReplaceContentView = "replace_content_view";
static const String messageTopicHideRightButton = "hide_right_button";
static const String messageShowPopup = "show_popup";
//static const String topicToServer = "/app/100/2/208738/to_server";
//static const String topicFromServer = "/app/100/2/208738/from_server";
}
+214
View File
@@ -0,0 +1,214 @@
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
import 'package:stadtbote/model/bootstrap_request.dart';
import 'package:stadtbote/model/bootstrap_response_payload.dart';
import 'package:stadtbote/model/device_object.dart';
import 'package:stadtbote/model/job.dart';
import 'package:stadtbote/tools/connection_status.dart';
import 'package:typed_data/typed_buffers.dart';
import 'package:http/http.dart' as http;
import '../main.dart';
import '../model/status.dart';
import 'constants.dart';
import 'util.dart';
class MqttCore {
static late MqttCore instance;
late String _brokerUri;
late int _brokerPort;
late String _fromServerTopic;
late String _toServerTopic;
late MqttServerClient _mqttClient;
late int _reconnectDelay = 0;
MqttCore() {
_processBootstrap();
}
static setup() {
instance = MqttCore();
}
_connectToBroker() async {
try {
String clientId = await Util.getAppUuid();
Util.logInfo("client id: $clientId");
_mqttClient = MqttServerClient.withPort(_brokerUri, clientId, _brokerPort);
_mqttClient.logging(on: false);
_mqttClient.keepAlivePeriod = 20;
_mqttClient.autoReconnect = false;
_mqttClient.onDisconnected = _clientDisconnected;
_mqttClient.connectionMessage = MqttConnectMessage()
.withClientIdentifier('clientId')
.withWillQos(MqttQos.atMostOnce)
.withWillTopic('willTopic')
.withWillMessage('willMessage')
.authenticateAs("app", "apppwd");
await _mqttClient.connect();
if (_mqttClient.connectionStatus?.state == MqttConnectionState.connected) {
Util.logInfo('Verbunden mit dem MQTT-Broker!');
_reconnectDelay = 0;
_setupSubscriptions();
} else {
Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!');
BroadcastReceiver().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
_startReconnectTimer();
}
} catch (ex) {
_startReconnectTimer();
Util.logInfo('Verbindung zum MQTT-Broker fehlgeschlagen!: $ex');
BroadcastReceiver().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
}
}
publishText(String topic, String text) {
try {
var buffer = Uint8Buffer();
buffer.addAll(text.codeUnits);
_mqttClient.publishMessage(topic, MqttQos.exactlyOnce, buffer);
} catch (e) {
Util.logException(e.toString());
}
}
void _setupSubscriptions() async {
Util.logInfo('_setupSubscriptions called');
_mqttClient.updates?.listen((List<MqttReceivedMessage<MqttMessage>> c) {
try {
final MqttPublishMessage message = c[0].payload as MqttPublishMessage;
final payload = MqttPublishPayload.bytesToStringAsString(message.payload.message);
var topic = message.variableHeader?.topicName;
Util.logInfo('message received');
Util.logInfo('topic: $topic');
Util.logInfo('payload: $payload');
Map<String, dynamic> messageData = jsonDecode(payload);
for (var entry in messageData.keys) {
if (entry == 'payload') {
var payload = messageData[entry];
for (var payloadEntry in payload.keys) {
var payloadData = payload[payloadEntry];
switch(payloadEntry) {
case 'session':
_sessionMessageReceived(payloadData);
break;
case 'jobs':
_jobMessageReceived(payloadData);
break;
default:
Util.logInfo('Unknown topic: $payloadEntry');
break;
}
}
}
}
} catch(ex) {
Util.logException(ex.toString());
}
});
_mqttClient.subscribe(_fromServerTopic, MqttQos.exactlyOnce);
Util.logInfo('subscribed to topic: $_fromServerTopic');
BroadcastReceiver().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.connected));
}
void _sessionMessageReceived(payloadData) async {
var statusMessage = Status.fromJson(payloadData['status']);
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.status.put(statusMessage);
});
}
void _jobMessageReceived(payloadData) async {
for (var foundJobData in payloadData) {
var newJob = Job.fromJson(foundJobData);
await MyApp.isarInstance.writeTxn(() async {
await MyApp.isarInstance.jobs.put(newJob);
});
}
}
void _startReconnectTimer() {
Util.logInfo("_startReconnectTimer called");
_reconnectDelay = min(_reconnectDelay + 1, 30);
Timer(Duration(seconds: _reconnectDelay), () {
_processBootstrap();
});
}
void _clientDisconnected() {
Util.logInfo("_clientDisconnected called");
BroadcastReceiver().publish<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, arguments: ConnectionStatus(status: ConnectionStatusEnum.notConnected));
_startReconnectTimer();
}
void _processBootstrap() async {
try {
var deviceObject = DeviceObject();
deviceObject.manufacturer = "sven";
deviceObject.model = "emulator";
deviceObject.os = "hat es";
deviceObject.osVer = "0.0";
var handshakeMessage = BootstrapRequest();
handshakeMessage.app = "sb";
handshakeMessage.mqttClientId = "12345";
handshakeMessage.deviceObject = deviceObject;
handshakeMessage.ver = 200;
var jsonMap = handshakeMessage.toJson();
var json = jsonEncode(jsonMap);
var uri = "https://init-x.assecutor.de/bootstrap?get_mqtt_broker=$json";
print("Bootstrap request: $uri");
var response = await http.get(Uri.parse(uri));
var responseText = response.body;
var bootstrapResponsePayload = BootstrapResponsePayload.fromJson(jsonDecode(responseText)["payload"]);
var brokerUriAndPortArray = bootstrapResponsePayload.config.broker.replaceFirst("mqtt://", "").split(":");
_brokerUri = brokerUriAndPortArray[0];
_brokerPort = int.parse(brokerUriAndPortArray[1]);
_fromServerTopic = bootstrapResponsePayload.config.topics.fromServer;
_toServerTopic = bootstrapResponsePayload.config.topics.toServer;
_connectToBroker();
} catch (ex) {
_startReconnectTimer();
}
}
}
+5
View File
@@ -0,0 +1,5 @@
import 'package:flutter/cupertino.dart';
abstract class PageBase extends StatelessWidget {
const PageBase({super.key});
}
+178
View File
@@ -0,0 +1,178 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart';
import '../Tools/colored_safe_area.dart';
class Util {
static Future<bool> preferencesContainsKey(String key) async {
var prefs = await SharedPreferences.getInstance();
return prefs.containsKey(key);
}
static void preferencesSaveString(String key, String value) async {
var prefs = await SharedPreferences.getInstance();
await prefs.setString(key, value);
}
static Future<String?> preferencesGetString(
String key, String? defaultValue) async {
if (await preferencesContainsKey(key)) {
var prefs = await SharedPreferences.getInstance();
return prefs.getString(key);
}
return defaultValue;
}
static void preferencesSaveInt(String key, int value) async {
var prefs = await SharedPreferences.getInstance();
await prefs.setInt(key, value);
}
static Future<int?> preferencesGetInt(String key, int? defaultValue) async {
if (await preferencesContainsKey(key)) {
var prefs = await SharedPreferences.getInstance();
return prefs.getInt(key);
}
return defaultValue;
}
static void preferencesSaveBool(String key, bool value) async {
var prefs = await SharedPreferences.getInstance();
await prefs.setBool(key, value);
}
static Future<bool> preferencesGetBool(String key, bool defaultValue) async {
if (await preferencesContainsKey(key)) {
var prefs = await SharedPreferences.getInstance();
return prefs.getBool(key) as bool;
}
return defaultValue;
}
static Future<String> getAppUuid() async {
var currentUuid = await preferencesGetString('uuid', null);
if (currentUuid == null) {
currentUuid ??= const Uuid().v4();
preferencesSaveString("uuid", currentUuid);
}
return currentUuid;
}
static logInfo(String message) {
if (kDebugMode) {
print('Message: $message');
}
}
static logException(String message) {
if (kDebugMode) {
print('Exception: $message');
}
}
static int fastHash(String string) {
var hash = 0xcbf29ce484222325;
var i = 0;
while (i < string.length) {
final codeUnit = string.codeUnitAt(i++);
hash ^= codeUnit >> 8;
hash *= 0x100000001b3;
hash ^= codeUnit & 0xFF;
hash *= 0x100000001b3;
}
return hash;
}
static Widget getWaitWidget(context) {
return ColoredSafeArea(
key: const Key('value'),
child: Container(
width: 10,
height: 10,
color: Colors.white,
),
);
}
static Future<Widget> fetchFutureIcon(icon) {
return Future.delayed(const Duration(seconds: 0), () async {
return icon;
});
}
}
Widget getDefaultButton(String text, Function() onPressed, {Image? image}) {
return SizedBox(
height: 60,
child: Stack(
children: [
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
height: 60,
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
side: const BorderSide(color: Colors.grey),
),
),
backgroundColor: MaterialStateProperty.all<Color>(const Color.fromARGB(255, 220, 220, 220)),
foregroundColor: MaterialStateProperty.all<Color>(Colors.black),
),
onPressed: () {
onPressed();
},
child: Text(text)
),
),
),
),
],
),
Positioned(
left: 20,
top: 15,
child: Center(
child: image
)
)
],
),
);
}
String mapTourMode(String mode)
{
var text = "";
switch (mode)
{
case "pu":
text += "/ Abholung";
break;
case "del":
text += "/ Auslieferung";
break;
case "pudel":
text += "/ Abholung/Auslieferung";
break;
}
return text;
}