import 'package:flutter/material.dart'; import 'package:isar/isar.dart'; import 'package:stadtbote/content_views/accepted_jobs_page.dart'; import 'package:stadtbote/content_views/approach_area_page.dart'; import 'package:stadtbote/content_views/assigned_jobs_page.dart'; import 'package:stadtbote/content_views/finished_jobs_page.dart'; import 'package:stadtbote/content_views/messages_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.dart'; import 'package:stadtbote/model/message.dart'; import 'package:stadtbote/model/session_status.dart'; import 'package:stadtbote/model/location_status.dart'; import 'package:stadtbote/popups/infos_popup.dart'; import 'package:stadtbote/protocoll_messages/logout_message.dart'; import 'package:stadtbote/tools/message_service.dart'; import 'package:stadtbote/tools/messages/publish_payload_message.dart'; import 'package:stadtbote/tools/messages/connect_client_message.dart'; import 'package:stadtbote/tools/messages/disconnect_client_message.dart'; import 'package:stadtbote/tools/messages/job_deleted_message.dart'; import 'package:stadtbote/tools/messages/job_received_message.dart'; import 'package:stadtbote/tools/messages/message_message.dart'; import 'package:stadtbote/tools/messages/session_info_update.dart'; import 'package:badges/badges.dart' as badges; import 'package:stadtbote/tools/messages/status_info_update.dart'; import 'package:stadtbote/tools/messages/refresh_badges_message.dart'; import '../main.dart'; import '../tools/constants.dart'; import '../tools/util.dart'; class MainPage extends ContentViewWidget { final ValueNotifier _zipValueNotifier = ValueNotifier("-----"); final ValueNotifier sidValueNotifier = ValueNotifier("-----"); MainPage({super.key}); @override State createState() => _MainPageState(); @override Future getHeaderInfo(BuildContext context) async { return HeaderInfo( titleWidget: Container( height: 100, padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 0), child: Column(children: [ ValueListenableBuilder( valueListenable: _zipValueNotifier, builder: (context, value, child) { return Text( value, style: const TextStyle( color: Colors.white, fontSize: 25.0, ), ); }, ), const SizedBox(height: 5), ValueListenableBuilder( valueListenable: sidValueNotifier, builder: (context, value, child) { return Text( value, style: const TextStyle( color: Colors.white, fontSize: 25.0, ), ); }, ), ]), ), rightButtonEnabled: true, rightButtonVisible: true, rightButtonImage: Util.fetchFutureIcon(const Icon(Icons.info_outline, size: 20.0, color: Colors.white)), rightButtonOnPressed: () async { showInfosPopup(context, await MyApp.isarInstance.sessionStatus.where().findFirst()); }); } } class _MainPageState extends State { final ValueNotifier _assignedJobsValueNotifier = ValueNotifier(0); final ValueNotifier _acceptedJobsValueNotifier = ValueNotifier(0); final ValueNotifier _messagesValueNotifier = ValueNotifier(0); late bool _loggedOut = false; @override void initState() { super.initState(); _updateHeader(); _refreshBadges(); _initMessages(); } @override void dispose() { super.dispose(); _exitMessages(); } @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: [ Visibility( visible: !_loggedOut, child: ValueListenableBuilder( valueListenable: _assignedJobsValueNotifier, builder: (context, value, child) { return badges.Badge( showBadge: value > 0, position: badges.BadgePosition.topEnd(top: -12, end: -5), badgeContent: Text( value.toString(), style: const TextStyle( color: Colors.white, fontSize: 13.0, ), ), badgeStyle: badges.BadgeStyle( badgeColor: Colors.red, padding: const EdgeInsets.all(10), borderRadius: BorderRadius.circular(4), borderSide: const BorderSide(color: Colors.white, width: 0), elevation: 0, ), child: getDefaultButton( 'Zugewiesene Aufträge', image: Image.asset('assets/zugewiesene_auftraege.png', width: 30, height: 30), () => { MessageService().publish(Constants.messageTopicPushContentView, arguments: const AssignedJobsPage()) }), ); }, ), ), SizedBox(height: _loggedOut == true ? 0 : 20), Visibility( visible: !_loggedOut, child: ValueListenableBuilder( valueListenable: _acceptedJobsValueNotifier, builder: (context, value, child) { return badges.Badge( showBadge: value > 0, position: badges.BadgePosition.topEnd(top: -12, end: -5), badgeContent: Text( value.toString(), style: const TextStyle( color: Colors.white, fontSize: 13.0, ), ), badgeStyle: badges.BadgeStyle( badgeColor: Colors.red, padding: const EdgeInsets.all(10), borderRadius: BorderRadius.circular(4), borderSide: const BorderSide(color: Colors.white, width: 0), elevation: 0, ), child: getDefaultButton( 'Angenommene Aufträge', image: Image.asset('assets/angenommene_auftraege.png', width: 30, height: 30), () => { MessageService() .publish(Constants.messageTopicPushContentView, arguments: const AcceptedJobsPage()) })); }, ), ), SizedBox(height: _loggedOut == true ? 0 : 20), Visibility( visible: !_loggedOut, child: getDefaultButton( 'Erledigte Aufträge', image: Image.asset('assets/erledigte_auftraege.png', width: 30, height: 30), () => {MessageService().publish(Constants.messageTopicPushContentView, arguments: const FinishedJobsPage())}), ), SizedBox(height: _loggedOut == true ? 0 : 20), Visibility( visible: !_loggedOut, child: ValueListenableBuilder( valueListenable: _messagesValueNotifier, builder: (context, value, child) { return badges.Badge( showBadge: value > 0, position: badges.BadgePosition.topEnd(top: -12, end: -5), badgeContent: Text( value.toString(), style: const TextStyle( color: Colors.white, fontSize: 13.0, ), ), badgeStyle: badges.BadgeStyle( badgeColor: Colors.red, padding: const EdgeInsets.all(10), borderRadius: BorderRadius.circular(4), borderSide: const BorderSide(color: Colors.white, width: 0), elevation: 0, ), child: getDefaultButton( 'Nachrichten', image: Image.asset('assets/nachrichten.png', width: 30, height: 30), () => {MessageService().publish(Constants.messageTopicPushContentView, arguments: const MessagesPage())})); }, ), ), SizedBox(height: _loggedOut == true ? 0 : 20), Visibility( visible: !_loggedOut, child: getDefaultButton( 'Anfahrtsbereich', image: Image.asset('assets/anfahrtsbereich.png', width: 30, height: 30), () => {MessageService().publish(Constants.messageTopicPushContentView, arguments: const ApproachAreaPage())}), ), SizedBox(height: _loggedOut == true ? 0 : 20), getDefaultButton( _loggedOut ? 'Anmelden' : 'Abmelden', image: Image.asset(_loggedOut ? 'assets/anmelden.png' : 'assets/abmelden.png', width: 30, height: 30), () async { _logout(context); }), 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, ), ], ), ), ], ); } _initMessages() { MessageService().subscribe(Constants.messageTopicSessionStatusInfoUpdate, this, (sessionStatusInfoUpdateMessage) { widget.sidValueNotifier.value = sessionStatusInfoUpdateMessage.status.sid; }); MessageService().subscribe(Constants.messageTopicLocationStatusUpdated, this, (statusInfoUpdateMessage) { _updateHeader(); }); MessageService().subscribe(Constants.messageTopicJobReceived, this, (JobReceivedMessage jobReceivedMessage) { _jobReceived(jobReceivedMessage.job); }); MessageService().subscribe(Constants.messageTopicMessageReceived, this, (MessageReceivedMessage mesage) { _refreshBadges(); }); MessageService().subscribe(Constants.messageTopicJobDeleted, this, (JobDeletedMessage job) { _refreshBadges(); }); MessageService().subscribe(Constants.messageTopicUpdateBadges, this, (RefreshBadgesMessage message) { _refreshBadges(); }); } void _exitMessages() { MessageService().unsubscribe(Constants.messageTopicSessionStatusInfoUpdate, this); MessageService().unsubscribe(Constants.messageTopicJobReceived, this); } void _refreshBadges() async { _assignedJobsValueNotifier.value = await MyApp.isarInstance.jobs.filter().stateEqualTo(0).count(); _acceptedJobsValueNotifier.value = await MyApp.isarInstance.jobs.filter().stateEqualTo(1).count(); _messagesValueNotifier.value = await MyApp.isarInstance.messages.filter().readEqualTo(false).count(); } void _jobReceived(Job job) { _refreshBadges(); } void _updateHeader() async { var status = await MyApp.isarInstance.locationStatus.where().findFirst(); var sessionStatus = await MyApp.isarInstance.sessionStatus.where().findFirst(); if (status != null) { widget._zipValueNotifier.value = '${status.zip} (${status.zipReal})'; } else if (sessionStatus != null) { widget._zipValueNotifier.value = sessionStatus.locZip; } else { widget._zipValueNotifier.value = "---"; } } _logout(context) { if (!_loggedOut) { showLogoutAlertDialog(context); } else { MessageService().publish(Constants.messageTopicConnectClient, arguments: ConnectClientMessage()); _loggedOut = false; setState(() {}); } } showLogoutAlertDialog(BuildContext context) { Widget yesButton = TextButton( child: const Text("Ja"), onPressed: () { Navigator.of(context).pop(); _sendLogoutMessage(); Future.delayed(const Duration(seconds: 1), () async { MessageService().publish(Constants.messageTopicDisconnectClient, arguments: DisconnectClientMessage()); }); _loggedOut = true; setState(() {}); }, ); Widget noButton = TextButton( child: const Text("Nein"), onPressed: () { Navigator.of(context).pop(); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: const Text("Warnung"), content: const Text("Wollen Sie sich wirklich abmelden?"), actions: [ yesButton, noButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } _sendLogoutMessage() { var position = MyApp.currentPosition; var logoutMessage = LogoutMessage(); if (position != null) { logoutMessage.pos = LogoutMessagePosition(); logoutMessage.pos!.time = position.timestamp.toIso8601String(); logoutMessage.pos!.lat = position.latitude; logoutMessage.pos!.long = position.longitude; logoutMessage.pos!.acc = position.accuracy.toInt(); } MessageService().publish(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "logout", message: logoutMessage.toJson())); } }