import 'package:bus_infotainment/backend/live_information.dart'; import 'package:bus_infotainment/pages/components/ibus_display.dart'; import 'package:bus_infotainment/remaster/dashboard.dart'; import 'package:bus_infotainment/tfl_datasets.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_scroll_shadow/flutter_scroll_shadow.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; class ArcDashboard extends StatefulWidget { @override State createState() => _ArcDashboardState(); } class _ArcDashboardState extends State { _closeDialogueChecker closeDialogWidget = _closeDialogueChecker(); @override Widget build(BuildContext context) { // Force landscape mode Future.delayed(Duration(seconds: 1), () { SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft, ]); }); return Scaffold( body: Container( child: Row( children: [ const SizedBox( width: 10, ), Container( padding: const EdgeInsets.symmetric( vertical: 10, ), child: IntrinsicWidth( child: Column( children: [ if (LiveInformation().roomDocumentID != null) Tooltip( child: ShadButton( icon: const Icon(Icons.network_check), width: double.infinity, onPressed: () { showShadSheet( context: context, builder: (context) { return ShadSheet( padding: const EdgeInsets.all(10), content: Column( children: [ Text("Room ID: ${LiveInformation().roomDocumentID}"), ], ), ); } ); }, ), message: "Room information", ), SizedBox( height: 220, child: RotatedBox( quarterTurns: 3, child: Column( children: [ ShadButton( text: const Text("Manual Announcements"), width: double.infinity, borderRadius: const BorderRadius.all(Radius.circular(10)), onPressed: () { List announcements = []; for (var announcement in LiveInformation().announcementModule.manualAnnouncements) { announcements.add( ShadButton( text: SizedBox( width: 200-42, child: Text(announcement.shortName), ), onPressed: () { if (closeDialogWidget.closeDialog) { Navigator.pop(context); } LiveInformation().announcementModule.queueAnnouncementByInfoIndex( infoIndex: LiveInformation().announcementModule.manualAnnouncements.indexOf(announcement), ); }, ) ); } print(announcements.length); showShadSheet( context: context, side: ShadSheetSide.left, builder: (context) { return ShadSheet( padding: const EdgeInsets.all(0), content: Container( height: MediaQuery.of(context).size.height, child: Row( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 5, ), Container( padding: const EdgeInsets.symmetric( vertical: 10, ), alignment: Alignment.bottomCenter, height: double.infinity, width: 35, child: RotatedBox( quarterTurns: 3, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Text( "Manual Ann'", style: ShadTheme.of(context).textTheme.h3 ), SizedBox( width: 16, ), Container( width: 1, height: 200, color: Colors.grey, ), ], ), closeDialogWidget ], ), ), ), Container( // width: 220, height: MediaQuery.of(context).size.height, child: Scrollbar( thumbVisibility: true, child: SingleChildScrollView( reverse: true, child: Container( margin: const EdgeInsets.fromLTRB( 0, 10, 10, 10 ), child: Column( children: announcements.reversed.toList(), ), ), ), ), ), ], ), ), ); } ); }, ), ShadButton( text: const Text("Bus Stop Announcements"), width: double.infinity, borderRadius: const BorderRadius.all(Radius.circular(10)), onPressed: () { showShadSheet( context: context, side: ShadSheetSide.left, builder: (context) { List announcements = []; LiveInformation info = LiveInformation(); for (var busStop in info.getRouteVariant()!.busStops) { if (info.trackerModule.nearestStop == busStop) { announcements.add( ShadButton( text: SizedBox( width: 200-42, child: Text( "-> ${busStop.formattedStopName}", overflow: TextOverflow.ellipsis, ), ), backgroundColor: Colors.amber, onPressed: () { if (closeDialogWidget.closeDialog) { Navigator.pop(context); } LiveInformation().announcementModule.queueAnnounceByAudioName( displayText: busStop.formattedStopName, audioNames: [busStop.getAudioFileName()], ); }, ) ); } else { announcements.add( ShadButton( text: SizedBox( width: 200-42, child: Text( busStop.formattedStopName, overflow: TextOverflow.ellipsis, ), ), onPressed: () { if (closeDialogWidget.closeDialog) { Navigator.pop(context); } LiveInformation().announcementModule.queueAnnounceByAudioName( displayText: busStop.formattedStopName, audioNames: [busStop.getAudioFileName()], ); }, ) ); } } ScrollController controller = ScrollController(); // Scroll to the current bus stop WidgetsBinding.instance!.addPostFrameCallback((_) { double offset = (info.getRouteVariant()!.busStops.indexOf(info.trackerModule.nearestStop!) * 50); // Offset the offset so that its in the middle of the screen offset -= (MediaQuery.of(context).size.height / 2) - 25; // controller.jumpTo(offset); }); return ShadSheet( padding: const EdgeInsets.all(0), content: Container( height: MediaQuery.of(context).size.height, child: Row( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 5, ), Container( padding: const EdgeInsets.symmetric( vertical: 10, ), alignment: Alignment.bottomCenter, height: double.infinity, width: 35, child: RotatedBox( quarterTurns: 3, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Text( "Bus Stops", style: ShadTheme.of(context).textTheme.h3 ), SizedBox( width: 16, ), Container( width: 1, height: 200, color: Colors.grey, ), ], ), closeDialogWidget ], ), ), ), Container( // width: 220, height: MediaQuery.of(context).size.height, child: Scrollbar( thumbVisibility: true, controller: controller, child: SingleChildScrollView( reverse: true, controller: controller, child: Container( margin: const EdgeInsets.fromLTRB( 0, 10, 10, 10 ), child: Column( children: announcements.reversed.toList(), ), ), ), ), ), ], ), ), ); } ); }, ), ], ) ) ), const ShadButton( icon: Icon(Icons.stop), width: double.infinity, ), ShadButton( // text: const Text("Announce Destination"), icon: const Icon(Icons.location_on), width: double.infinity, borderRadius: const BorderRadius.all(Radius.circular(10)), onPressed: () { LiveInformation info = LiveInformation(); BusRouteVariant? routeVariant = info.getRouteVariant(); if (routeVariant != null) { info.announcementModule.queueAnnouncementByRouteVariant( routeVariant: routeVariant, sendToServer: false ); } }, ) ], ), ), ), Expanded( child: Container( decoration: const BoxDecoration( color: Colors.black, borderRadius: BorderRadius.all(Radius.circular(10)), ), margin: const EdgeInsets.all(10), padding: const EdgeInsets.all(10), width: double.infinity, height: double.infinity, child: Stack( children: [ Container( alignment: Alignment.center, child: ibus_display( hasBorder: false, ), ), Container( alignment: Alignment.bottomRight, child: ShadButton.ghost( icon: const Icon(Icons.fullscreen), padding: const EdgeInsets.all(8), onPressed: () { Navigator.pushNamed(context, '/display'); }, ), ), Container( alignment: Alignment.bottomLeft, child: ShadButton.ghost( icon: const Icon(Icons.arrow_back), padding: const EdgeInsets.all(8), onPressed: () { Navigator.pop(context); }, ), ) ], ), ), ) ], ), ), ); } } class _closeDialogueChecker extends StatefulWidget { bool closeDialog = false; @override State<_closeDialogueChecker> createState() => _closeDialogueCheckerState(); } class _closeDialogueCheckerState extends State<_closeDialogueChecker> { @override Widget build(BuildContext context) { // TODO: implement build return ShadSwitch( value: widget.closeDialog, enabled: true, label: const Text("Close Dialog?"), onChanged: (value) { widget.closeDialog = value; setState(() { }); }, ); } }