Skip to content

Commit

Permalink
Misc cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Levi-Lesches committed Feb 9, 2024
1 parent 23c8187 commit 68231c7
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 82 deletions.
2 changes: 1 addition & 1 deletion lib/src/models/data/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
10 changes: 0 additions & 10 deletions lib/src/models/data/views.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,8 @@ class DashboardView {
static final List<DashboardView> 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,
Expand Down Expand Up @@ -142,10 +138,4 @@ class ViewsModel extends Model {
}
notifyListeners();
}

/// Opens the log page in a full-screen view.
void openLogs() {
views = [DashboardView.logView];
notifyListeners();
}
}
6 changes: 3 additions & 3 deletions lib/src/models/view/builders/autonomy_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class AutonomyCommandBuilder extends ValueBuilder<AutonomyCommand> {
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();
Expand All @@ -72,12 +72,12 @@ class AutonomyCommandBuilder extends ValueBuilder<AutonomyCommand> {
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<void>.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();
Expand Down
15 changes: 10 additions & 5 deletions lib/src/models/view/logs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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();
}
}
4 changes: 2 additions & 2 deletions lib/src/models/view/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class AutonomyModel with ChangeNotifier {
markCell(result, marker, AutonomyCell.marker);
}
// Marks the rover and destination -- these should be last
markCell(result, data.destination, AutonomyCell.destination);
if (data.hasDestination()) markCell(result, data.destination, AutonomyCell.destination);
markCell(result, roverPosition, AutonomyCell.rover);
return result;
}
Expand Down Expand Up @@ -152,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();
}
Expand Down
4 changes: 1 addition & 3 deletions lib/src/pages/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,9 @@ class HomePageState extends State<HomePage>{
icon: const Icon(Icons.menu),
onPressed: () => setState(() => showSidebar = !showSidebar),
),),

],

),
bottomNavigationBar: Footer(),
bottomNavigationBar: const Footer(),
body: Row(
children: [
const Expanded(child: ViewsWidget()),
Expand Down
100 changes: 50 additions & 50 deletions lib/src/pages/logs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -65,6 +64,7 @@ class LogsOptions extends ReactiveWidget<LogsOptionsViewModel> {
value: model.autoscroll,
onChanged: (input) {
model.setAutoscroll(input: input);
if (input ?? false) viewModel.jumpToBottom();
viewModel.update();
},
),),
Expand All @@ -86,57 +86,56 @@ class LogsState extends State<LogsPage> {
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<void>(
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<void>(
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),
);
}

Expand All @@ -158,6 +157,7 @@ class LogsBody extends ReactiveWidget<LogsViewModel> {
: ListView.builder(
itemCount: model.logs.length,
controller: model.scrollController,
reverse: true,
itemBuilder: (context, index) => LogWidget(model.logs[index]),
);
}
Expand Down
24 changes: 16 additions & 8 deletions lib/src/widgets/navigation/footer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
Expand Down Expand Up @@ -227,12 +233,15 @@ class SerialButton extends StatelessWidget {

/// Displays the latest [TaskbarMessage] from [HomeModel.message].
class MessageDisplay extends ReactiveWidget<HomeModel> {
/// 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) {
Expand All @@ -259,21 +268,20 @@ class MessageDisplay extends ReactiveWidget<HomeModel> {
Widget build(BuildContext context, HomeModel model) => SizedBox(
height: 48,
child: InkWell(
onTap: models.views.openLogs,
onTap: () => Navigator.of(context).push(MaterialPageRoute<void>(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
Expand Down

0 comments on commit 68231c7

Please sign in to comment.