diff --git a/lib/content_views/assigned_jobs_page.dart b/lib/content_views/assigned_jobs_page.dart index 39708df..85cb40c 100644 --- a/lib/content_views/assigned_jobs_page.dart +++ b/lib/content_views/assigned_jobs_page.dart @@ -3,6 +3,7 @@ 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:intl/intl.dart'; +import 'package:stadtbote/popups/accept_job_popup.dart'; import '../main.dart'; import '../model/job.dart'; @@ -128,5 +129,6 @@ class _AssignedJobsPageState extends State { } void _clicked(Job job) { + showAcceptJobPopup(context, job); } } diff --git a/lib/content_views/main_page.dart b/lib/content_views/main_page.dart index 4dd4331..27494f8 100644 --- a/lib/content_views/main_page.dart +++ b/lib/content_views/main_page.dart @@ -10,6 +10,7 @@ import 'package:stadtbote/content_views/utils/content_view_widget.dart'; import 'package:stadtbote/content_views/utils/header_info.dart'; import 'package:stadtbote/model/job.dart'; import 'package:stadtbote/model/status.dart'; +import 'package:stadtbote/popups/accept_job_popup.dart'; import 'package:stadtbote/popups/infos_popup.dart'; import 'package:stadtbote/tools/messages/job_received_message.dart'; import 'package:stadtbote/tools/messages/session_info_update.dart'; @@ -107,7 +108,7 @@ class _MainPageState extends State { builder: (context, value, child) { return badges.Badge( showBadge: value > 0, - position: badges.BadgePosition.topEnd(top: 0, end: -5), + position: badges.BadgePosition.topEnd(top: -12, end: -5), badgeContent: Text( value.toString(), style: const TextStyle( @@ -129,13 +130,13 @@ class _MainPageState extends State { ); }, ), - const SizedBox(height: 10), + const SizedBox(height: 20), ValueListenableBuilder( valueListenable: _acceptedJobsValueNotifier, builder: (context, value, child) { return badges.Badge( showBadge: value > 0, - position: badges.BadgePosition.topEnd(top: 0, end: -5), + position: badges.BadgePosition.topEnd(top: -12, end: -5), badgeContent: Text( value.toString(), style: const TextStyle( @@ -157,18 +158,18 @@ class _MainPageState extends State { ); }, ), - const SizedBox(height: 10), + const SizedBox(height: 20), getDefaultButton( 'Erledigte Aufträge', image: Image.asset('assets/erledigte_auftraege.png', width: 30, height: 30), () => {BroadcastReceiver().publish(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage())}), - const SizedBox(height: 10), + const SizedBox(height: 20), ValueListenableBuilder( valueListenable: _messagesValueNotifier, builder: (context, value, child) { return badges.Badge( showBadge: value > 0, - position: badges.BadgePosition.topEnd(top: 0, end: -5), + position: badges.BadgePosition.topEnd(top: -12, end: -5), badgeContent: Text( value.toString(), style: const TextStyle( @@ -190,14 +191,14 @@ class _MainPageState extends State { ); }, ), - const SizedBox(height: 10), + const SizedBox(height: 20), getDefaultButton( 'Anfahrtsbereich', image: Image.asset('assets/anfahrtsbereich.png', width: 30, height: 30), () => { //BroadcastReceiver().publish(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage()) }), - const SizedBox(height: 10), + const SizedBox(height: 20), getDefaultButton( 'Abmelden', image: Image.asset('assets/abmelden.png', width: 30, height: 30), @@ -260,7 +261,11 @@ class _MainPageState extends State { _refreshBadges(); if (job.state == 0) { - Util.logInfo("test"); + _showAcceptanceDialog(job); } } + + void _showAcceptanceDialog(Job job) { + showAcceptJobPopup(context, job); + } } diff --git a/lib/model/message.dart b/lib/model/message.dart new file mode 100644 index 0000000..b348bd3 --- /dev/null +++ b/lib/model/message.dart @@ -0,0 +1,24 @@ +import 'package:isar/isar.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'message.g.dart'; + +@collection +@JsonSerializable() +class Message { + late Id id; + + late String time; + + late String from; + + late String subj; + + late List text; + + Message(); + + factory Message.fromJson(Map json) => _$MessageFromJson(json); + + Map toJson() => _$MessageToJson(this); +} diff --git a/lib/model/message.g.dart b/lib/model/message.g.dart new file mode 100644 index 0000000..c5b5b5a --- /dev/null +++ b/lib/model/message.g.dart @@ -0,0 +1,1043 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'message.dart'; + +// ************************************************************************** +// IsarCollectionGenerator +// ************************************************************************** + +// coverage:ignore-file +// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types + +extension GetMessageCollection on Isar { + IsarCollection get messages => this.collection(); +} + +const MessageSchema = CollectionSchema( + name: r'Message', + id: 2463283977299753079, + properties: { + r'from': PropertySchema( + id: 0, + name: r'from', + type: IsarType.string, + ), + r'subj': PropertySchema( + id: 1, + name: r'subj', + type: IsarType.string, + ), + r'text': PropertySchema( + id: 2, + name: r'text', + type: IsarType.stringList, + ), + r'time': PropertySchema( + id: 3, + name: r'time', + type: IsarType.string, + ) + }, + estimateSize: _messageEstimateSize, + serialize: _messageSerialize, + deserialize: _messageDeserialize, + deserializeProp: _messageDeserializeProp, + idName: r'id', + indexes: {}, + links: {}, + embeddedSchemas: {}, + getId: _messageGetId, + getLinks: _messageGetLinks, + attach: _messageAttach, + version: '3.1.0+1', +); + +int _messageEstimateSize( + Message object, + List offsets, + Map> allOffsets, +) { + var bytesCount = offsets.last; + bytesCount += 3 + object.from.length * 3; + bytesCount += 3 + object.subj.length * 3; + bytesCount += 3 + object.text.length * 3; + { + for (var i = 0; i < object.text.length; i++) { + final value = object.text[i]; + bytesCount += value.length * 3; + } + } + bytesCount += 3 + object.time.length * 3; + return bytesCount; +} + +void _messageSerialize( + Message object, + IsarWriter writer, + List offsets, + Map> allOffsets, +) { + writer.writeString(offsets[0], object.from); + writer.writeString(offsets[1], object.subj); + writer.writeStringList(offsets[2], object.text); + writer.writeString(offsets[3], object.time); +} + +Message _messageDeserialize( + Id id, + IsarReader reader, + List offsets, + Map> allOffsets, +) { + final object = Message(); + object.from = reader.readString(offsets[0]); + object.id = id; + object.subj = reader.readString(offsets[1]); + object.text = reader.readStringList(offsets[2]) ?? []; + object.time = reader.readString(offsets[3]); + return object; +} + +P _messageDeserializeProp

