refactor: logs page to shadcn

This commit is contained in:
Kingkor Roy Tirtho 2025-01-19 21:00:49 +06:00
parent e470f50e81
commit 74a328e529
6 changed files with 144 additions and 81 deletions

View File

@ -414,5 +414,6 @@
"no_tracks": "Looks like there are no tracks here",
"no_tracks_listened_yet": "Looks like you haven't listened to anything yet",
"not_following_artists": "You're not following any artists",
"no_favorite_albums_yet": "Looks like you haven't added any albums to your favorites yet"
"no_favorite_albums_yet": "Looks like you haven't added any albums to your favorites yet",
"no_logs_found": "No logs found"
}

View File

@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_undraw/flutter_undraw.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/button/back_button.dart';
import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart';
import 'package:spotube/components/titlebar/titlebar.dart';
import 'package:spotube/extensions/context.dart';
@ -21,54 +24,73 @@ class LogsPage extends HookConsumerWidget {
final logsQuery = ref.watch(logsProvider);
return Scaffold(
appBar: TitleBar(
title: Text(context.l10n.logs),
leading: const [BackButton()],
trailing: [
IconButton(
icon: const Icon(SpotubeIcons.clipboard),
iconSize: 16,
onPressed: () async {
final logsSnapshot = await ref.read(logsProvider.future);
headers: [
TitleBar(
title: Text(context.l10n.logs),
leading: const [BackButton()],
trailing: [
IconButton.ghost(
icon: const Icon(SpotubeIcons.clipboard, size: 16),
onPressed: () async {
final logsSnapshot = await ref.read(logsProvider.future);
await Clipboard.setData(ClipboardData(text: logsSnapshot));
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(context.l10n.copied_to_clipboard("")),
),
);
}
},
),
IconButton(
icon: const Icon(SpotubeIcons.trash),
iconSize: 16,
onPressed: () async {
ref.invalidate(logsProvider);
await Clipboard.setData(ClipboardData(text: logsSnapshot));
if (context.mounted) {
showToast(
context: context,
location: ToastLocation.topRight,
builder: (context, overlay) {
return SurfaceCard(
child: Basic(
title: Text(context.l10n.copied_to_clipboard("")),
),
);
},
);
}
},
),
IconButton.ghost(
icon: const Icon(
SpotubeIcons.trash,
size: 16,
),
onPressed: () async {
ref.invalidate(logsProvider);
final logsFile = await AppLogger.getLogsPath();
final logsFile = await AppLogger.getLogsPath();
await logsFile.writeAsString("");
},
)
],
),
body: SafeArea(
await logsFile.writeAsString("");
},
)
],
)
],
child: SafeArea(
child: switch (logsQuery) {
AsyncData(:final value) => Card(
child: InterScrollbar(
AsyncData(:final value) => InterScrollbar(
controller: controller,
child: SingleChildScrollView(
padding: const EdgeInsets.all(8.0),
controller: controller,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
controller: controller,
child: Text(value),
),
),
child: Card(child: SelectableText(value)),
),
),
AsyncError(:final error) => Center(child: Text(error.toString())),
AsyncError(:final error) => switch (error) {
StateError() => Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Undraw(
illustration: UndrawIllustration.noData,
height: 200 * context.theme.scaling,
width: 200 * context.theme.scaling,
color: context.theme.colorScheme.primary,
),
Text(context.l10n.no_logs_found).muted().small(),
],
),
_ => Center(child: Text(error.toString())),
},
_ => const Center(child: CircularProgressIndicator()),
},
),

View File

@ -1,9 +1,8 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart' show FilledButton, ButtonStyle, ListTile;
import 'package:flutter/material.dart' show ListTile;
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart' hide ButtonStyle;
import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
import 'package:spotube/collections/env.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/modules/settings/section_card_with_heading.dart';
@ -44,16 +43,25 @@ class SettingsAboutSection extends HookConsumerWidget {
),
),
),
trailing: (context, update) => FilledButton(
style: ButtonStyle(
backgroundColor: WidgetStatePropertyAll(Colors.red[100]),
foregroundColor: const WidgetStatePropertyAll(Colors.pink),
padding: const WidgetStatePropertyAll(EdgeInsets.all(15)),
shape: WidgetStatePropertyAll(
RoundedRectangleBorder(
borderRadius: context.theme.borderRadiusLg,
),
),
trailing: (context, update) => Button(
style: ButtonVariance.primary.copyWith(
decoration: (context, states, value) {
final decoration = ButtonVariance.primary
.decoration(context, states) as BoxDecoration;
if (states.contains(WidgetState.hovered)) {
return decoration.copyWith(color: Colors.pink[400]);
} else if (states.contains(WidgetState.focused)) {
return decoration.copyWith(color: Colors.pink[300]);
} else if (states.isNotEmpty) {
return decoration;
}
return decoration.copyWith(color: Colors.pink);
},
textStyle: (context, states, value) => ButtonVariance.primary
.textStyle(context, states)
.copyWith(color: Colors.white),
),
onPressed: () {
launchUrlString(

View File

@ -6,6 +6,11 @@ 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);
if (await stream.isEmpty) {
throw StateError('No logs found');
}
await for (final line in stream) {
yield line;
}

View File

@ -188,6 +188,7 @@ flutter:
- packages/flutter_undraw/assets/undraw/follow_me_drone.svg
- packages/flutter_undraw/assets/undraw/taken.svg
- packages/flutter_undraw/assets/undraw/empty.svg
- packages/flutter_undraw/assets/undraw/no_data.svg
fonts:
- family: GeistSans
fonts:

View File

@ -14,7 +14,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"bn": [
@ -32,7 +33,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"ca": [
@ -50,7 +52,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"cs": [
@ -68,7 +71,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"de": [
@ -86,7 +90,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"es": [
@ -104,7 +109,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"eu": [
@ -122,7 +128,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"fa": [
@ -140,7 +147,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"fi": [
@ -158,7 +166,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"fr": [
@ -176,7 +185,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"hi": [
@ -194,7 +204,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"id": [
@ -212,7 +223,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"it": [
@ -230,7 +242,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"ja": [
@ -248,7 +261,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"ka": [
@ -266,7 +280,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"ko": [
@ -284,7 +299,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"ne": [
@ -302,7 +318,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"nl": [
@ -320,7 +337,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"pl": [
@ -338,7 +356,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"pt": [
@ -356,7 +375,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"ru": [
@ -374,7 +394,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"th": [
@ -392,7 +413,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"tr": [
@ -410,7 +432,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"uk": [
@ -428,7 +451,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"vi": [
@ -446,7 +470,8 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
],
"zh": [
@ -464,6 +489,7 @@
"no_tracks",
"no_tracks_listened_yet",
"not_following_artists",
"no_favorite_albums_yet"
"no_favorite_albums_yet",
"no_logs_found"
]
}