Skip to content

Commit

Permalink
improved log file screen
Browse files Browse the repository at this point in the history
  • Loading branch information
clragon committed Nov 28, 2023
1 parent 1dfeab8 commit f318777
Show file tree
Hide file tree
Showing 8 changed files with 472 additions and 157 deletions.
2 changes: 1 addition & 1 deletion lib/app/widgets/errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ErrorNotifier extends StatelessWidget {
.currentState!
.push(
MaterialPageRoute(
builder: (context) => LogRecordsPage(logs: logs),
builder: (context) => const LogsPage(),
),
),
child: child,
Expand Down
83 changes: 83 additions & 0 deletions lib/interface/widgets/navigation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,86 @@ class _RouterDrawerEntryState<T extends Widget>
return widget.child;
}
}

class AppBarDismissalProxy extends StatefulWidget {
/// Tricks the enclosed Route into thinking it can be popped.
///
/// This is necessary to escape nested navigators.
/// The enclosing navigator has to appropriately handle the pop.
const AppBarDismissalProxy({
super.key,
this.enabled = true,
required this.child,
});

/// Whether the enclosed Route can be popped.
final bool enabled;

/// The widget below this widget in the tree.
final Widget child;

@override
State<AppBarDismissalProxy> createState() => _AppBarDismissalProxyState();
}

class _AppBarDismissalProxyState extends State<AppBarDismissalProxy> {
LocalHistoryEntry? _entry;

late ModalRoute<dynamic> _modalRoute = ModalRoute.of<dynamic>(context)!;

@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (widget.enabled) {
_modalRoute.addLocalHistoryEntry(createEntry());
}
});
}

LocalHistoryEntry createEntry() {
return _entry = LocalHistoryEntry(
onRemove: () => _entry = null,
);
}

@override
void didUpdateWidget(covariant AppBarDismissalProxy oldWidget) {
if (widget.enabled != oldWidget.enabled) {
if (widget.enabled) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_modalRoute.addLocalHistoryEntry(createEntry());
});
} else {
WidgetsBinding.instance.addPostFrameCallback((_) {
_modalRoute.removeLocalHistoryEntry(_entry!);
});
}
}
super.didUpdateWidget(oldWidget);
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
ModalRoute route = ModalRoute.of<dynamic>(context)!;
if (route != _modalRoute) {
_modalRoute.removeLocalHistoryEntry(_entry!);
_modalRoute = route;
WidgetsBinding.instance.addPostFrameCallback((_) {
_modalRoute.addLocalHistoryEntry(createEntry());
});
}
}

@override
void dispose() {
if (_entry != null) {
_modalRoute.removeLocalHistoryEntry(_entry!);
}
super.dispose();
}

@override
Widget build(BuildContext context) => widget.child;
}
9 changes: 1 addition & 8 deletions lib/logs/data/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,7 @@ class RouteLoggerObserver extends NavigatorObserver {
void logRoute(Route<dynamic>? route, String action) {
if (route == null) return;
String? name = route.settings.name;
if (name == null) {
if (route is PageRoute) {
name = 'A page';
} else if (route is ModalRoute) {
name = 'A modal';
}
}
name ??= 'A route';
if (name == null) return;
loggy.debug('$name $action');
}

Expand Down
1 change: 0 additions & 1 deletion lib/logs/logs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export 'data/routes.dart';
// widgets
export 'widgets/appbar.dart';
export 'widgets/card.dart';
export 'widgets/dialog.dart';
export 'widgets/drawer.dart';
export 'widgets/error.dart';
export 'widgets/expandable.dart';
Expand Down
71 changes: 71 additions & 0 deletions lib/logs/widgets/appbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,74 @@ class LogSelectionAppBar extends StatelessWidget with AppBarBuilderWidget {
);
}
}

class LogFileSelectionAppBar extends StatelessWidget with AppBarBuilderWidget {
const LogFileSelectionAppBar({
super.key,
required this.child,
this.onDelete,
});

@override
final PreferredSizeWidget child;
final ValueSetter<List<LogFileInfo>>? onDelete;

@override
Widget build(BuildContext context) {
return SelectionAppBar<LogFileInfo>(
child: child,
titleBuilder: (context, data) => data.selections.length == 1
? Text('Logs - ${data.selections.first.date}')
: Text('${data.selections.length} log files'),
actionBuilder: (context, data) => [
if (onDelete != null)
IconButton(
tooltip: 'Delete',
icon: const Icon(Icons.delete),
onPressed: () => showDialog(
context: context,
builder: (context) => LogFileDeleteConfirmation(
files: data.selections.toList(),
onConfirm: () {
onDelete?.call(data.selections.toList());
data.onChanged({});
},
),
),
),
],
);
}
}

class LogFileDeleteConfirmation extends StatelessWidget {
const LogFileDeleteConfirmation({
super.key,
required this.files,
required this.onConfirm,
});

final List<LogFileInfo> files;
final VoidCallback? onConfirm;

@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Delete ${files.length} log files?'),
content: const Text('This action cannot be undone.'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel'),
),
TextButton(
onPressed: () {
onConfirm?.call();
Navigator.of(context).pop();
},
child: const Text('Delete'),
),
],
);
}
}
74 changes: 0 additions & 74 deletions lib/logs/widgets/dialog.dart

This file was deleted.

Loading

0 comments on commit f318777

Please sign in to comment.