( + IsarReader reader, + int propertyId, + int offset, + Map> allOffsets, +) { + switch (propertyId) { + case 0: + return (reader.readString(offset)) as P; + case 1: + return (reader.readString(offset)) as P; + case 2: + return (reader.readStringList(offset) ?? []) as P; + case 3: + return (reader.readString(offset)) as P; + default: + throw IsarError('Unknown property with id $propertyId'); + } +} + +Id _messageGetId(Message object) { + return object.id; +} + +List> _messageGetLinks(Message object) { + return []; +} + +void _messageAttach(IsarCollection col, Id id, Message object) { + object.id = id; +} + +extension MessageQueryWhereSort on QueryBuilder { + QueryBuilder anyId() { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(const IdWhereClause.any()); + }); + } +} + +extension MessageQueryWhere on QueryBuilder { + QueryBuilder idEqualTo(Id id) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: id, + upper: id, + )); + }); + } + + QueryBuilder 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 idGreaterThan(Id id, + {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: include), + ); + }); + } + + QueryBuilder idLessThan(Id id, + {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: include), + ); + }); + } + + QueryBuilder 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 MessageQueryFilter + on QueryBuilder { + QueryBuilder fromEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'from', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder fromGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'from', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder fromLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'from', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder fromBetween( + 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'from', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder fromStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'from', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder fromEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'from', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder fromContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'from', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder fromMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'from', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder fromIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'from', + value: '', + )); + }); + } + + QueryBuilder fromIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'from', + value: '', + )); + }); + } + + QueryBuilder idEqualTo(Id value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'id', + value: value, + )); + }); + } + + QueryBuilder idGreaterThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder idLessThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder 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 subjEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'subj', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder subjGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'subj', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder subjLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'subj', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder subjBetween( + 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'subj', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder subjStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'subj', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder subjEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'subj', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder subjContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'subj', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder subjMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'subj', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder subjIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'subj', + value: '', + )); + }); + } + + QueryBuilder subjIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'subj', + value: '', + )); + }); + } + + QueryBuilder textElementEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'text', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder textElementGreaterThan( + 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 textElementLessThan( + 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 textElementBetween( + 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 textElementStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'text', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder textElementEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'text', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder textElementContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'text', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder textElementMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'text', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder textElementIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'text', + value: '', + )); + }); + } + + QueryBuilder + textElementIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'text', + value: '', + )); + }); + } + + QueryBuilder textLengthEqualTo( + int length) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'text', + length, + true, + length, + true, + ); + }); + } + + QueryBuilder textIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'text', + 0, + true, + 0, + true, + ); + }); + } + + QueryBuilder textIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'text', + 0, + false, + 999999, + true, + ); + }); + } + + QueryBuilder textLengthLessThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'text', + 0, + true, + length, + include, + ); + }); + } + + QueryBuilder textLengthGreaterThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'text', + length, + include, + 999999, + true, + ); + }); + } + + QueryBuilder textLengthBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'text', + lower, + includeLower, + upper, + includeUpper, + ); + }); + } + + QueryBuilder timeEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'time', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder timeGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'time', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder timeLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'time', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder timeBetween( + 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'time', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder timeStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'time', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder timeEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'time', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder timeContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'time', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder timeMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'time', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder timeIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'time', + value: '', + )); + }); + } + + QueryBuilder timeIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'time', + value: '', + )); + }); + } +} + +extension MessageQueryObject + on QueryBuilder {} + +extension MessageQueryLinks + on QueryBuilder {} + +extension MessageQuerySortBy on QueryBuilder { + QueryBuilder sortByFrom() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'from', Sort.asc); + }); + } + + QueryBuilder sortByFromDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'from', Sort.desc); + }); + } + + QueryBuilder sortBySubj() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'subj', Sort.asc); + }); + } + + QueryBuilder sortBySubjDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'subj', Sort.desc); + }); + } + + QueryBuilder sortByTime() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'time', Sort.asc); + }); + } + + QueryBuilder sortByTimeDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'time', Sort.desc); + }); + } +} + +extension MessageQuerySortThenBy + on QueryBuilder { + QueryBuilder thenByFrom() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'from', Sort.asc); + }); + } + + QueryBuilder thenByFromDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'from', Sort.desc); + }); + } + + QueryBuilder thenById() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.asc); + }); + } + + QueryBuilder thenByIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.desc); + }); + } + + QueryBuilder thenBySubj() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'subj', Sort.asc); + }); + } + + QueryBuilder thenBySubjDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'subj', Sort.desc); + }); + } + + QueryBuilder thenByTime() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'time', Sort.asc); + }); + } + + QueryBuilder thenByTimeDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'time', Sort.desc); + }); + } +} + +extension MessageQueryWhereDistinct + on QueryBuilder { + QueryBuilder distinctByFrom( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'from', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctBySubj( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'subj', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByText() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'text'); + }); + } + + QueryBuilder distinctByTime( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'time', caseSensitive: caseSensitive); + }); + } +} + +extension MessageQueryProperty + on QueryBuilder { + QueryBuilder idProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'id'); + }); + } + + QueryBuilder fromProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'from'); + }); + } + + QueryBuilder subjProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'subj'); + }); + } + + QueryBuilder, QQueryOperations> textProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'text'); + }); + } + + QueryBuilder timeProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'time'); + }); + } +} + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Message _$MessageFromJson(Map json) => Message() + ..id = json['id'] as int + ..time = json['time'] as String + ..from = json['from'] as String + ..subj = json['subj'] as String + ..text = (json['text'] as List).map((e) => e as String).toList(); + +Map _$MessageToJson(Message instance) => { + 'id': instance.id, + 'time': instance.time, + 'from': instance.from, + 'subj': instance.subj, + 'text': instance.text, + }; diff --git a/lib/popups/accept_job_popup.dart b/lib/popups/accept_job_popup.dart new file mode 100644 index 0000000..d794b39 --- /dev/null +++ b/lib/popups/accept_job_popup.dart @@ -0,0 +1,130 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:kumi_popup_window/kumi_popup_window.dart'; +import 'package:stadtbote/main.dart'; +import 'package:stadtbote/model/job.dart'; +import 'package:stadtbote/tools/util.dart'; + +void showAcceptJobPopup(BuildContext context, Job job) async { + 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.5, + width: MediaQuery.of(context).size.width * 0.8, + 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(12.0), + child: Column( + children: [ + Text(DateFormat('dd.MM.yyyy HH:mm').format(DateTime.parse(job.ordertime)).toString(), textAlign: TextAlign.left), + Text('Auftragsnummer: ${job.id}'), + Text(job.tours[0].comp), + Text(job.tours[0].street), + Text(job.tours[0].city), + const SizedBox(height: 20), + Container( + height: 200, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: const Color(0xfffff4e4), + border: Border.all( + color: Colors.grey, + width: 0.5, + ), + ), + child: const SingleChildScrollView( + child: Text('asd asd asd asd asd asd asd asd asd asd asd asd asd asd asd '), + ), + ), + const SizedBox(height: 20), + Row( + children: [ + Expanded( + child: getDefaultButton( + 'Ablehnen', + () => {_sendAnswer()}), + ), + const SizedBox(width: 20), + Expanded( + child: getDefaultButton( + 'Annehmen', + () => {}), + ) + ] + ) + ], + ), + ), + ) + ); + }, + ); +} + +/* +private void SendAnswer(int item) + { + JObject payloadObject; + + var location = App.CurrentLocation; + if (location != null) + payloadObject = new JObject( + new JProperty("reaction", new JObject( + new JProperty("id", _jobViewModel.IdString), + new JProperty("ver", _jobViewModel.Version), + new JProperty("item", item), + new JProperty("track", new JObject( + new JProperty("time", DateTime.Now.ToString("o")), + new JProperty("pos", new JObject( + new JProperty("lat", location.Latitude), + new JProperty("long", location.Longitude), + new JProperty("acc", location.Accuracy)))))))); + else + payloadObject = new JObject( + new JProperty("reaction", new JObject( + new JProperty("id", _jobViewModel.IdString), + new JProperty("ver", _jobViewModel.Version), + new JProperty("item", item), + new JProperty("track", new JObject( + new JProperty("time", DateTime.Now.ToString("o"))))))); + + App.Core.SendJsonMessageAsync("job", payloadObject); + } + */ + +_sendAnswer() { + +} \ No newline at end of file diff --git a/lib/tools/constants.dart b/lib/tools/constants.dart index 15bfea5..0ba1817 100644 --- a/lib/tools/constants.dart +++ b/lib/tools/constants.dart @@ -8,6 +8,7 @@ class Constants { static const String messageTopicSessionInfoUpdate = "status_info_updated"; static const String messageTopicStatusInfoUpdate = "session_info_updated"; static const String messageTopicJobReceived = "job_received"; + static const String messageTopicMessageReceived = "message_received"; static const String messageTopicPushContentView = "push_content_view"; static const String messageTopicPopContentView = "pop_content_view"; static const String messageTopicReplaceContentView = "replace_content_view"; diff --git a/lib/tools/messages/message_message.dart b/lib/tools/messages/message_message.dart new file mode 100644 index 0000000..668c6b3 --- /dev/null +++ b/lib/tools/messages/message_message.dart @@ -0,0 +1,8 @@ +import 'package:stadtbote/model/job.dart'; +import 'package:stadtbote/model/message.dart'; + +class MessageReceivedMessage { + final Message message; + + MessageReceivedMessage({required this.message}); +} \ No newline at end of file diff --git a/lib/tools/mqtt_core.dart b/lib/tools/mqtt_core.dart index 9964427..404699f 100644 --- a/lib/tools/mqtt_core.dart +++ b/lib/tools/mqtt_core.dart @@ -9,9 +9,11 @@ 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/model/message.dart'; import 'package:stadtbote/model/start_session_message.dart'; import 'package:stadtbote/tools/connection_status.dart'; import 'package:stadtbote/tools/messages/job_received_message.dart'; +import 'package:stadtbote/tools/messages/message_message.dart'; import 'package:stadtbote/tools/messages/session_info_update.dart'; import 'package:typed_data/typed_buffers.dart'; import 'package:http/http.dart' as http; @@ -131,6 +133,10 @@ class MqttCore { _jobMessageReceived(payloadData); break; + case "mssg": + _messageMessageReceived(payloadData); + break; + default: Util.logInfo('Unknown topic: $payloadEntry'); break; @@ -171,6 +177,16 @@ class MqttCore { } } + void _messageMessageReceived(Map payloadData) async { + var newMessage = Message.fromJson(payloadData); + + await MyApp.isarInstance.writeTxn(() async { + await MyApp.isarInstance.messages.put(newMessage); + }); + + BroadcastReceiver().publish(Constants.messageTopicJobReceived, arguments: MessageReceivedMessage(message: newMessage)); + } + void _startReconnectTimer() { Util.logInfo("_startReconnectTimer called"); diff --git a/lib/tools/util.dart b/lib/tools/util.dart index 8718b8d..9efe947 100644 --- a/lib/tools/util.dart +++ b/lib/tools/util.dart @@ -177,15 +177,16 @@ class Util { } Widget getDefaultButton(String text, Function() onPressed, {Image? image, double? buttonHeight}) { - return SizedBox( + /*return SizedBox( height: buttonHeight ?? 60, child: Stack( + fit: StackFit.expand, children: [ Row( children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), + Padding( + padding: const EdgeInsets.all(0), + child: Expanded( child: SizedBox( height: 60, child: ElevatedButton( @@ -211,6 +212,38 @@ Widget getDefaultButton(String text, Function() onPressed, {Image? image, double Positioned(left: 20, top: 15, child: Center(child: image)) ], ), + );*/ + return SizedBox( + height: buttonHeight ?? 50, + child: MaterialButton( + color: const Color.fromARGB(255, 220, 220, 220), + disabledColor: Colors.indigo[400], + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + onPressed: onPressed, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Visibility( + visible: image != null, + child: CircleAvatar( + backgroundColor: Colors.transparent, + child: image, + ), + ), + Expanded( + child: Text( + text, + style: const TextStyle(color: Colors.black, fontSize: 18.0), + textAlign: TextAlign.center, + ), + ), + ], + ), + ), ); }