From 66a19dd19e7e2a507412ccc45e3f9e161fa28c2b Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Fri, 9 Feb 2024 05:13:01 -0500 Subject: [PATCH] Autonomy fixes and cleanups (#131) --- lib/models.dart | 2 +- lib/pages.dart | 2 +- lib/src/models/data/home.dart | 2 +- lib/src/models/data/sockets.dart | 8 +- lib/src/models/data/views.dart | 10 -- .../view/builders/autonomy_command.dart | 6 +- lib/src/models/view/logs.dart | 15 ++- .../models/view/{autonomy.dart => map.dart} | 9 +- lib/src/pages/home.dart | 4 +- lib/src/pages/logs.dart | 100 ++++++++--------- lib/src/pages/{autonomy.dart => map.dart} | 4 +- lib/src/services/socket.dart | 10 +- lib/src/widgets/navigation/footer.dart | 24 +++-- pubspec.lock | 102 +++++++++--------- pubspec.yaml | 4 +- 15 files changed, 151 insertions(+), 151 deletions(-) rename lib/src/models/view/{autonomy.dart => map.dart} (95%) rename lib/src/pages/{autonomy.dart => map.dart} (98%) diff --git a/lib/models.dart b/lib/models.dart index 36760b1d1..8a7ae5780 100644 --- a/lib/models.dart +++ b/lib/models.dart @@ -39,7 +39,7 @@ export "src/models/rover/metrics.dart"; export "src/models/rover/rover.dart"; // View models -export "src/models/view/autonomy.dart"; +export "src/models/view/map.dart"; export "src/models/view/logs.dart"; export "src/models/view/mars.dart"; export "src/models/view/science.dart"; diff --git a/lib/pages.dart b/lib/pages.dart index 5dc1f05f4..05e3790e3 100644 --- a/lib/pages.dart +++ b/lib/pages.dart @@ -6,7 +6,7 @@ /// This library may depend on the data, services, models, and widgets libraries. library pages; -export "src/pages/autonomy.dart"; +export "src/pages/map.dart"; export "src/pages/home.dart"; export "src/pages/science.dart"; export "src/pages/logs.dart"; diff --git a/lib/src/models/data/home.dart b/lib/src/models/data/home.dart index 925d6c153..616edb3bd 100644 --- a/lib/src/models/data/home.dart +++ b/lib/src/models/data/home.dart @@ -32,7 +32,7 @@ class HomeModel extends Model { /// Sets a new message that will disappear in 3 seconds. void setMessage({required Severity severity, required String text, bool permanent = false}) { - if (_hasError) return; // Don't replace error messages + if (_hasError && severity != Severity.critical) return; // Don't replace critical messages _messageTimer?.cancel(); // the new message might be cleared if the old one were about to message = TaskbarMessage(severity: severity, text: text); notifyListeners(); diff --git a/lib/src/models/data/sockets.dart b/lib/src/models/data/sockets.dart index afa0e432d..f100594d1 100644 --- a/lib/src/models/data/sockets.dart +++ b/lib/src/models/data/sockets.dart @@ -92,7 +92,6 @@ class Sockets extends Model { data.destination = settings.subsystemsSocket.copyWith(address: addressOverride); video.destination = settings.videoSocket.copyWith(address: addressOverride); autonomy.destination = settings.autonomySocket.copyWith(address: addressOverride); - await reset(); } /// Resets all the sockets. @@ -101,12 +100,11 @@ class Sockets extends Model { /// Resetting the sockets will bypass these errors. Future reset() async { for (final socket in sockets) { - // Sockets lose their destination when disposed, so we save it and restore it. - final destination = socket.destination; await socket.dispose(); - socket.destination = destination; await socket.init(); } + // Sockets lose their destination when disposed, so we restore it. + await updateSockets(); } /// Change which rover is being used. @@ -114,7 +112,7 @@ class Sockets extends Model { if (value == null) return; rover = value; models.home.setMessage(severity: Severity.info, text: "Using: ${rover.name}"); - await updateSockets(); + await reset(); notifyListeners(); } } diff --git a/lib/src/models/data/views.dart b/lib/src/models/data/views.dart index 0d6ebdda7..f2cf8e9ed 100644 --- a/lib/src/models/data/views.dart +++ b/lib/src/models/data/views.dart @@ -83,12 +83,8 @@ class DashboardView { static final List uiViews = [ DashboardView(name: Routes.science, builder: (context) => SciencePage()), DashboardView(name: Routes.autonomy, builder: (context) => MapPage()), - logView, ]; - /// The [LogsPage] view. - static final logView = DashboardView(name: Routes.logs, builder: (context) => LogsPage()); - /// A blank view. static final blank = DashboardView( name: Routes.blank, @@ -142,10 +138,4 @@ class ViewsModel extends Model { } notifyListeners(); } - - /// Opens the log page in a full-screen view. - void openLogs() { - views = [DashboardView.logView]; - notifyListeners(); - } } diff --git a/lib/src/models/view/builders/autonomy_command.dart b/lib/src/models/view/builders/autonomy_command.dart index 0b690f863..ff179502b 100644 --- a/lib/src/models/view/builders/autonomy_command.dart +++ b/lib/src/models/view/builders/autonomy_command.dart @@ -56,7 +56,7 @@ class AutonomyCommandBuilder extends ValueBuilder { if (_handshake != null) { models.home.setMessage(severity: Severity.info, text: "Command received"); } else { - models.home.setMessage(severity: Severity.error, text: "The rover did not receive that command"); + models.home.setMessage(severity: Severity.error, text: "Command not received"); } isLoading = false; notifyListeners(); @@ -72,12 +72,12 @@ class AutonomyCommandBuilder extends ValueBuilder { models.sockets.autonomy.sendMessage(message); models.sockets.autonomy.sendMessage(message); models.sockets.autonomy.sendMessage(message); - models.home.setMessage(severity: Severity.info, text: "Aborting autonomy..."); + models.home.setMessage(severity: Severity.info, text: "Aborting..."); await Future.delayed(const Duration(seconds: 1)); if (_handshake != null) { models.home.setMessage(severity: Severity.info, text: "Command received"); } else { - models.home.setMessage(severity: Severity.critical, text: "The rover did not receive that command"); + models.home.setMessage(severity: Severity.critical, text: "Command not received"); } isLoading = false; notifyListeners(); diff --git a/lib/src/models/view/logs.dart b/lib/src/models/view/logs.dart index ffcc4934b..4fdce5b61 100644 --- a/lib/src/models/view/logs.dart +++ b/lib/src/models/view/logs.dart @@ -83,16 +83,21 @@ class LogsViewModel with ChangeNotifier { /// Disables [LogsOptionsViewModel.autoscroll] when the user scrolls manually. void onScroll() { - final enableAutoscroll = scrollController.position.pixels == scrollController.position.maxScrollExtent; + final enableAutoscroll = scrollController.position.pixels == 0; options.setAutoscroll(input: enableAutoscroll); } /// Scrolls to the bottom when a new log appears (if [LogsOptionsViewModel.autoscroll] is true). void onNewLog() { notifyListeners(); - if (options.autoscroll && scrollController.hasClients) { - scrollController.jumpTo(scrollController.position.maxScrollExtent); - } + if (!scrollController.hasClients) return; + scrollController.jumpTo(options.autoscroll ? 0 : scrollController.offset + 64); + } + + /// Jumps to the bottom of the logs. + void jumpToBottom() { + if (!scrollController.hasClients) return; + scrollController.animateTo(0, duration: const Duration(milliseconds: 500), curve: Curves.easeOutBack); } /// Updates the UI. @@ -106,6 +111,6 @@ class LogsViewModel with ChangeNotifier { if (log.level.value > options.levelFilter.value) continue; result.add(log); } - return result; + return result.reversed.toList(); } } diff --git a/lib/src/models/view/autonomy.dart b/lib/src/models/view/map.dart similarity index 95% rename from lib/src/models/view/autonomy.dart rename to lib/src/models/view/map.dart index 757a12d2e..c20e09142 100644 --- a/lib/src/models/view/autonomy.dart +++ b/lib/src/models/view/map.dart @@ -78,7 +78,7 @@ class AutonomyModel with ChangeNotifier { ], ]; - /// A list of markers maanually placed by the user. Useful for the Extreme Retrieval Mission. + /// A list of markers manually placed by the user. Useful for the Extreme Retrieval Mission. List markers = []; /// The view model to edit the coordinate of the marker. GpsBuilder markerBuilder = GpsBuilder(); @@ -92,8 +92,6 @@ class AutonomyModel with ChangeNotifier { /// The grid of size [gridSize] with the rover in the center, ready to draw on the UI. List> get grid { final result = empty; - markCell(result, data.destination, AutonomyCell.destination); - markCell(result, roverPosition, AutonomyCell.rover); for (final obstacle in data.obstacles) { markCell(result, obstacle, AutonomyCell.obstacle); } @@ -103,6 +101,9 @@ class AutonomyModel with ChangeNotifier { for (final marker in markers) { markCell(result, marker, AutonomyCell.marker); } + // Marks the rover and destination -- these should be last + if (data.hasDestination()) markCell(result, data.destination, AutonomyCell.destination); + markCell(result, roverPosition, AutonomyCell.rover); return result; } @@ -151,7 +152,7 @@ class AutonomyModel with ChangeNotifier { /// A handler to call when new data arrives. Updates [data] and the UI. void onNewData(AutonomyData value) { - data.mergeFromMessage(value); + data = value; services.files.logData(value); notifyListeners(); } diff --git a/lib/src/pages/home.dart b/lib/src/pages/home.dart index 8592bc51f..37cc0841c 100644 --- a/lib/src/pages/home.dart +++ b/lib/src/pages/home.dart @@ -95,11 +95,9 @@ class HomePageState extends State{ icon: const Icon(Icons.menu), onPressed: () => setState(() => showSidebar = !showSidebar), ),), - ], - ), - bottomNavigationBar: Footer(), + bottomNavigationBar: const Footer(), body: Row( children: [ const Expanded(child: ViewsWidget()), diff --git a/lib/src/pages/logs.dart b/lib/src/pages/logs.dart index 04e5205d5..05730bf01 100644 --- a/lib/src/pages/logs.dart +++ b/lib/src/pages/logs.dart @@ -2,7 +2,6 @@ import "package:flutter/material.dart"; import "package:rover_dashboard/data.dart"; import "package:rover_dashboard/models.dart"; -import "package:rover_dashboard/pages.dart"; import "package:rover_dashboard/widgets.dart"; /// A widget to show the options for the logs page. @@ -65,6 +64,7 @@ class LogsOptions extends ReactiveWidget { value: model.autoscroll, onChanged: (input) { model.setAutoscroll(input: input); + if (input ?? false) viewModel.jumpToBottom(); viewModel.update(); }, ),), @@ -86,57 +86,56 @@ class LogsState extends State { final model = LogsViewModel(); @override - Widget build(BuildContext context) => Stack( - children: [ - Column(children: [ - const SizedBox(height: 50), - LogsOptions(model), - const Divider(), - Expanded(child: LogsBody(model)), - ],), - Container( - color: context.colorScheme.surface, - height: 50, - child: Row(children: [ - const SizedBox(width: 8), - Text("Logs", style: context.textTheme.headlineMedium), - const Spacer(), - IconButton( - icon: const Icon(Icons.delete_forever), - onPressed: models.logs.clear, - tooltip: "Clear logs", - ), - IconButton( - icon: const Icon(Icons.help), - tooltip: "Help", - onPressed: () => showDialog( - context: context, - builder: (context) => AlertDialog( - title: const Text("Logs help"), - content: Column(mainAxisSize: MainAxisSize.min, children: [ - const Text("This page contains all logs received by the dashboard.\nSelecting a level means that only messages of that level or higher will be shown.", textAlign: TextAlign.center,), - const SizedBox(height: 4), - ListTile(leading: criticalWidget, title: const Text("Critical"), subtitle: const Text("The rover is in a broken state and may shutdown")), - const ListTile(leading: errorWidget, title: Text("Error"), subtitle: Text("Something you tried didn't work, but the rover can still function")), - const ListTile(leading: warningWidget, title: Text("Warning"), subtitle: Text("Something may have gone wrong, you should check it out")), - ListTile(leading: infoWidget, title: const Text("Info"), subtitle: const Text("The rover is functioning normally")), - const ListTile(leading: debugWidget, title: Text("Debug"), subtitle: Text("Extra information that shows what the rover's thinking")), - const ListTile(leading: traceWidget, title: Text("Trace"), subtitle: Text("Values from the code to debug specific issues")), - const SizedBox(height: 12), - ],), - actions: [ - ElevatedButton( - onPressed: () => Navigator.of(context).pop(), - child: const Text("Close"), - ), - ], - ), + Widget build(BuildContext context) => Scaffold( + body: Column(children: [ + const SizedBox(height: 12), + LogsOptions(model), + const Divider(), + Expanded(child: LogsBody(model)), + ],), + appBar: AppBar( + title: const Text("Logs"), + actions: [ + IconButton( + icon: const Icon(Icons.help), + tooltip: "Help", + onPressed: () => showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text("Logs help"), + content: Column(mainAxisSize: MainAxisSize.min, children: [ + const Text("This page contains all logs received by the dashboard.\nSelecting a level means that only messages of that level or higher will be shown.", textAlign: TextAlign.center,), + const SizedBox(height: 4), + ListTile(leading: criticalWidget, title: const Text("Critical"), subtitle: const Text("The rover is in a broken state and may shutdown")), + const ListTile(leading: errorWidget, title: Text("Error"), subtitle: Text("Something you tried didn't work, but the rover can still function")), + const ListTile(leading: warningWidget, title: Text("Warning"), subtitle: Text("Something may have gone wrong, you should check it out")), + ListTile(leading: infoWidget, title: const Text("Info"), subtitle: const Text("The rover is functioning normally")), + const ListTile(leading: debugWidget, title: Text("Debug"), subtitle: Text("Extra information that shows what the rover's thinking")), + const ListTile(leading: traceWidget, title: Text("Trace"), subtitle: Text("Values from the code to debug specific issues")), + const SizedBox(height: 12), + ],), + actions: [ + ElevatedButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text("Close"), + ), + ], ), ), - const ViewsSelector(currentView: Routes.logs), - ],), - ), - ], + ), + IconButton( + icon: const Icon(Icons.vertical_align_bottom), + onPressed: model.jumpToBottom, + tooltip: "Jump to bottom", + ), + IconButton( + icon: const Icon(Icons.delete_forever), + onPressed: models.logs.clear, + tooltip: "Clear logs", + ), + ], + ), + bottomNavigationBar: const Footer(showLogs: false), ); } @@ -158,6 +157,7 @@ class LogsBody extends ReactiveWidget { : ListView.builder( itemCount: model.logs.length, controller: model.scrollController, + reverse: true, itemBuilder: (context, index) => LogWidget(model.logs[index]), ); } diff --git a/lib/src/pages/autonomy.dart b/lib/src/pages/map.dart similarity index 98% rename from lib/src/pages/autonomy.dart rename to lib/src/pages/map.dart index 81cce31c5..e3cd6c628 100644 --- a/lib/src/pages/autonomy.dart +++ b/lib/src/pages/map.dart @@ -78,7 +78,7 @@ class MapPage extends StatelessWidget { builder: (model) => Stack(children: [ Column(children: [ const SizedBox(height: 48), - for (final row in model.grid) Expanded( + for (final row in model.grid.reversed) Expanded( child: Row(children: [ for (final cell in row) Expanded( child: Container( @@ -88,7 +88,7 @@ class MapPage extends StatelessWidget { child: cell != AutonomyCell.rover ? null : ProviderConsumer.value( value: models.rover.metrics.position, builder: (position) => Transform.rotate( - angle: position.angle * pi / 180, + angle: -position.angle * pi / 180, child: const Icon(Icons.arrow_upward, size: 24), ), ), diff --git a/lib/src/services/socket.dart b/lib/src/services/socket.dart index 6472d5e03..345b2826a 100644 --- a/lib/src/services/socket.dart +++ b/lib/src/services/socket.dart @@ -15,7 +15,7 @@ import "package:rover_dashboard/data.dart"; /// - Check [connectionStrength] or [isConnected] for the connection to the given [device]. /// - To send a message, call [sendMessage]. /// - Call [dispose] to close the socket. -class DashboardSocket extends ProtoSocket { +class DashboardSocket extends BurtUdpProtocol { /// A callback to run when the [device] has connected. void Function(Device device) onConnect; /// A callback to run when the [device] has disconnected. @@ -33,9 +33,11 @@ class DashboardSocket extends ProtoSocket { }) : super( port: null, quiet: true, - heartbeatInterval: const Duration(milliseconds: 200), ); + @override + Duration get heartbeatInterval => const Duration(milliseconds: 200); + /// The connection strength, as a percentage to this [device]. final connectionStrength = ValueNotifier(0); @@ -46,11 +48,9 @@ class DashboardSocket extends ProtoSocket { bool _isChecking = false; /// Whether this socket has a stable connection to the [device]. + @override bool get isConnected => connectionStrength.value > 0; - @override - void updateSettings(UpdateSetting settings) { } - @override void onMessage(WrappedMessage wrapper) => messageHandler(wrapper); diff --git a/lib/src/widgets/navigation/footer.dart b/lib/src/widgets/navigation/footer.dart index 7eca8e353..843f4ef73 100644 --- a/lib/src/widgets/navigation/footer.dart +++ b/lib/src/widgets/navigation/footer.dart @@ -3,18 +3,24 @@ import "package:provider/provider.dart"; import "package:rover_dashboard/data.dart"; import "package:rover_dashboard/models.dart"; +import "package:rover_dashboard/pages.dart"; import "package:rover_dashboard/services.dart"; import "package:rover_dashboard/widgets.dart"; /// The footer, responsible for showing vitals and logs. class Footer extends StatelessWidget { + /// Whether to show logs. Disable this when on the logs page. + final bool showLogs; + /// Creates the footer. + const Footer({this.showLogs = true}); + @override Widget build(BuildContext context) => ColoredBox( color: Theme.of(context).colorScheme.secondary, child: Wrap( alignment: WrapAlignment.spaceBetween, children: [ - const MessageDisplay(), + MessageDisplay(showLogs: showLogs), Wrap( // Groups these elements together even when wrapping // mainAxisSize: MainAxisSize.min, children: [ @@ -227,12 +233,15 @@ class SerialButton extends StatelessWidget { /// Displays the latest [TaskbarMessage] from [HomeModel.message]. class MessageDisplay extends ReactiveWidget { + /// Whether to show an option to open the logs page. + final bool showLogs; + + /// Provides a const constructor for this widget. + const MessageDisplay({required this.showLogs}) : super(shouldDispose: false); + @override HomeModel createModel() => models.home; - /// Provides a const constructor for this widget. - const MessageDisplay() : super(shouldDispose: false); - /// Gets the appropriate icon for the given severity. IconData getIcon(Severity? severity) { switch (severity) { @@ -259,21 +268,20 @@ class MessageDisplay extends ReactiveWidget { Widget build(BuildContext context, HomeModel model) => SizedBox( height: 48, child: InkWell( - onTap: models.views.openLogs, + onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) => LogsPage())), child: Card( shadowColor: Colors.transparent, color: getColor(model.message?.severity), shape: ContinuousRectangleBorder( borderRadius: BorderRadius.circular(12), ), - child: Row( + child: (model.message == null && !showLogs) ? const SizedBox() : Row( mainAxisSize: MainAxisSize.min, children: [ const SizedBox(width: 4), Icon(getIcon(model.message?.severity)), const SizedBox(width: 4), - if (model.message == null) - const Text("Open logs") + if (model.message == null) const Text("Open logs") else Tooltip( message: "Click to open logs", child: models.settings.easterEggs.enableClippy diff --git a/pubspec.lock b/pubspec.lock index b3caa4b44..eb5443965 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: archive - sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" url: "https://pub.dev" source: hosted - version: "3.4.9" + version: "3.4.10" args: dependency: transitive description: @@ -38,7 +38,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: "59df01fc4702c8e691bd3229b877bbe413cd209f" + resolved-ref: "566cb25e55663cc0fdafc5d94a44a482fbdb1cb8" url: "https://github.com/BinghamtonRover/Networking.git" source: git version: "1.1.0" @@ -62,10 +62,10 @@ packages: dependency: transitive description: name: cli_util - sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 + sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.4.1" clock: dependency: transitive description: @@ -158,10 +158,10 @@ packages: dependency: "direct main" description: name: fl_chart - sha256: "5a74434cc83bf64346efb562f1a06eefaf1bcb530dc3d96a104f631a1eff8d79" + sha256: fe6fec7d85975a99c73b9515a69a6e291364accfa0e4a5b3ce6de814d74b9a1c url: "https://pub.dev" source: hosted - version: "0.65.0" + version: "0.66.0" flutter: dependency: "direct main" description: flutter @@ -205,18 +205,18 @@ packages: dependency: transitive description: name: get_it - sha256: f79870884de16d689cf9a7d15eedf31ed61d750e813c538a6efb92660fea83c3 + sha256: e6017ce7fdeaf218dc51a100344d8cb70134b80e28b760f8bb23c242437bafd7 url: "https://pub.dev" source: hosted - version: "7.6.4" + version: "7.6.7" http: dependency: transitive description: name: http - sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.0" http_parser: dependency: transitive description: @@ -229,26 +229,26 @@ packages: dependency: "direct dev" description: name: icons_launcher - sha256: "0c4a46dfbc1e9025745c1d28949149d601bdf56a892338e74c4b4dd9a7066987" + sha256: "9b514ffed6ed69b232fd2bf34c44878c8526be71fc74129a658f35c04c9d4a9d" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.7" image: dependency: transitive description: name: image - sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271" + sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d" url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "4.1.4" js: dependency: transitive description: name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + sha256: "4186c61b32f99e60f011f7160e32c89a758ae9b1d0c6d28e2c02ef0382300e2b" url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.7.0" json_annotation: dependency: transitive description: @@ -349,26 +349,26 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -381,10 +381,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -405,26 +405,26 @@ packages: dependency: transitive description: name: platform - sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.1.8" pointycastle: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" protobuf: dependency: "direct main" description: @@ -522,34 +522,34 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba + sha256: d25bb0ca00432a5e1ee40e69c36c85863addf7cc45e433769d61bed3fe81fd96 url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.3" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" + sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.2" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 + sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.4" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" + sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" url_launcher_macos: dependency: transitive description: @@ -562,26 +562,26 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" + sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.1" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7" + sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" + sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" vector_math: dependency: transitive description: @@ -610,10 +610,10 @@ packages: dependency: transitive description: name: win32 - sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "5.2.0" win32_gamepad: dependency: "direct main" description: @@ -626,10 +626,10 @@ packages: dependency: transitive description: name: xdg_directories - sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" xml: dependency: transitive description: @@ -650,10 +650,10 @@ packages: dependency: "direct main" description: name: yaml_writer - sha256: "76740047e3d4b1687c588bc8cb3466bea55a7d915a91bb23e99ea2a8c58337b6" + sha256: f182931a598f9a3fd29ff528f0caab98fffa713583e30c12c7a27ce0b66c1308 url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "2.0.0" sdks: dart: ">=3.2.0 <4.0.0" flutter: ">=3.16.0" diff --git a/pubspec.yaml b/pubspec.yaml index 10c8a1264..d1e24ad0c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,7 +10,7 @@ environment: dependencies: async: ^2.11.0 file_picker: ^6.1.1 - fl_chart: ^0.65.0 + fl_chart: ^0.66.0 flutter: sdk: flutter flutter_libserialport: ^0.3.0 @@ -21,7 +21,7 @@ dependencies: url_launcher: ^6.1.10 win32_gamepad: ^1.0.3 yaml: ^3.1.1 - yaml_writer: ^1.0.2 + yaml_writer: ^2.0.0 burt_network: git: https://github.com/BinghamtonRover/Networking.git