import 'package:dart_mq/dart_mq.dart'; import 'package:flutter/material.dart'; import 'package:isar/isar.dart'; import 'package:stadtbote/content_views/utils/content_view_widget.dart'; import 'package:stadtbote/main.dart'; import 'package:stadtbote/messages/pop_content_view_message.dart'; import 'package:stadtbote/model/rank.dart'; import 'package:stadtbote/network_messages/zip_message.dart'; import 'package:stadtbote/popups/tasks_popups/zip_popup.dart'; import 'package:stadtbote/tools/constants.dart'; import 'package:stadtbote/tools/messages/publish_payload_message.dart'; import 'package:badges/badges.dart' as badges; import '../tools/util.dart'; class ApproachAreaPage extends ContentViewWidget { const ApproachAreaPage({super.key}); @override State createState() => _ApproachAreaPageState(); @override Future getHeaderWidget(BuildContext context) async { await Future.delayed(const Duration(microseconds: 0)); return _HeaderWidget(); } } class _ApproachAreaPageState extends State with ProducerMixin, ConsumerMixin { late Ranking? _ranking; late bool _initCompleted = false; @override void initState() { super.initState(); Future.delayed(const Duration(seconds: 0), () async { _ranking = await MyApp.isarInstance.rankings.where().findFirst(); _initCompleted = true; setState(() {}); }); _initMessages(); } @override Widget build(BuildContext context) { if (!_initCompleted) { return Util.getWaitWidget(context); } _fillColumns(); return Padding( padding: const EdgeInsets.all(8.0), child: InteractiveViewer( alignment: Alignment.topCenter, child: SingleChildScrollView( scrollDirection: Axis.vertical, child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: _fillColumns()), ), ), ), ); } List _fillColumns() { List columns = []; if (_ranking != null) { for (int i = 0; i < _ranking!.ranks.length; i++) { var rank = _ranking!.ranks[i]; var rankArea = rank.area ?? ""; List entries = []; entries.add( GestureDetector( onTap: () => { if (i == 0) { showZipPopup(context, 'ACHTUNG: Wenn Sie Ihre PLZ ändern, verlieren Sie Ihr Ranking!\n', 'Freimelden', (zip) => {_sendZip(rank, zip)}), } }, child: Container( padding: const EdgeInsets.all(4), margin: const EdgeInsets.all(2), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: i == 0 ? Constants.colorPrimary : Colors.white, border: Border.all( color: Colors.grey, width: 0.5, ), ), width: 85, height: 60, child: Column(children: [ Text( rank.zip, style: TextStyle(fontSize: 20, color: (i == 0 ? Colors.white : Colors.black)), ), Text( rankArea, style: TextStyle(fontSize: 13, color: (i == 0 ? Colors.white : Colors.black)), ) ] ) ), ), ); for (int j = 0; j < rank.vehicles.length; j++) { var vehicle = rank.vehicles[j]; var imageFilename = vehicle.self == true ? "assets/mein_${mapVehicleTypeToImageName(vehicle.type)}" : "assets/${mapVehicleTypeToImageName(vehicle.type)}"; entries.add( badges.Badge( showBadge: vehicle.cnt != null && vehicle.cnt! > 0, position: badges.BadgePosition.topEnd(top: -12, end: 0), badgeContent: Text( vehicle.cnt.toString(), style: const TextStyle( color: Colors.white, fontSize: 12, ), ), badgeStyle: badges.BadgeStyle( badgeColor: Colors.red, padding: const EdgeInsets.all(8), borderRadius: BorderRadius.circular(4), borderSide: const BorderSide(color: Colors.white, width: 0), elevation: 0, ), child: Container( padding: const EdgeInsets.all(4), margin: const EdgeInsets.all(2), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.white, border: Border.all( color: Colors.grey, width: 0.5, ), ), width: 80, height: 60, child: Column( children: [ Image.asset(imageFilename, width: 30, height: 30), const SizedBox(width: 10), Text( mapVehicleTypeToText(vehicle.type) ), ], ), )), ); } columns.add(Align( alignment: Alignment.topLeft, child: Row( mainAxisAlignment: MainAxisAlignment.start, children: entries, ), )); } } return columns; } _sendZip(Rank rank, String zip) async { var position = MyApp.currentPosition; var setPosMessage = ZipSetPos(); setPosMessage.zip = zip; if (position != null) { setPosMessage.track = ZipTrack(); setPosMessage.track!.time = DateTime.now().toIso8601String(); setPosMessage.track!.pos = ZipTrackPos(); setPosMessage.track!.pos!.lat = position.latitude; setPosMessage.track!.pos!.long = position.longitude; setPosMessage.track!.pos!.acc = position.accuracy.toInt(); } // TODO MESSAGING sendMessage( routingKey: Constants.messageTopicPublishPayload, payload: PublishPayloadMessage(topic: "set_zip", message: setPosMessage.toJson(), acknowledgeRequired: false), ); //await MessageService().publish(Constants.messageTopicPublishPayload, arguments: PublishPayloadMessage(topic: "set_zip", message: setPosMessage.toJson(), qos: MqttQos.exactlyOnce)); } _initMessages() { subscribe( queueId: Constants.messageTopicRankingUpdated, callback: (message) async { _ranking = await MyApp.isarInstance.rankings.where().findFirst(); setState(() {}); }, ); /*MessageService().subscribe(Constants.messageTopicRankingUpdated, this, (rankingUpdateMessage) async { _ranking = await MyApp.isarInstance.rankings.where().findFirst(); setState(() {}); });*/ } } class _HeaderWidget extends StatefulWidget { @override State<_HeaderWidget> createState() => _HeaderWidgetState(); } class _HeaderWidgetState extends State<_HeaderWidget> with ProducerMixin { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { var cellWidth = (MediaQuery.of(context).size.width - 60 - 60 - 25) / 2; return Padding( padding: const EdgeInsets.all(8), child: Stack( alignment: Alignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Visibility( visible: true, child: Container( width: 60, height: 60, decoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.white, ), child: FittedBox( child: GestureDetector( onTap: () async { // TODO MESSAGING sendMessage( routingKey: Constants.messageTopicPopContentView, payload: PopContentViewMessage(count: 1), ); //await MessageService().publish(Constants.messageTopicPopContentView, arguments: PopContentViewMessage(count: 1)); }, child: const CircleAvatar( radius: 10, backgroundColor: Constants.colorPrimary, child: Padding(padding: EdgeInsets.all(1.0), child: Icon(Icons.arrow_back, size: 20.0, color: Colors.white)), ), ), ), ), ), Visibility( visible: false, child: Container( width: 60, height: 60, decoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.red, ), child: FittedBox( child: GestureDetector( onTap: () async { // TODO MESSAGING sendMessage( routingKey: Constants.messageTopicPopContentView, payload: PopContentViewMessage(count: 1), ); //await MessageService().publish(Constants.messageTopicPopContentView, arguments: PopContentViewMessage(count: 1)); }, child: const CircleAvatar( backgroundColor: Constants.colorPrimary, radius: 10, child: Padding(padding: EdgeInsets.all(1.0), child: Icon(Icons.info_outline, size: 20.0, color: Colors.white))), ), ), ), ), ], ), SizedBox( height: 100, width: cellWidth * 2, child: const Center( child: Text( textAlign: TextAlign.center, "Anfahrtsbereich", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white), ), ), ), ], ), ); } }