mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
refactor: logs page to shadcn
This commit is contained in:
parent
e470f50e81
commit
74a328e529
@ -414,5 +414,6 @@
|
|||||||
"no_tracks": "Looks like there are no tracks here",
|
"no_tracks": "Looks like there are no tracks here",
|
||||||
"no_tracks_listened_yet": "Looks like you haven't listened to anything yet",
|
"no_tracks_listened_yet": "Looks like you haven't listened to anything yet",
|
||||||
"not_following_artists": "You're not following any artists",
|
"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"
|
||||||
}
|
}
|
@ -1,8 +1,11 @@
|
|||||||
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:flutter_undraw/flutter_undraw.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.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/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/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';
|
||||||
@ -21,29 +24,37 @@ class LogsPage extends HookConsumerWidget {
|
|||||||
final logsQuery = ref.watch(logsProvider);
|
final logsQuery = ref.watch(logsProvider);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: TitleBar(
|
headers: [
|
||||||
|
TitleBar(
|
||||||
title: Text(context.l10n.logs),
|
title: Text(context.l10n.logs),
|
||||||
leading: const [BackButton()],
|
leading: const [BackButton()],
|
||||||
trailing: [
|
trailing: [
|
||||||
IconButton(
|
IconButton.ghost(
|
||||||
icon: const Icon(SpotubeIcons.clipboard),
|
icon: const Icon(SpotubeIcons.clipboard, size: 16),
|
||||||
iconSize: 16,
|
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final logsSnapshot = await ref.read(logsProvider.future);
|
final logsSnapshot = await ref.read(logsProvider.future);
|
||||||
|
|
||||||
await Clipboard.setData(ClipboardData(text: logsSnapshot));
|
await Clipboard.setData(ClipboardData(text: logsSnapshot));
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
showToast(
|
||||||
SnackBar(
|
context: context,
|
||||||
content: Text(context.l10n.copied_to_clipboard("")),
|
location: ToastLocation.topRight,
|
||||||
|
builder: (context, overlay) {
|
||||||
|
return SurfaceCard(
|
||||||
|
child: Basic(
|
||||||
|
title: Text(context.l10n.copied_to_clipboard("")),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton.ghost(
|
||||||
icon: const Icon(SpotubeIcons.trash),
|
icon: const Icon(
|
||||||
iconSize: 16,
|
SpotubeIcons.trash,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
ref.invalidate(logsProvider);
|
ref.invalidate(logsProvider);
|
||||||
|
|
||||||
@ -53,22 +64,33 @@ class LogsPage extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
body: SafeArea(
|
],
|
||||||
|
child: SafeArea(
|
||||||
child: switch (logsQuery) {
|
child: switch (logsQuery) {
|
||||||
AsyncData(:final value) => Card(
|
AsyncData(:final value) => InterScrollbar(
|
||||||
child: InterScrollbar(
|
|
||||||
controller: controller,
|
controller: controller,
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
controller: controller,
|
controller: controller,
|
||||||
child: Text(value),
|
child: Card(child: SelectableText(value)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
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(),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
AsyncError(:final error) => Center(child: Text(error.toString())),
|
_ => Center(child: Text(error.toString())),
|
||||||
|
},
|
||||||
_ => const Center(child: CircularProgressIndicator()),
|
_ => const Center(child: CircularProgressIndicator()),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import 'package:auto_size_text/auto_size_text.dart';
|
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:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:shadcn_flutter/shadcn_flutter.dart' hide ButtonStyle;
|
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/env.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/modules/settings/section_card_with_heading.dart';
|
||||||
@ -44,16 +43,25 @@ class SettingsAboutSection extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
trailing: (context, update) => FilledButton(
|
trailing: (context, update) => Button(
|
||||||
style: ButtonStyle(
|
style: ButtonVariance.primary.copyWith(
|
||||||
backgroundColor: WidgetStatePropertyAll(Colors.red[100]),
|
decoration: (context, states, value) {
|
||||||
foregroundColor: const WidgetStatePropertyAll(Colors.pink),
|
final decoration = ButtonVariance.primary
|
||||||
padding: const WidgetStatePropertyAll(EdgeInsets.all(15)),
|
.decoration(context, states) as BoxDecoration;
|
||||||
shape: WidgetStatePropertyAll(
|
|
||||||
RoundedRectangleBorder(
|
if (states.contains(WidgetState.hovered)) {
|
||||||
borderRadius: context.theme.borderRadiusLg,
|
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: () {
|
onPressed: () {
|
||||||
launchUrlString(
|
launchUrlString(
|
||||||
|
@ -6,6 +6,11 @@ import 'package:spotube/services/logger/logger.dart';
|
|||||||
final logsProvider = StreamProvider.autoDispose((ref) async* {
|
final logsProvider = StreamProvider.autoDispose((ref) async* {
|
||||||
final file = await AppLogger.getLogsPath();
|
final file = await AppLogger.getLogsPath();
|
||||||
final stream = file.openRead().transform(utf8.decoder);
|
final stream = file.openRead().transform(utf8.decoder);
|
||||||
|
|
||||||
|
if (await stream.isEmpty) {
|
||||||
|
throw StateError('No logs found');
|
||||||
|
}
|
||||||
|
|
||||||
await for (final line in stream) {
|
await for (final line in stream) {
|
||||||
yield line;
|
yield line;
|
||||||
}
|
}
|
||||||
|
@ -188,6 +188,7 @@ flutter:
|
|||||||
- packages/flutter_undraw/assets/undraw/follow_me_drone.svg
|
- packages/flutter_undraw/assets/undraw/follow_me_drone.svg
|
||||||
- packages/flutter_undraw/assets/undraw/taken.svg
|
- packages/flutter_undraw/assets/undraw/taken.svg
|
||||||
- packages/flutter_undraw/assets/undraw/empty.svg
|
- packages/flutter_undraw/assets/undraw/empty.svg
|
||||||
|
- packages/flutter_undraw/assets/undraw/no_data.svg
|
||||||
fonts:
|
fonts:
|
||||||
- family: GeistSans
|
- family: GeistSans
|
||||||
fonts:
|
fonts:
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"bn": [
|
"bn": [
|
||||||
@ -32,7 +33,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ca": [
|
"ca": [
|
||||||
@ -50,7 +52,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"cs": [
|
"cs": [
|
||||||
@ -68,7 +71,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"de": [
|
"de": [
|
||||||
@ -86,7 +90,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"es": [
|
"es": [
|
||||||
@ -104,7 +109,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"eu": [
|
"eu": [
|
||||||
@ -122,7 +128,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fa": [
|
"fa": [
|
||||||
@ -140,7 +147,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fi": [
|
"fi": [
|
||||||
@ -158,7 +166,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fr": [
|
"fr": [
|
||||||
@ -176,7 +185,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"hi": [
|
"hi": [
|
||||||
@ -194,7 +204,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"id": [
|
"id": [
|
||||||
@ -212,7 +223,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"it": [
|
"it": [
|
||||||
@ -230,7 +242,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
@ -248,7 +261,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ka": [
|
"ka": [
|
||||||
@ -266,7 +280,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ko": [
|
"ko": [
|
||||||
@ -284,7 +299,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ne": [
|
"ne": [
|
||||||
@ -302,7 +318,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"nl": [
|
"nl": [
|
||||||
@ -320,7 +337,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pl": [
|
"pl": [
|
||||||
@ -338,7 +356,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
@ -356,7 +375,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ru": [
|
"ru": [
|
||||||
@ -374,7 +394,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"th": [
|
"th": [
|
||||||
@ -392,7 +413,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"tr": [
|
"tr": [
|
||||||
@ -410,7 +432,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"uk": [
|
"uk": [
|
||||||
@ -428,7 +451,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"vi": [
|
"vi": [
|
||||||
@ -446,7 +470,8 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
@ -464,6 +489,7 @@
|
|||||||
"no_tracks",
|
"no_tracks",
|
||||||
"no_tracks_listened_yet",
|
"no_tracks_listened_yet",
|
||||||
"not_following_artists",
|
"not_following_artists",
|
||||||
"no_favorite_albums_yet"
|
"no_favorite_albums_yet",
|
||||||
|
"no_logs_found"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user