refactor: logs page show full log

This commit is contained in:
Kingkor Roy Tirtho 2024-08-10 20:53:17 +06:00
parent 123eb168a3
commit 6456b43d10
3 changed files with 35 additions and 111 deletions

View File

@ -1,77 +1,23 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/modules/settings/section_card_with_heading.dart';
import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart';
import 'package:spotube/components/titlebar/titlebar.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/services/logger/logger.dart';
import 'package:spotube/provider/logs/logs_provider.dart';
class LogsPage extends HookWidget {
class LogsPage extends HookConsumerWidget {
static const name = "logs";
const LogsPage({super.key});
List<({DateTime? date, String body})> parseLogs(String raw) {
return raw
.split(
"======================================================================",
)
.map(
(line) {
DateTime? date;
line = line
.replaceAll(
"============================== CATCHER LOG ==============================",
"",
)
.split("\n")
.map((l) {
if (l.startsWith("Crash occurred on")) {
date = DateTime.parse(
l.split("Crash occurred on")[1].trim(),
);
return "";
}
return l;
})
.where((l) => l.replaceAll("\n", "").trim().isNotEmpty)
.join("\n");
return (
date: date,
body: line,
);
},
)
.where((e) => e.date != null && e.body.isNotEmpty)
.toList()
..sort((a, b) => b.date!.compareTo(a.date!));
}
@override
Widget build(BuildContext context) {
Widget build(BuildContext context, ref) {
final controller = useScrollController();
final logs = useState<List<({DateTime? date, String body})>>([]);
final rawLogs = useRef<String>("");
final path = useRef<File?>(null);
useEffect(() {
final timer = Timer.periodic(const Duration(seconds: 5), (t) async {
path.value ??= await AppLogger.getLogsPath();
final raw = await path.value!.readAsString();
final hasChanged = rawLogs.value != raw;
rawLogs.value = raw;
if (hasChanged) logs.value = parseLogs(rawLogs.value);
});
return () {
timer.cancel();
};
}, []);
final logsQuery = ref.watch(logsProvider);
return Scaffold(
appBar: PageWindowTitleBar(
@ -82,7 +28,9 @@ class LogsPage extends HookWidget {
icon: const Icon(SpotubeIcons.clipboard),
iconSize: 16,
onPressed: () async {
await Clipboard.setData(ClipboardData(text: rawLogs.value));
final logsSnapshot = await ref.read(logsProvider.future);
await Clipboard.setData(ClipboardData(text: logsSnapshot));
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
@ -95,53 +43,23 @@ class LogsPage extends HookWidget {
],
),
body: SafeArea(
child: switch (logsQuery) {
AsyncData(:final value) => Card(
child: InterScrollbar(
controller: controller,
child: ListView.builder(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
controller: controller,
itemCount: logs.value.length,
itemBuilder: (context, index) {
final log = logs.value[index];
return Stack(
children: [
SectionCardWithHeading(
heading: log.date.toString(),
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: SelectableText(log.body),
),
],
),
Positioned(
right: 10,
top: 0,
child: IconButton(
icon: const Icon(SpotubeIcons.clipboard),
onPressed: () async {
await Clipboard.setData(
ClipboardData(text: log.body),
);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
context.l10n.copied_to_clipboard(
log.date.toString(),
child: Text(value),
),
),
),
);
}
),
AsyncError(:final error) => Center(child: Text(error.toString())),
_ => const Center(child: CircularProgressIndicator()),
},
),
),
],
);
},
),
),
),
);
}
}

View File

@ -0,0 +1,12 @@
import 'dart:convert';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/services/logger/logger.dart';
final logsProvider = StreamProvider.autoDispose((ref) async* {
final file = await AppLogger.getLogsPath();
final stream = file.openRead().transform(utf8.decoder);
await for (final line in stream) {
yield line;
}
});

View File

@ -61,8 +61,6 @@ PODS:
- sqlite3/rtree
- system_theme (0.0.1):
- FlutterMacOS
- system_tray (0.0.1):
- FlutterMacOS
- tray_manager (0.0.1):
- FlutterMacOS
- url_launcher_macos (0.0.1):
@ -93,7 +91,6 @@ DEPENDENCIES:
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`)
- system_theme (from `Flutter/ephemeral/.symlinks/plugins/system_theme/macos`)
- system_tray (from `Flutter/ephemeral/.symlinks/plugins/system_tray/macos`)
- tray_manager (from `Flutter/ephemeral/.symlinks/plugins/tray_manager/macos`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
@ -148,8 +145,6 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos
system_theme:
:path: Flutter/ephemeral/.symlinks/plugins/system_theme/macos
system_tray:
:path: Flutter/ephemeral/.symlinks/plugins/system_tray/macos
tray_manager:
:path: Flutter/ephemeral/.symlinks/plugins/tray_manager/macos
url_launcher_macos:
@ -182,7 +177,6 @@ SPEC CHECKSUMS:
sqlite3: 292c3e1bfe89f64e51ea7fc7dab9182a017c8630
sqlite3_flutter_libs: 1be4459672f8168ded2d8667599b8e3ca5e72b83
system_theme: c7b9f6659a5caa26c9bc2284da096781e9a6fcbc
system_tray: e53c972838c69589ff2e77d6d3abfd71332f9e5d
tray_manager: 9064e219c56d75c476e46b9a21182087930baf90
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8