mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
refactor: logs page show full log
This commit is contained in:
parent
123eb168a3
commit
6456b43d10
@ -1,77 +1,23 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.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/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/inter_scrollbar/inter_scrollbar.dart';
|
||||||
import 'package:spotube/components/titlebar/titlebar.dart';
|
import 'package:spotube/components/titlebar/titlebar.dart';
|
||||||
import 'package:spotube/extensions/context.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";
|
static const name = "logs";
|
||||||
|
|
||||||
const LogsPage({super.key});
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context, ref) {
|
||||||
final controller = useScrollController();
|
final controller = useScrollController();
|
||||||
final logs = useState<List<({DateTime? date, String body})>>([]);
|
|
||||||
final rawLogs = useRef<String>("");
|
|
||||||
final path = useRef<File?>(null);
|
|
||||||
|
|
||||||
useEffect(() {
|
final logsQuery = ref.watch(logsProvider);
|
||||||
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();
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: PageWindowTitleBar(
|
appBar: PageWindowTitleBar(
|
||||||
@ -82,7 +28,9 @@ class LogsPage extends HookWidget {
|
|||||||
icon: const Icon(SpotubeIcons.clipboard),
|
icon: const Icon(SpotubeIcons.clipboard),
|
||||||
iconSize: 16,
|
iconSize: 16,
|
||||||
onPressed: () async {
|
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) {
|
if (context.mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
@ -95,52 +43,22 @@ class LogsPage extends HookWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: InterScrollbar(
|
child: switch (logsQuery) {
|
||||||
controller: controller,
|
AsyncData(:final value) => Card(
|
||||||
child: ListView.builder(
|
child: InterScrollbar(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
itemCount: logs.value.length,
|
child: Padding(
|
||||||
itemBuilder: (context, index) {
|
padding: const EdgeInsets.all(8.0),
|
||||||
final log = logs.value[index];
|
child: SingleChildScrollView(
|
||||||
return Stack(
|
controller: controller,
|
||||||
children: [
|
child: Text(value),
|
||||||
SectionCardWithHeading(
|
|
||||||
heading: log.date.toString(),
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(12.0),
|
|
||||||
child: SelectableText(log.body),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
Positioned(
|
),
|
||||||
right: 10,
|
),
|
||||||
top: 0,
|
),
|
||||||
child: IconButton(
|
AsyncError(:final error) => Center(child: Text(error.toString())),
|
||||||
icon: const Icon(SpotubeIcons.clipboard),
|
_ => const Center(child: CircularProgressIndicator()),
|
||||||
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(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
12
lib/provider/logs/logs_provider.dart
Normal file
12
lib/provider/logs/logs_provider.dart
Normal 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;
|
||||||
|
}
|
||||||
|
});
|
@ -61,8 +61,6 @@ PODS:
|
|||||||
- sqlite3/rtree
|
- sqlite3/rtree
|
||||||
- system_theme (0.0.1):
|
- system_theme (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- system_tray (0.0.1):
|
|
||||||
- FlutterMacOS
|
|
||||||
- tray_manager (0.0.1):
|
- tray_manager (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- url_launcher_macos (0.0.1):
|
- url_launcher_macos (0.0.1):
|
||||||
@ -93,7 +91,6 @@ DEPENDENCIES:
|
|||||||
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
|
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
|
||||||
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`)
|
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`)
|
||||||
- system_theme (from `Flutter/ephemeral/.symlinks/plugins/system_theme/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`)
|
- tray_manager (from `Flutter/ephemeral/.symlinks/plugins/tray_manager/macos`)
|
||||||
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||||
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/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
|
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos
|
||||||
system_theme:
|
system_theme:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/system_theme/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/system_theme/macos
|
||||||
system_tray:
|
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/system_tray/macos
|
|
||||||
tray_manager:
|
tray_manager:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/tray_manager/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/tray_manager/macos
|
||||||
url_launcher_macos:
|
url_launcher_macos:
|
||||||
@ -182,7 +177,6 @@ SPEC CHECKSUMS:
|
|||||||
sqlite3: 292c3e1bfe89f64e51ea7fc7dab9182a017c8630
|
sqlite3: 292c3e1bfe89f64e51ea7fc7dab9182a017c8630
|
||||||
sqlite3_flutter_libs: 1be4459672f8168ded2d8667599b8e3ca5e72b83
|
sqlite3_flutter_libs: 1be4459672f8168ded2d8667599b8e3ca5e72b83
|
||||||
system_theme: c7b9f6659a5caa26c9bc2284da096781e9a6fcbc
|
system_theme: c7b9f6659a5caa26c9bc2284da096781e9a6fcbc
|
||||||
system_tray: e53c972838c69589ff2e77d6d3abfd71332f9e5d
|
|
||||||
tray_manager: 9064e219c56d75c476e46b9a21182087930baf90
|
tray_manager: 9064e219c56d75c476e46b9a21182087930baf90
|
||||||
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
|
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
|
||||||
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
|
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
|
||||||
|
Loading…
Reference in New Issue
Block a user