格式化代码

This commit is contained in:
rang 2025-10-25 10:38:56 +08:00
parent a28547685b
commit b3a9d76c78
24 changed files with 611 additions and 451 deletions

View file

@ -26,8 +26,8 @@ class ExplorePage extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// hooks for the dark mode
final settings = ref.watch(appSettingsProvider);
final api = ref.watch(authenticatedApiProvider);
ref.watch(appSettingsProvider);
// final api = ref.watch(authenticatedApiProvider);
return Scaffold(
appBar: AppBar(
title: Text(S.of(context).explore),
@ -62,8 +62,8 @@ class MySearchBar extends HookConsumerWidget {
currentQuery = query;
// In a real application, there should be some error handling here.
final options =
await api.libraries.search(libraryId: settings.activeLibraryId!, query: query, limit: 3);
final options = await api.libraries
.search(libraryId: settings.activeLibraryId!, query: query, limit: 3);
// If another search happened after this one, throw away these options.
if (currentQuery != query) {
@ -98,7 +98,10 @@ class MySearchBar extends HookConsumerWidget {
// opacity: 0.5 for the hint text
hintStyle: WidgetStatePropertyAll(
Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.5),
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.5),
),
),
textInputAction: TextInputAction.search,
@ -231,8 +234,9 @@ class BookSearchResultMini extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final item = ref.watch(libraryItemProvider(book.libraryItemId)).valueOrNull;
final image =
item == null ? const AsyncValue.loading() : ref.watch(coverImageProvider(item.id));
final image = item == null
? const AsyncValue.loading()
: ref.watch(coverImageProvider(item.id));
return ListTile(
leading: SizedBox(
width: 50,

View file

@ -77,9 +77,11 @@ class LibraryItemActions extends HookConsumerWidget {
IconButton(
onPressed: () {
appLogger.fine('Sharing');
var currentServerUrl = apiSettings.activeServer!.serverUrl;
var currentServerUrl =
apiSettings.activeServer!.serverUrl;
if (!currentServerUrl.hasScheme) {
currentServerUrl = Uri.https(currentServerUrl.toString());
currentServerUrl =
Uri.https(currentServerUrl.toString());
}
handleLaunchUrl(
Uri.parse(
@ -138,7 +140,8 @@ class LibraryItemActions extends HookConsumerWidget {
FileDownloader()
.database
.deleteRecordWithId(
record.task.taskId,
record
.task.taskId,
);
Navigator.pop(context);
},
@ -157,7 +160,8 @@ class LibraryItemActions extends HookConsumerWidget {
},
onTap: () async {
// open the file location
final didOpen = await FileDownloader().openFile(
final didOpen =
await FileDownloader().openFile(
task: record.task,
);
@ -226,7 +230,9 @@ class LibItemDownloadButton extends HookConsumerWidget {
onPressed: () {
appLogger.fine('Pressed download button');
ref.read(downloadManagerProvider.notifier).queueAudioBookDownload(item);
ref
.read(downloadManagerProvider.notifier)
.queueAudioBookDownload(item);
},
icon: const Icon(
Icons.download_rounded,
@ -245,7 +251,10 @@ class ItemCurrentlyInDownloadQueue extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final progress = ref.watch(itemDownloadProgressProvider(item.id)).valueOrNull?.clamp(0.05, 1.0);
final progress = ref
.watch(itemDownloadProgressProvider(item.id))
.valueOrNull
?.clamp(0.05, 1.0);
if (progress == 1) {
return AlreadyItemDownloadedButton(item: item);
@ -333,7 +342,7 @@ class DownloadSheet extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final manager = ref.watch(downloadManagerProvider);
// final manager = ref.watch(downloadManagerProvider);
return Column(
mainAxisSize: MainAxisSize.min,
@ -377,7 +386,9 @@ class DownloadSheet extends HookConsumerWidget {
TextButton(
onPressed: () {
// delete the file
ref.read(downloadManagerProvider.notifier).deleteDownloadedItem(
ref
.read(downloadManagerProvider.notifier)
.deleteDownloadedItem(
item,
);
GoRouter.of(context).pop(true);
@ -396,7 +407,8 @@ class DownloadSheet extends HookConsumerWidget {
);
if (wasDeleted ?? false) {
appLogger.fine(S.of(context).deleted(item.media.metadata.title ?? ''));
appLogger
.fine(S.of(context).deleted(item.media.metadata.title ?? ''));
GoRouter.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
@ -520,7 +532,8 @@ Future<void> libraryItemPlayButtonOnPressed({
appLogger.info('Setting the book ${book.libraryItemId}');
appLogger.info('Initial position: ${userMediaProgress?.currentTime}');
final downloadManager = ref.watch(simpleDownloadManagerProvider);
final libItem = await ref.read(libraryItemProvider(book.libraryItemId).future);
final libItem =
await ref.read(libraryItemProvider(book.libraryItemId).future);
final downloadedUris = await downloadManager.getDownloadedFilesUri(libItem);
setSourceFuture = player.setSourceAudiobook(
book,
@ -536,23 +549,27 @@ Future<void> libraryItemPlayButtonOnPressed({
}
}
// set the volume as this is the first time playing and dismissing causes the volume to go to 0
var bookPlayerSettings = ref.read(bookSettingsProvider(book.libraryItemId)).playerSettings;
var bookPlayerSettings =
ref.read(bookSettingsProvider(book.libraryItemId)).playerSettings;
var appPlayerSettings = ref.read(appSettingsProvider).playerSettings;
var configurePlayerForEveryBook = appPlayerSettings.configurePlayerForEveryBook;
var configurePlayerForEveryBook =
appPlayerSettings.configurePlayerForEveryBook;
await Future.wait([
setSourceFuture ?? Future.value(),
// set the volume
player.setVolume(
configurePlayerForEveryBook
? bookPlayerSettings.preferredDefaultVolume ?? appPlayerSettings.preferredDefaultVolume
? bookPlayerSettings.preferredDefaultVolume ??
appPlayerSettings.preferredDefaultVolume
: appPlayerSettings.preferredDefaultVolume,
),
// set the speed
player.setSpeed(
configurePlayerForEveryBook
? bookPlayerSettings.preferredDefaultSpeed ?? appPlayerSettings.preferredDefaultSpeed
? bookPlayerSettings.preferredDefaultSpeed ??
appPlayerSettings.preferredDefaultSpeed
: appPlayerSettings.preferredDefaultSpeed,
),
]);

View file

@ -25,8 +25,9 @@ class LibraryItemMetadata extends HookConsumerWidget {
if (book == null) {
return null;
}
final duration =
book.audioFiles.map((e) => e.duration).reduce((value, element) => value + element);
final duration = book.audioFiles
.map((e) => e.duration)
.reduce((value, element) => value + element);
final hours = duration.inHours;
final minutes = duration.inMinutes.remainder(60);
return '${hours}h ${minutes}m';
@ -41,8 +42,9 @@ class LibraryItemMetadata extends HookConsumerWidget {
if (book == null) {
return null;
}
final size =
book.audioFiles.map((e) => e.metadata.size).reduce((value, element) => value + element);
final size = book.audioFiles
.map((e) => e.metadata.size)
.reduce((value, element) => value + element);
if (size / 1024 / 1024 < 1024) {
return '${(size / 1024 / 1024).toStringAsFixed(2)} MB';
}
@ -98,7 +100,10 @@ class LibraryItemMetadata extends HookConsumerWidget {
return VerticalDivider(
indent: 6,
endIndent: 6,
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.6),
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.6),
);
},
),

View file

@ -28,7 +28,8 @@ class LibraryItemPage extends HookConsumerWidget {
static const double _showFabThreshold = 300.0;
@override
Widget build(BuildContext context, WidgetRef ref) {
final additionalItemData = extra is LibraryItemExtras ? extra as LibraryItemExtras : null;
final additionalItemData =
extra is LibraryItemExtras ? extra as LibraryItemExtras : null;
final scrollController = useScrollController();
final showFab = useState(false);
@ -151,7 +152,8 @@ class LibraryItemDescription extends HookConsumerWidget {
}
return ExpandableDescription(
title: S.of(context).bookAbout,
content: item.media.metadata.description ?? S.of(context).bookAboutDefault,
content:
item.media.metadata.description ?? S.of(context).bookAboutDefault,
readMoreText: S.of(context).readMore,
readLessText: S.of(context).readLess,
);
@ -168,8 +170,10 @@ double calculateWidth(
/// height ratio of the cover image to the available height
double maxHeightToUse = 0.25,
}) {
final availHeight = min(constraints.maxHeight, MediaQuery.of(context).size.height);
final availWidth = min(constraints.maxWidth, MediaQuery.of(context).size.width);
final availHeight =
min(constraints.maxHeight, MediaQuery.of(context).size.height);
final availWidth =
min(constraints.maxWidth, MediaQuery.of(context).size.width);
// make the width widthRatio of the available width
var width = availWidth * widthRatio;

View file

@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/api/library_provider.dart' show currentLibraryProvider;
import 'package:vaani/features/you/view/widgets/library_switch_chip.dart' show showLibrarySwitcher;
import 'package:vaani/features/you/view/widgets/library_switch_chip.dart'
show showLibrarySwitcher;
import 'package:vaani/generated/l10n.dart';
import 'package:vaani/router/router.dart' show Routes;
import 'package:vaani/shared/icons/abs_icons.dart' show AbsIcons;
import 'package:vaani/shared/widgets/not_implemented.dart' show showNotImplementedToast;
import 'package:vaani/shared/widgets/not_implemented.dart'
show showNotImplementedToast;
class LibraryBrowserPage extends HookConsumerWidget {
const LibraryBrowserPage({super.key});
@ -32,7 +34,9 @@ class LibraryBrowserPage extends HookConsumerWidget {
// true, // Optional: uncomment if you want snapping behavior (usually with floating: true)
leading: IconButton(
icon: Icon(libraryIconData),
tooltip: S.of(context).librarySwitchTooltip, // Helpful tooltip for users
tooltip: S
.of(context)
.librarySwitchTooltip, // Helpful tooltip for users
onPressed: () {
showLibrarySwitcher(context, ref);
},

View file

@ -1,7 +1,8 @@
import 'package:logging/logging.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:vaani/db/available_boxes.dart';
import 'package:vaani/features/per_book_settings/models/book_settings.dart' as model;
import 'package:vaani/features/per_book_settings/models/book_settings.dart'
as model;
import 'package:vaani/features/per_book_settings/models/nullable_player_settings.dart';
part 'book_settings_provider.g.dart';

View file

@ -122,9 +122,11 @@ class AudiobookPlayer extends AudioPlayer {
final trackToPlay = getTrackToPlay(book, initialPosition ?? Duration.zero);
final initialIndex = book.tracks.indexOf(trackToPlay);
final initialPositionInTrack =
initialPosition != null ? initialPosition - trackToPlay.startOffset : null;
await setAudioSourceTrack(initialIndex, initialPosition: initialPositionInTrack);
final initialPositionInTrack = initialPosition != null
? initialPosition - trackToPlay.startOffset
: null;
await setAudioSourceTrack(initialIndex,
initialPosition: initialPositionInTrack);
// _logger.finer('Setting audioSource');
// await setAudioSource(
// preload: preload,
@ -158,7 +160,8 @@ class AudiobookPlayer extends AudioPlayer {
// });
}
Future<void> setAudioSourceTrack(int index, {Duration? initialPosition}) async {
Future<void> setAudioSourceTrack(int index,
{Duration? initialPosition}) async {
if (_book == null) {
return stop();
}
@ -168,9 +171,11 @@ class AudiobookPlayer extends AudioPlayer {
_currentIndex = index;
AudioTrack track = _book!.tracks[index];
final appSettings = loadOrCreateAppSettings();
final playerSettings = readFromBoxOrCreate(_book!.libraryItemId).playerSettings;
final playerSettings =
readFromBoxOrCreate(_book!.libraryItemId).playerSettings;
final retrievedUri = _getUri(track, _downloadedUris, baseUrl: baseUrl, token: token);
final retrievedUri =
_getUri(track, _downloadedUris, baseUrl: baseUrl, token: token);
await setAudioSource(
initialPosition: initialPosition == null || initialPosition <= Duration()
@ -185,8 +190,10 @@ class AudiobookPlayer extends AudioPlayer {
// Specify a unique ID for each media item:
id: '${book?.libraryItemId}${track.index}',
// Metadata to display in the notification:
title: appSettings.notificationSettings.primaryTitle.formatNotificationTitle(book!),
album: appSettings.notificationSettings.secondaryTitle.formatNotificationTitle(book!),
title: appSettings.notificationSettings.primaryTitle
.formatNotificationTitle(book!),
album: appSettings.notificationSettings.secondaryTitle
.formatNotificationTitle(book!),
artUri: Uri.parse(
'$baseUrl/api/items/${book?.libraryItemId}/cover?token=$token&width=800',
),
@ -392,7 +399,8 @@ Uri _getUri(
},
);
return uri ?? Uri.parse('${baseUrl.toString()}${track.contentUrl}?token=$token');
return uri ??
Uri.parse('${baseUrl.toString()}${track.contentUrl}?token=$token');
}
extension FormatNotificationTitle on String {

View file

@ -31,7 +31,8 @@ class AudiobookPlayer extends HookConsumerWidget {
if (currentBook == null) {
return const SizedBox.shrink();
}
final itemBeingPlayed = ref.watch(libraryItemProvider(currentBook.libraryItemId));
final itemBeingPlayed =
ref.watch(libraryItemProvider(currentBook.libraryItemId));
final player = ref.watch(audiobookPlayerProvider);
final imageOfItemBeingPlayed = itemBeingPlayed.valueOrNull != null
? ref.watch(
@ -64,7 +65,8 @@ class AudiobookPlayer extends HookConsumerWidget {
themeOfLibraryItemProvider(
itemBeingPlayed.valueOrNull?.id,
brightness: Theme.of(context).brightness,
highContrast: appSettings.themeSettings.highContrast || MediaQuery.of(context).highContrast,
highContrast: appSettings.themeSettings.highContrast ||
MediaQuery.of(context).highContrast,
),
);
@ -86,7 +88,8 @@ class AudiobookPlayer extends HookConsumerWidget {
onDragDown: (percentage) async {
// preferred volume
// set volume to 0 when dragging down
await player.setVolume(preferredVolume * (1 - percentage.clamp(0, .75)));
await player
.setVolume(preferredVolume * (1 - percentage.clamp(0, .75)));
},
minHeight: playerMinHeight,
// subtract the height of notches and other system UI
@ -106,8 +109,10 @@ class AudiobookPlayer extends HookConsumerWidget {
// at what point should the player switch from miniplayer to expanded player
// also at this point the image should be at its max size and in the center of the player
final miniplayerPercentageDeclaration =
(maxImgSize - playerMinHeight) / (playerMaxHeight - playerMinHeight);
final bool isFormMiniplayer = percentage < miniplayerPercentageDeclaration;
(maxImgSize - playerMinHeight) /
(playerMaxHeight - playerMinHeight);
final bool isFormMiniplayer =
percentage < miniplayerPercentageDeclaration;
if (!isFormMiniplayer) {
// this calculation needs a refactor
@ -207,14 +212,17 @@ class AudiobookChapterProgressBar extends HookConsumerWidget {
// now find the chapter that corresponds to the current time
// and calculate the progress of the current chapter
final currentChapterProgress =
currentChapter == null ? null : (player.positionInBook - currentChapter.start);
final currentChapterProgress = currentChapter == null
? null
: (player.positionInBook - currentChapter.start);
final currentChapterBuffered =
currentChapter == null ? null : (player.bufferedPositionInBook - currentChapter.start);
final currentChapterBuffered = currentChapter == null
? null
: (player.bufferedPositionInBook - currentChapter.start);
return ProgressBar(
progress: currentChapterProgress ?? position.data ?? const Duration(seconds: 0),
progress:
currentChapterProgress ?? position.data ?? const Duration(seconds: 0),
total: currentChapter == null
? player.book?.duration ?? const Duration(seconds: 0)
: currentChapter.end - currentChapter.start,
@ -226,7 +234,8 @@ class AudiobookChapterProgressBar extends HookConsumerWidget {
player.seek(duration);
},
thumbRadius: 8,
buffered: currentChapterBuffered ?? buffered.data ?? const Duration(seconds: 0),
buffered:
currentChapterBuffered ?? buffered.data ?? const Duration(seconds: 0),
bufferedBarColor: Theme.of(context).colorScheme.secondary,
timeLabelType: TimeLabelType.remainingTime,
timeLabelLocation: TimeLabelLocation.below,

View file

@ -105,7 +105,10 @@ class PlayerWhenExpanded extends HookConsumerWidget {
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.primary.withValues(alpha: 0.1),
color: Theme.of(context)
.colorScheme
.primary
.withValues(alpha: 0.1),
blurRadius: 32 * earlyPercentage,
spreadRadius: 8 * earlyPercentage,
// offset: Offset(0, 16 * earlyPercentage),
@ -171,7 +174,10 @@ class PlayerWhenExpanded extends HookConsumerWidget {
currentBookMetadata?.authorName ?? '',
].join(' - '),
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7),
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.7),
),
maxLines: 1,
overflow: TextOverflow.ellipsis,

View file

@ -34,7 +34,8 @@ class PlayerWhenMinimized extends HookConsumerWidget {
final currentChapter = ref.watch(currentPlayingChapterProvider);
final vanishingPercentage = 1 - percentageMiniplayer;
final progress = useStream(player.slowPositionStreamInBook, initialData: Duration.zero);
final progress =
useStream(player.slowPositionStreamInBook, initialData: Duration.zero);
final bookMetaExpanded = ref.watch(currentBookMetadataProvider);
@ -56,7 +57,8 @@ class PlayerWhenMinimized extends HookConsumerWidget {
context.pushNamed(
Routes.libraryItem.name,
pathParameters: {
Routes.libraryItem.pathParamName!: player.book!.libraryItemId,
Routes.libraryItem.pathParamName!:
player.book!.libraryItemId,
},
);
},
@ -90,7 +92,10 @@ class PlayerWhenMinimized extends HookConsumerWidget {
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7),
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.7),
),
),
],
@ -134,7 +139,8 @@ class PlayerWhenMinimized extends HookConsumerWidget {
SizedBox(
height: barHeight,
child: LinearProgressIndicator(
value: (progress.data ?? Duration.zero).inSeconds / player.book!.duration.inSeconds,
value: (progress.data ?? Duration.zero).inSeconds /
player.book!.duration.inSeconds,
color: Theme.of(context).colorScheme.onPrimaryContainer,
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
),

View file

@ -1,14 +1,17 @@
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart' show audiobookPlayerProvider;
import 'package:vaani/features/player/providers/audiobook_player.dart'
show audiobookPlayerProvider;
import 'package:vaani/features/player/providers/currently_playing_provider.dart'
show currentPlayingChapterProvider, currentlyPlayingBookProvider;
import 'package:vaani/features/player/view/player_when_expanded.dart' show pendingPlayerModals;
import 'package:vaani/features/player/view/player_when_expanded.dart'
show pendingPlayerModals;
import 'package:vaani/features/player/view/widgets/playing_indicator_icon.dart';
import 'package:vaani/main.dart' show appLogger;
import 'package:vaani/shared/extensions/chapter.dart' show ChapterDuration;
import 'package:vaani/shared/extensions/duration_format.dart' show DurationFormat;
import 'package:vaani/shared/extensions/duration_format.dart'
show DurationFormat;
import 'package:vaani/shared/hooks.dart' show useTimer;
class ChapterSelectionButton extends HookConsumerWidget {
@ -88,11 +91,13 @@ class ChapterSelectionModal extends HookConsumerWidget {
children: currentBook!.chapters.map(
(chapter) {
final isCurrent = currentChapterIndex == chapter.id;
final isPlayed =
currentChapterIndex != null && chapter.id < currentChapterIndex;
final isPlayed = currentChapterIndex != null &&
chapter.id < currentChapterIndex;
return ListTile(
autofocus: isCurrent,
iconColor: isPlayed && !isCurrent ? theme.disabledColor : null,
iconColor: isPlayed && !isCurrent
? theme.disabledColor
: null,
title: Text(
chapter.title,
style: isPlayed && !isCurrent

View file

@ -50,7 +50,8 @@ class PlayerSkipChapterStartEnd extends HookConsumerWidget {
body: Column(
children: [
ListTile(
title: Text('跳过片头 ${bookSettings.playerSettings.skipChapterStart.inSeconds}s'),
title: Text(
'跳过片头 ${bookSettings.playerSettings.skipChapterStart.inSeconds}s'),
),
Expanded(
child: TimeIntervalSlider(
@ -65,14 +66,16 @@ class PlayerSkipChapterStartEnd extends HookConsumerWidget {
bookSettingsProvider(bookId).notifier,
)
.update(
bookSettings.copyWith.playerSettings(skipChapterStart: interval),
bookSettings.copyWith
.playerSettings(skipChapterStart: interval),
);
ref.read(audiobookPlayerProvider).setClip(start: interval);
},
),
),
ListTile(
title: Text('跳过片尾 ${bookSettings.playerSettings.skipChapterEnd.inSeconds}s'),
title: Text(
'跳过片尾 ${bookSettings.playerSettings.skipChapterEnd.inSeconds}s'),
),
Expanded(
child: TimeIntervalSlider(
@ -87,7 +90,8 @@ class PlayerSkipChapterStartEnd extends HookConsumerWidget {
bookSettingsProvider(bookId).notifier,
)
.update(
bookSettings.copyWith.playerSettings(skipChapterEnd: interval),
bookSettings.copyWith
.playerSettings(skipChapterEnd: interval),
);
},
),

View file

@ -3,7 +3,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shelfsdk/audiobookshelf_api.dart' show Library;
import 'package:vaani/api/library_provider.dart';
import 'package:vaani/generated/l10n.dart';
import 'package:vaani/settings/api_settings_provider.dart' show apiSettingsProvider;
import 'package:vaani/settings/api_settings_provider.dart'
show apiSettingsProvider;
import 'package:vaani/shared/icons/abs_icons.dart';
import 'dart:io' show Platform;
@ -99,7 +100,8 @@ void showLibrarySwitcher(
// Make it scrollable and control height
isScrollControlled: true,
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.6, // Max 60% of screen
maxHeight:
MediaQuery.of(context).size.height * 0.6, // Max 60% of screen
),
builder: (sheetContext) => Padding(
// Add padding within the bottom sheet

View file

@ -68,7 +68,8 @@ class YouPage extends HookConsumerWidget {
},
),
librariesAsyncValue.when(
data: (libraries) => LibrarySwitchChip(libraries: libraries),
data: (libraries) =>
LibrarySwitchChip(libraries: libraries),
loading: () => const ActionChip(
avatar: SizedBox(
width: 18,
@ -88,7 +89,8 @@ class YouPage extends HookConsumerWidget {
// Maybe show error details or allow retry
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Failed to load libraries: $error'),
content:
Text('Failed to load libraries: $error'),
),
);
},
@ -141,7 +143,8 @@ class YouPage extends HookConsumerWidget {
icon: const Icon(Icons.info),
applicationName: AppMetadata.appName,
applicationVersion: AppMetadata.version,
applicationLegalese: 'Made with ❤️ by ${AppMetadata.author}',
applicationLegalese:
'Made with ❤️ by ${AppMetadata.author}',
aboutBoxChildren: [
// link to github repo
ListTile(
@ -216,7 +219,8 @@ class UserBar extends HookConsumerWidget {
Text(
api.baseUrl.toString(),
style: textTheme.bodyMedium?.copyWith(
color: themeData.colorScheme.onSurface.withValues(alpha: 0.6),
color:
themeData.colorScheme.onSurface.withValues(alpha: 0.6),
),
),
],

View file

@ -28,199 +28,207 @@ class MessageLookup extends MessageLookupByLibrary {
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"account": MessageLookupByLibrary.simpleMessage("Account"),
"accountSwitch": MessageLookupByLibrary.simpleMessage("Switch Account"),
"appSettings": MessageLookupByLibrary.simpleMessage("App Settings"),
"appearance": MessageLookupByLibrary.simpleMessage("Appearance"),
"autoTurnOnSleepTimer": MessageLookupByLibrary.simpleMessage(
"Auto Turn On Sleep Timer",
),
"automaticallyDescription": MessageLookupByLibrary.simpleMessage(
"Automatically turn on the sleep timer based on the time of day",
),
"backup": MessageLookupByLibrary.simpleMessage("Backup"),
"backupAndRestore": MessageLookupByLibrary.simpleMessage(
"Backup and Restore",
),
"bookAbout": MessageLookupByLibrary.simpleMessage("About the Book"),
"bookAboutDefault": MessageLookupByLibrary.simpleMessage(
"Sorry, no description found",
),
"bookAuthors": MessageLookupByLibrary.simpleMessage("Authors"),
"bookDownloads": MessageLookupByLibrary.simpleMessage("Downloads"),
"bookGenres": MessageLookupByLibrary.simpleMessage("Genres"),
"bookMetadataAbridged": MessageLookupByLibrary.simpleMessage("Abridged"),
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("Length"),
"bookMetadataPublished": MessageLookupByLibrary.simpleMessage("Published"),
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage(
"Unabridged",
),
"bookSeries": MessageLookupByLibrary.simpleMessage("Series"),
"bookShelveEmpty": MessageLookupByLibrary.simpleMessage("Try again"),
"bookShelveEmptyText": MessageLookupByLibrary.simpleMessage(
"No shelves to display",
),
"cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
"copyToClipboard": MessageLookupByLibrary.simpleMessage(
"Copy to Clipboard",
),
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
"Copy the app settings to the clipboard",
),
"copyToClipboardToast": MessageLookupByLibrary.simpleMessage(
"Settings copied to clipboard",
),
"delete": MessageLookupByLibrary.simpleMessage("Delete"),
"deleteDialog": m0,
"deleted": m1,
"explore": MessageLookupByLibrary.simpleMessage("explore"),
"exploreHint": MessageLookupByLibrary.simpleMessage(
"Seek and you shall discover...",
),
"exploreTooltip": MessageLookupByLibrary.simpleMessage(
"Search and Explore",
),
"general": MessageLookupByLibrary.simpleMessage("General"),
"help": MessageLookupByLibrary.simpleMessage("Help"),
"home": MessageLookupByLibrary.simpleMessage("Home"),
"homeBookContinueListening": MessageLookupByLibrary.simpleMessage(
"Continue Listening",
),
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage(
"Continue Series",
),
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("Discover"),
"homeBookListenAgain": MessageLookupByLibrary.simpleMessage("Listen Again"),
"homeBookNewestAuthors": MessageLookupByLibrary.simpleMessage(
"Newest Authors",
),
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage(
"Recently Added",
),
"homeBookRecommended": MessageLookupByLibrary.simpleMessage("Recommended"),
"homeContinueListening": MessageLookupByLibrary.simpleMessage(
"Continue Listening",
),
"homeListenAgain": MessageLookupByLibrary.simpleMessage("Listen Again"),
"homePageSettings": MessageLookupByLibrary.simpleMessage(
"Home Page Settings",
),
"homePageSettingsDescription": MessageLookupByLibrary.simpleMessage(
"Customize the home page",
),
"homeStartListening": MessageLookupByLibrary.simpleMessage(
"Start Listening",
),
"language": MessageLookupByLibrary.simpleMessage("Language"),
"languageDescription": MessageLookupByLibrary.simpleMessage(
"Language switch",
),
"library": MessageLookupByLibrary.simpleMessage("Library"),
"libraryChange": MessageLookupByLibrary.simpleMessage("Change Library"),
"libraryEmpty": MessageLookupByLibrary.simpleMessage(
"No libraries available.",
),
"libraryLoadError": m2,
"librarySelect": MessageLookupByLibrary.simpleMessage("Select Library"),
"librarySwitchTooltip": MessageLookupByLibrary.simpleMessage(
"Switch Library",
),
"libraryTooltip": MessageLookupByLibrary.simpleMessage(
"Browse your library",
),
"loading": MessageLookupByLibrary.simpleMessage("Loading..."),
"logs": MessageLookupByLibrary.simpleMessage("Logs"),
"no": MessageLookupByLibrary.simpleMessage("No"),
"notImplemented": MessageLookupByLibrary.simpleMessage("Not implemented"),
"notificationMediaPlayer": MessageLookupByLibrary.simpleMessage(
"Notification Media Player",
),
"notificationMediaPlayerDescription": MessageLookupByLibrary.simpleMessage(
"Customize the media player in notifications",
),
"ok": MessageLookupByLibrary.simpleMessage("OK"),
"pause": MessageLookupByLibrary.simpleMessage("Pause"),
"play": MessageLookupByLibrary.simpleMessage("Play"),
"playerSettings": MessageLookupByLibrary.simpleMessage("Player Settings"),
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
"Customize the player settings",
),
"playerSettingsPlaybackReporting": MessageLookupByLibrary.simpleMessage(
"Playback Reporting",
),
"playerSettingsPlaybackReportingIgnore":
MessageLookupByLibrary.simpleMessage(
"account": MessageLookupByLibrary.simpleMessage("Account"),
"accountSwitch": MessageLookupByLibrary.simpleMessage("Switch Account"),
"appSettings": MessageLookupByLibrary.simpleMessage("App Settings"),
"appearance": MessageLookupByLibrary.simpleMessage("Appearance"),
"autoTurnOnSleepTimer": MessageLookupByLibrary.simpleMessage(
"Auto Turn On Sleep Timer",
),
"automaticallyDescription": MessageLookupByLibrary.simpleMessage(
"Automatically turn on the sleep timer based on the time of day",
),
"backup": MessageLookupByLibrary.simpleMessage("Backup"),
"backupAndRestore": MessageLookupByLibrary.simpleMessage(
"Backup and Restore",
),
"bookAbout": MessageLookupByLibrary.simpleMessage("About the Book"),
"bookAboutDefault": MessageLookupByLibrary.simpleMessage(
"Sorry, no description found",
),
"bookAuthors": MessageLookupByLibrary.simpleMessage("Authors"),
"bookDownloads": MessageLookupByLibrary.simpleMessage("Downloads"),
"bookGenres": MessageLookupByLibrary.simpleMessage("Genres"),
"bookMetadataAbridged":
MessageLookupByLibrary.simpleMessage("Abridged"),
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("Length"),
"bookMetadataPublished":
MessageLookupByLibrary.simpleMessage("Published"),
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage(
"Unabridged",
),
"bookSeries": MessageLookupByLibrary.simpleMessage("Series"),
"bookShelveEmpty": MessageLookupByLibrary.simpleMessage("Try again"),
"bookShelveEmptyText": MessageLookupByLibrary.simpleMessage(
"No shelves to display",
),
"cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
"copyToClipboard": MessageLookupByLibrary.simpleMessage(
"Copy to Clipboard",
),
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
"Copy the app settings to the clipboard",
),
"copyToClipboardToast": MessageLookupByLibrary.simpleMessage(
"Settings copied to clipboard",
),
"delete": MessageLookupByLibrary.simpleMessage("Delete"),
"deleteDialog": m0,
"deleted": m1,
"explore": MessageLookupByLibrary.simpleMessage("explore"),
"exploreHint": MessageLookupByLibrary.simpleMessage(
"Seek and you shall discover...",
),
"exploreTooltip": MessageLookupByLibrary.simpleMessage(
"Search and Explore",
),
"general": MessageLookupByLibrary.simpleMessage("General"),
"help": MessageLookupByLibrary.simpleMessage("Help"),
"home": MessageLookupByLibrary.simpleMessage("Home"),
"homeBookContinueListening": MessageLookupByLibrary.simpleMessage(
"Continue Listening",
),
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage(
"Continue Series",
),
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("Discover"),
"homeBookListenAgain":
MessageLookupByLibrary.simpleMessage("Listen Again"),
"homeBookNewestAuthors": MessageLookupByLibrary.simpleMessage(
"Newest Authors",
),
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage(
"Recently Added",
),
"homeBookRecommended":
MessageLookupByLibrary.simpleMessage("Recommended"),
"homeContinueListening": MessageLookupByLibrary.simpleMessage(
"Continue Listening",
),
"homeListenAgain": MessageLookupByLibrary.simpleMessage("Listen Again"),
"homePageSettings": MessageLookupByLibrary.simpleMessage(
"Home Page Settings",
),
"homePageSettingsDescription": MessageLookupByLibrary.simpleMessage(
"Customize the home page",
),
"homeStartListening": MessageLookupByLibrary.simpleMessage(
"Start Listening",
),
"language": MessageLookupByLibrary.simpleMessage("Language"),
"languageDescription": MessageLookupByLibrary.simpleMessage(
"Language switch",
),
"library": MessageLookupByLibrary.simpleMessage("Library"),
"libraryChange": MessageLookupByLibrary.simpleMessage("Change Library"),
"libraryEmpty": MessageLookupByLibrary.simpleMessage(
"No libraries available.",
),
"libraryLoadError": m2,
"librarySelect": MessageLookupByLibrary.simpleMessage("Select Library"),
"librarySwitchTooltip": MessageLookupByLibrary.simpleMessage(
"Switch Library",
),
"libraryTooltip": MessageLookupByLibrary.simpleMessage(
"Browse your library",
),
"loading": MessageLookupByLibrary.simpleMessage("Loading..."),
"logs": MessageLookupByLibrary.simpleMessage("Logs"),
"no": MessageLookupByLibrary.simpleMessage("No"),
"notImplemented":
MessageLookupByLibrary.simpleMessage("Not implemented"),
"notificationMediaPlayer": MessageLookupByLibrary.simpleMessage(
"Notification Media Player",
),
"notificationMediaPlayerDescription":
MessageLookupByLibrary.simpleMessage(
"Customize the media player in notifications",
),
"ok": MessageLookupByLibrary.simpleMessage("OK"),
"pause": MessageLookupByLibrary.simpleMessage("Pause"),
"play": MessageLookupByLibrary.simpleMessage("Play"),
"playerSettings":
MessageLookupByLibrary.simpleMessage("Player Settings"),
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
"Customize the player settings",
),
"playerSettingsPlaybackReporting": MessageLookupByLibrary.simpleMessage(
"Playback Reporting",
),
"playerSettingsPlaybackReportingIgnore":
MessageLookupByLibrary.simpleMessage(
"Ignore Playback Position Less Than",
),
"playerSettingsPlaybackReportingMinimum":
MessageLookupByLibrary.simpleMessage("Minimum Position to Report"),
"playerSettingsPlaybackReportingMinimumDescriptionHead":
MessageLookupByLibrary.simpleMessage(
"playerSettingsPlaybackReportingMinimum":
MessageLookupByLibrary.simpleMessage("Minimum Position to Report"),
"playerSettingsPlaybackReportingMinimumDescriptionHead":
MessageLookupByLibrary.simpleMessage(
"Do not report playback for the first ",
),
"playerSettingsPlaybackReportingMinimumDescriptionTail":
MessageLookupByLibrary.simpleMessage("of the book"),
"playerSettingsRememberForEveryBook": MessageLookupByLibrary.simpleMessage(
"Remember Player Settings for Every Book",
),
"playerSettingsRememberForEveryBookDescription":
MessageLookupByLibrary.simpleMessage(
"playerSettingsPlaybackReportingMinimumDescriptionTail":
MessageLookupByLibrary.simpleMessage("of the book"),
"playerSettingsRememberForEveryBook":
MessageLookupByLibrary.simpleMessage(
"Remember Player Settings for Every Book",
),
"playerSettingsRememberForEveryBookDescription":
MessageLookupByLibrary.simpleMessage(
"Settings like speed, loudness, etc. will be remembered for every book",
),
"playerSettingsSpeedDefault": MessageLookupByLibrary.simpleMessage(
"Default Speed",
),
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
"Speed Options",
),
"playlistsMine": MessageLookupByLibrary.simpleMessage("My Playlists"),
"readLess": MessageLookupByLibrary.simpleMessage("Read Less"),
"readMore": MessageLookupByLibrary.simpleMessage("Read More"),
"refresh": MessageLookupByLibrary.simpleMessage("Refresh"),
"reset": MessageLookupByLibrary.simpleMessage("Reset"),
"resetAppSettings": MessageLookupByLibrary.simpleMessage(
"Reset App Settings",
),
"resetAppSettingsDescription": MessageLookupByLibrary.simpleMessage(
"Reset the app settings to the default values",
),
"resetAppSettingsDialog": MessageLookupByLibrary.simpleMessage(
"Are you sure you want to reset the app settings?",
),
"restore": MessageLookupByLibrary.simpleMessage("Restore"),
"restoreBackup": MessageLookupByLibrary.simpleMessage("Restore Backup"),
"restoreBackupHint": MessageLookupByLibrary.simpleMessage(
"Paste the backup here",
),
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage(
"Invalid backup",
),
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage(
"Settings restored",
),
"restoreBackupValidator": MessageLookupByLibrary.simpleMessage(
"Please paste the backup here",
),
"restoreDescription": MessageLookupByLibrary.simpleMessage(
"Restore the app settings from the backup",
),
"resume": MessageLookupByLibrary.simpleMessage("Resume"),
"retry": MessageLookupByLibrary.simpleMessage("Retry"),
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
"shakeDetector": MessageLookupByLibrary.simpleMessage("Shake Detector"),
"shakeDetectorDescription": MessageLookupByLibrary.simpleMessage(
"Customize the shake detector settings",
),
"themeSettings": MessageLookupByLibrary.simpleMessage("Theme Settings"),
"themeSettingsDescription": MessageLookupByLibrary.simpleMessage(
"Customize the app theme",
),
"unknown": MessageLookupByLibrary.simpleMessage("Unknown"),
"webVersion": MessageLookupByLibrary.simpleMessage("Web Version"),
"yes": MessageLookupByLibrary.simpleMessage("Yes"),
"you": MessageLookupByLibrary.simpleMessage("You"),
"youTooltip": MessageLookupByLibrary.simpleMessage(
"Your Profile and Settings",
),
};
"playerSettingsSpeedDefault": MessageLookupByLibrary.simpleMessage(
"Default Speed",
),
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
"Speed Options",
),
"playlistsMine": MessageLookupByLibrary.simpleMessage("My Playlists"),
"readLess": MessageLookupByLibrary.simpleMessage("Read Less"),
"readMore": MessageLookupByLibrary.simpleMessage("Read More"),
"refresh": MessageLookupByLibrary.simpleMessage("Refresh"),
"reset": MessageLookupByLibrary.simpleMessage("Reset"),
"resetAppSettings": MessageLookupByLibrary.simpleMessage(
"Reset App Settings",
),
"resetAppSettingsDescription": MessageLookupByLibrary.simpleMessage(
"Reset the app settings to the default values",
),
"resetAppSettingsDialog": MessageLookupByLibrary.simpleMessage(
"Are you sure you want to reset the app settings?",
),
"restore": MessageLookupByLibrary.simpleMessage("Restore"),
"restoreBackup": MessageLookupByLibrary.simpleMessage("Restore Backup"),
"restoreBackupHint": MessageLookupByLibrary.simpleMessage(
"Paste the backup here",
),
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage(
"Invalid backup",
),
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage(
"Settings restored",
),
"restoreBackupValidator": MessageLookupByLibrary.simpleMessage(
"Please paste the backup here",
),
"restoreDescription": MessageLookupByLibrary.simpleMessage(
"Restore the app settings from the backup",
),
"resume": MessageLookupByLibrary.simpleMessage("Resume"),
"retry": MessageLookupByLibrary.simpleMessage("Retry"),
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
"shakeDetector": MessageLookupByLibrary.simpleMessage("Shake Detector"),
"shakeDetectorDescription": MessageLookupByLibrary.simpleMessage(
"Customize the shake detector settings",
),
"themeSettings": MessageLookupByLibrary.simpleMessage("Theme Settings"),
"themeSettingsDescription": MessageLookupByLibrary.simpleMessage(
"Customize the app theme",
),
"unknown": MessageLookupByLibrary.simpleMessage("Unknown"),
"webVersion": MessageLookupByLibrary.simpleMessage("Web Version"),
"yes": MessageLookupByLibrary.simpleMessage("Yes"),
"you": MessageLookupByLibrary.simpleMessage("You"),
"youTooltip": MessageLookupByLibrary.simpleMessage(
"Your Profile and Settings",
),
};
}

View file

@ -28,135 +28,144 @@ class MessageLookup extends MessageLookupByLibrary {
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"account": MessageLookupByLibrary.simpleMessage("账户"),
"accountSwitch": MessageLookupByLibrary.simpleMessage("切换账户"),
"appSettings": MessageLookupByLibrary.simpleMessage("应用设置"),
"appearance": MessageLookupByLibrary.simpleMessage("外观"),
"autoTurnOnSleepTimer": MessageLookupByLibrary.simpleMessage("自动开启睡眠定时器"),
"automaticallyDescription": MessageLookupByLibrary.simpleMessage(
"根据一天中的时间自动打开睡眠定时器",
),
"backup": MessageLookupByLibrary.simpleMessage("备份"),
"backupAndRestore": MessageLookupByLibrary.simpleMessage("备份与恢复"),
"bookAbout": MessageLookupByLibrary.simpleMessage("关于本书"),
"bookAboutDefault": MessageLookupByLibrary.simpleMessage("抱歉,找不到描述"),
"bookAuthors": MessageLookupByLibrary.simpleMessage("作者"),
"bookDownloads": MessageLookupByLibrary.simpleMessage("下载"),
"bookGenres": MessageLookupByLibrary.simpleMessage("风格"),
"bookMetadataAbridged": MessageLookupByLibrary.simpleMessage("删节版"),
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("持续时间"),
"bookMetadataPublished": MessageLookupByLibrary.simpleMessage("发布年份"),
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage("未删节版"),
"bookSeries": MessageLookupByLibrary.simpleMessage("系列"),
"bookShelveEmpty": MessageLookupByLibrary.simpleMessage("重试"),
"bookShelveEmptyText": MessageLookupByLibrary.simpleMessage("未查询到书架"),
"cancel": MessageLookupByLibrary.simpleMessage("取消"),
"copyToClipboard": MessageLookupByLibrary.simpleMessage("复制到剪贴板"),
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
"将应用程序设置复制到剪贴板",
),
"copyToClipboardToast": MessageLookupByLibrary.simpleMessage("设置已复制到剪贴板"),
"delete": MessageLookupByLibrary.simpleMessage("删除"),
"deleteDialog": m0,
"deleted": m1,
"explore": MessageLookupByLibrary.simpleMessage("探索"),
"exploreHint": MessageLookupByLibrary.simpleMessage("搜索与探索..."),
"exploreTooltip": MessageLookupByLibrary.simpleMessage("搜索和探索"),
"general": MessageLookupByLibrary.simpleMessage("通用"),
"help": MessageLookupByLibrary.simpleMessage("Help"),
"home": MessageLookupByLibrary.simpleMessage("首页"),
"homeBookContinueListening": MessageLookupByLibrary.simpleMessage("继续收听"),
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage("继续系列"),
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("发现"),
"homeBookListenAgain": MessageLookupByLibrary.simpleMessage("再听一遍"),
"homeBookNewestAuthors": MessageLookupByLibrary.simpleMessage("最新作者"),
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage("最近添加"),
"homeBookRecommended": MessageLookupByLibrary.simpleMessage("推荐"),
"homeContinueListening": MessageLookupByLibrary.simpleMessage("继续收听"),
"homeListenAgain": MessageLookupByLibrary.simpleMessage("再听一遍"),
"homePageSettings": MessageLookupByLibrary.simpleMessage("主页设置"),
"homePageSettingsDescription": MessageLookupByLibrary.simpleMessage(
"自定义主页",
),
"homeStartListening": MessageLookupByLibrary.simpleMessage("开始收听"),
"language": MessageLookupByLibrary.simpleMessage("语言"),
"languageDescription": MessageLookupByLibrary.simpleMessage("语言切换"),
"library": MessageLookupByLibrary.simpleMessage("媒体库"),
"libraryChange": MessageLookupByLibrary.simpleMessage("更改媒体库"),
"libraryEmpty": MessageLookupByLibrary.simpleMessage("没有可用的库。"),
"libraryLoadError": m2,
"librarySelect": MessageLookupByLibrary.simpleMessage("选择媒体库"),
"librarySwitchTooltip": MessageLookupByLibrary.simpleMessage("切换媒体库"),
"libraryTooltip": MessageLookupByLibrary.simpleMessage("浏览您的媒体库"),
"loading": MessageLookupByLibrary.simpleMessage("加载中..."),
"logs": MessageLookupByLibrary.simpleMessage("日志"),
"no": MessageLookupByLibrary.simpleMessage(""),
"notImplemented": MessageLookupByLibrary.simpleMessage("未实现"),
"notificationMediaPlayer": MessageLookupByLibrary.simpleMessage("通知媒体播放器"),
"notificationMediaPlayerDescription": MessageLookupByLibrary.simpleMessage(
"在通知中自定义媒体播放器",
),
"ok": MessageLookupByLibrary.simpleMessage("确定"),
"pause": MessageLookupByLibrary.simpleMessage("暂停"),
"play": MessageLookupByLibrary.simpleMessage("播放"),
"playerSettings": MessageLookupByLibrary.simpleMessage("播放器设置"),
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
"自定义播放器设置",
),
"playerSettingsPlaybackReporting": MessageLookupByLibrary.simpleMessage(
"回放报告",
),
"playerSettingsPlaybackReportingIgnore":
MessageLookupByLibrary.simpleMessage("忽略播放位置小于"),
"playerSettingsPlaybackReportingMinimum":
MessageLookupByLibrary.simpleMessage("回放报告最小位置"),
"playerSettingsPlaybackReportingMinimumDescriptionHead":
MessageLookupByLibrary.simpleMessage("不要报告本书前 "),
"playerSettingsPlaybackReportingMinimumDescriptionTail":
MessageLookupByLibrary.simpleMessage(" 的播放"),
"playerSettingsRememberForEveryBook": MessageLookupByLibrary.simpleMessage(
"记住每本书的播放器设置",
),
"playerSettingsRememberForEveryBookDescription":
MessageLookupByLibrary.simpleMessage("每本书都会记住播放速度、音量等设置"),
"playerSettingsSpeedDefault": MessageLookupByLibrary.simpleMessage(
"默认播放速度",
),
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
"播放速度选项",
),
"playlistsMine": MessageLookupByLibrary.simpleMessage("播放列表"),
"readLess": MessageLookupByLibrary.simpleMessage("折叠"),
"readMore": MessageLookupByLibrary.simpleMessage("展开"),
"refresh": MessageLookupByLibrary.simpleMessage("刷新"),
"reset": MessageLookupByLibrary.simpleMessage("重置"),
"resetAppSettings": MessageLookupByLibrary.simpleMessage("重置应用程序设置"),
"resetAppSettingsDescription": MessageLookupByLibrary.simpleMessage(
"将应用程序设置重置为默认值",
),
"resetAppSettingsDialog": MessageLookupByLibrary.simpleMessage(
"您确定要重置应用程序设置吗?",
),
"restore": MessageLookupByLibrary.simpleMessage("恢复"),
"restoreBackup": MessageLookupByLibrary.simpleMessage("恢复备份"),
"restoreBackupHint": MessageLookupByLibrary.simpleMessage("将备份粘贴到此处"),
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage("无效备份"),
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage("设置已恢复"),
"restoreBackupValidator": MessageLookupByLibrary.simpleMessage("请将备份粘贴到此处"),
"restoreDescription": MessageLookupByLibrary.simpleMessage("从备份中还原应用程序设置"),
"resume": MessageLookupByLibrary.simpleMessage("继续"),
"retry": MessageLookupByLibrary.simpleMessage("重试"),
"settings": MessageLookupByLibrary.simpleMessage("设置"),
"shakeDetector": MessageLookupByLibrary.simpleMessage("抖动检测器"),
"shakeDetectorDescription": MessageLookupByLibrary.simpleMessage(
"自定义抖动检测器设置",
),
"themeSettings": MessageLookupByLibrary.simpleMessage("主题设置"),
"themeSettingsDescription": MessageLookupByLibrary.simpleMessage("自定义应用主题"),
"unknown": MessageLookupByLibrary.simpleMessage("未知"),
"webVersion": MessageLookupByLibrary.simpleMessage("Web版本"),
"yes": MessageLookupByLibrary.simpleMessage(""),
"you": MessageLookupByLibrary.simpleMessage("我的"),
"youTooltip": MessageLookupByLibrary.simpleMessage("您的个人资料和设置"),
};
"account": MessageLookupByLibrary.simpleMessage("账户"),
"accountSwitch": MessageLookupByLibrary.simpleMessage("切换账户"),
"appSettings": MessageLookupByLibrary.simpleMessage("应用设置"),
"appearance": MessageLookupByLibrary.simpleMessage("外观"),
"autoTurnOnSleepTimer":
MessageLookupByLibrary.simpleMessage("自动开启睡眠定时器"),
"automaticallyDescription": MessageLookupByLibrary.simpleMessage(
"根据一天中的时间自动打开睡眠定时器",
),
"backup": MessageLookupByLibrary.simpleMessage("备份"),
"backupAndRestore": MessageLookupByLibrary.simpleMessage("备份与恢复"),
"bookAbout": MessageLookupByLibrary.simpleMessage("关于本书"),
"bookAboutDefault": MessageLookupByLibrary.simpleMessage("抱歉,找不到描述"),
"bookAuthors": MessageLookupByLibrary.simpleMessage("作者"),
"bookDownloads": MessageLookupByLibrary.simpleMessage("下载"),
"bookGenres": MessageLookupByLibrary.simpleMessage("风格"),
"bookMetadataAbridged": MessageLookupByLibrary.simpleMessage("删节版"),
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("持续时间"),
"bookMetadataPublished": MessageLookupByLibrary.simpleMessage("发布年份"),
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage("未删节版"),
"bookSeries": MessageLookupByLibrary.simpleMessage("系列"),
"bookShelveEmpty": MessageLookupByLibrary.simpleMessage("重试"),
"bookShelveEmptyText": MessageLookupByLibrary.simpleMessage("未查询到书架"),
"cancel": MessageLookupByLibrary.simpleMessage("取消"),
"copyToClipboard": MessageLookupByLibrary.simpleMessage("复制到剪贴板"),
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
"将应用程序设置复制到剪贴板",
),
"copyToClipboardToast":
MessageLookupByLibrary.simpleMessage("设置已复制到剪贴板"),
"delete": MessageLookupByLibrary.simpleMessage("删除"),
"deleteDialog": m0,
"deleted": m1,
"explore": MessageLookupByLibrary.simpleMessage("探索"),
"exploreHint": MessageLookupByLibrary.simpleMessage("搜索与探索..."),
"exploreTooltip": MessageLookupByLibrary.simpleMessage("搜索和探索"),
"general": MessageLookupByLibrary.simpleMessage("通用"),
"help": MessageLookupByLibrary.simpleMessage("Help"),
"home": MessageLookupByLibrary.simpleMessage("首页"),
"homeBookContinueListening":
MessageLookupByLibrary.simpleMessage("继续收听"),
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage("继续系列"),
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("发现"),
"homeBookListenAgain": MessageLookupByLibrary.simpleMessage("再听一遍"),
"homeBookNewestAuthors": MessageLookupByLibrary.simpleMessage("最新作者"),
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage("最近添加"),
"homeBookRecommended": MessageLookupByLibrary.simpleMessage("推荐"),
"homeContinueListening": MessageLookupByLibrary.simpleMessage("继续收听"),
"homeListenAgain": MessageLookupByLibrary.simpleMessage("再听一遍"),
"homePageSettings": MessageLookupByLibrary.simpleMessage("主页设置"),
"homePageSettingsDescription": MessageLookupByLibrary.simpleMessage(
"自定义主页",
),
"homeStartListening": MessageLookupByLibrary.simpleMessage("开始收听"),
"language": MessageLookupByLibrary.simpleMessage("语言"),
"languageDescription": MessageLookupByLibrary.simpleMessage("语言切换"),
"library": MessageLookupByLibrary.simpleMessage("媒体库"),
"libraryChange": MessageLookupByLibrary.simpleMessage("更改媒体库"),
"libraryEmpty": MessageLookupByLibrary.simpleMessage("没有可用的库。"),
"libraryLoadError": m2,
"librarySelect": MessageLookupByLibrary.simpleMessage("选择媒体库"),
"librarySwitchTooltip": MessageLookupByLibrary.simpleMessage("切换媒体库"),
"libraryTooltip": MessageLookupByLibrary.simpleMessage("浏览您的媒体库"),
"loading": MessageLookupByLibrary.simpleMessage("加载中..."),
"logs": MessageLookupByLibrary.simpleMessage("日志"),
"no": MessageLookupByLibrary.simpleMessage(""),
"notImplemented": MessageLookupByLibrary.simpleMessage("未实现"),
"notificationMediaPlayer":
MessageLookupByLibrary.simpleMessage("通知媒体播放器"),
"notificationMediaPlayerDescription":
MessageLookupByLibrary.simpleMessage(
"在通知中自定义媒体播放器",
),
"ok": MessageLookupByLibrary.simpleMessage("确定"),
"pause": MessageLookupByLibrary.simpleMessage("暂停"),
"play": MessageLookupByLibrary.simpleMessage("播放"),
"playerSettings": MessageLookupByLibrary.simpleMessage("播放器设置"),
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
"自定义播放器设置",
),
"playerSettingsPlaybackReporting": MessageLookupByLibrary.simpleMessage(
"回放报告",
),
"playerSettingsPlaybackReportingIgnore":
MessageLookupByLibrary.simpleMessage("忽略播放位置小于"),
"playerSettingsPlaybackReportingMinimum":
MessageLookupByLibrary.simpleMessage("回放报告最小位置"),
"playerSettingsPlaybackReportingMinimumDescriptionHead":
MessageLookupByLibrary.simpleMessage("不要报告本书前 "),
"playerSettingsPlaybackReportingMinimumDescriptionTail":
MessageLookupByLibrary.simpleMessage(" 的播放"),
"playerSettingsRememberForEveryBook":
MessageLookupByLibrary.simpleMessage(
"记住每本书的播放器设置",
),
"playerSettingsRememberForEveryBookDescription":
MessageLookupByLibrary.simpleMessage("每本书都会记住播放速度、音量等设置"),
"playerSettingsSpeedDefault": MessageLookupByLibrary.simpleMessage(
"默认播放速度",
),
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
"播放速度选项",
),
"playlistsMine": MessageLookupByLibrary.simpleMessage("播放列表"),
"readLess": MessageLookupByLibrary.simpleMessage("折叠"),
"readMore": MessageLookupByLibrary.simpleMessage("展开"),
"refresh": MessageLookupByLibrary.simpleMessage("刷新"),
"reset": MessageLookupByLibrary.simpleMessage("重置"),
"resetAppSettings": MessageLookupByLibrary.simpleMessage("重置应用程序设置"),
"resetAppSettingsDescription": MessageLookupByLibrary.simpleMessage(
"将应用程序设置重置为默认值",
),
"resetAppSettingsDialog": MessageLookupByLibrary.simpleMessage(
"您确定要重置应用程序设置吗?",
),
"restore": MessageLookupByLibrary.simpleMessage("恢复"),
"restoreBackup": MessageLookupByLibrary.simpleMessage("恢复备份"),
"restoreBackupHint": MessageLookupByLibrary.simpleMessage("将备份粘贴到此处"),
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage("无效备份"),
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage("设置已恢复"),
"restoreBackupValidator":
MessageLookupByLibrary.simpleMessage("请将备份粘贴到此处"),
"restoreDescription":
MessageLookupByLibrary.simpleMessage("从备份中还原应用程序设置"),
"resume": MessageLookupByLibrary.simpleMessage("继续"),
"retry": MessageLookupByLibrary.simpleMessage("重试"),
"settings": MessageLookupByLibrary.simpleMessage("设置"),
"shakeDetector": MessageLookupByLibrary.simpleMessage("抖动检测器"),
"shakeDetectorDescription": MessageLookupByLibrary.simpleMessage(
"自定义抖动检测器设置",
),
"themeSettings": MessageLookupByLibrary.simpleMessage("主题设置"),
"themeSettingsDescription":
MessageLookupByLibrary.simpleMessage("自定义应用主题"),
"unknown": MessageLookupByLibrary.simpleMessage("未知"),
"webVersion": MessageLookupByLibrary.simpleMessage("Web版本"),
"yes": MessageLookupByLibrary.simpleMessage(""),
"you": MessageLookupByLibrary.simpleMessage("我的"),
"youTooltip": MessageLookupByLibrary.simpleMessage("您的个人资料和设置"),
};
}

View file

@ -66,7 +66,8 @@ class MyApp extends ConsumerWidget {
ColorScheme lightColorScheme = brandLightColorScheme;
ColorScheme darkColorScheme = brandDarkColorScheme;
final shouldUseHighContrast = themeSettings.highContrast || MediaQuery.of(context).highContrast;
final shouldUseHighContrast =
themeSettings.highContrast || MediaQuery.of(context).highContrast;
if (shouldUseHighContrast) {
lightColorScheme = lightColorScheme.copyWith(
@ -78,7 +79,8 @@ class MyApp extends ConsumerWidget {
}
if (themeSettings.useMaterialThemeFromSystem) {
var themes = ref.watch(systemThemeProvider(highContrast: shouldUseHighContrast));
var themes =
ref.watch(systemThemeProvider(highContrast: shouldUseHighContrast));
if (themes.valueOrNull != null) {
lightColorScheme = themes.valueOrNull!.$1;
darkColorScheme = themes.valueOrNull!.$2;

View file

@ -7,7 +7,8 @@ import 'package:vaani/generated/l10n.dart';
import 'package:vaani/main.dart';
import 'package:vaani/router/router.dart';
import 'package:vaani/settings/api_settings_provider.dart';
import 'package:vaani/settings/app_settings_provider.dart' show appSettingsProvider;
import 'package:vaani/settings/app_settings_provider.dart'
show appSettingsProvider;
import 'package:vaani/settings/constants.dart';
import '../shared/widgets/shelves/home_shelf.dart';
@ -72,9 +73,12 @@ class HomePage extends HookConsumerWidget {
// check if showPlayButton is enabled for the shelf
// using the id of the shelf
final showPlayButton = switch (shelf.id) {
'continue-listening' => homePageSettings.showPlayButtonOnContinueListeningShelf,
'continue-series' => homePageSettings.showPlayButtonOnContinueSeriesShelf,
'listen-again' => homePageSettings.showPlayButtonOnListenAgainShelf,
'continue-listening' =>
homePageSettings.showPlayButtonOnContinueListeningShelf,
'continue-series' =>
homePageSettings.showPlayButtonOnContinueSeriesShelf,
'listen-again' =>
homePageSettings.showPlayButtonOnListenAgainShelf,
_ => homePageSettings.showPlayButtonOnAllRemainingShelves,
};
final showLabel = switch (shelf.label) {
@ -111,7 +115,8 @@ class HomePage extends HookConsumerWidget {
},
loading: () => const HomePageSkeleton(),
error: (error, stack) {
if (apiSettings.activeUser == null || apiSettings.activeServer == null) {
if (apiSettings.activeUser == null ||
apiSettings.activeServer == null) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,

View file

@ -25,7 +25,8 @@ import 'transitions/slide.dart';
part 'constants.dart';
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'root');
final GlobalKey<NavigatorState> rootNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'root');
final GlobalKey<NavigatorState> sectionHomeNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'HomeNavigator');
@ -93,8 +94,10 @@ class MyAppRouter {
// itemId: itemId, extra: state.extra);
// },
pageBuilder: (context, state) {
final itemId = state.pathParameters[Routes.libraryItem.pathParamName]!;
final child = LibraryItemPage(itemId: itemId, extra: state.extra);
final itemId = state
.pathParameters[Routes.libraryItem.pathParamName]!;
final child =
LibraryItemPage(itemId: itemId, extra: state.extra);
return buildPageWithDefaultTransition(
context: context,
state: state,
@ -201,7 +204,8 @@ class MyAppRouter {
GoRoute(
path: Routes.playerSettings.pathName,
name: Routes.playerSettings.name,
pageBuilder: defaultPageBuilder(const PlayerSettingsPage()),
pageBuilder:
defaultPageBuilder(const PlayerSettingsPage()),
),
GoRoute(
path: Routes.shakeDetectorSettings.pathName,
@ -249,7 +253,8 @@ class MyAppRouter {
final stateParam = state.uri.queryParameters['state'];
appLogger.fine('deep linking callback: code: $code, state: $stateParam');
var callbackPage = CallbackPage(code: code, state: stateParam, key: ValueKey(stateParam));
var callbackPage =
CallbackPage(code: code, state: stateParam, key: ValueKey(stateParam));
return buildPageWithDefaultTransition(
context: context,
state: state,

View file

@ -116,7 +116,8 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
// extended: false,
destinations: _navigationItems(context).map((item) {
final isDestinationLibrary = item.name == S.of(context).library;
var currentLibrary = ref.watch(currentLibraryProvider).valueOrNull;
var currentLibrary =
ref.watch(currentLibraryProvider).valueOrNull;
final libraryIcon = AbsIcons.getIconByName(
currentLibrary?.icon,
);
@ -125,9 +126,13 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
isDestinationLibrary ? libraryIcon ?? item.icon : item.icon,
),
selectedIcon: Icon(
isDestinationLibrary ? libraryIcon ?? item.activeIcon : item.activeIcon,
isDestinationLibrary
? libraryIcon ?? item.activeIcon
: item.activeIcon,
),
label: Text(isDestinationLibrary ? currentLibrary?.name ?? item.name : item.name),
label: Text(isDestinationLibrary
? currentLibrary?.name ?? item.name
: item.name),
// tooltip: item.tooltip,
);
// if (isDestinationLibrary) {
@ -166,8 +171,8 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
// useValueListenable(ref.watch(playerExpandProgressNotifierProvider));
final playerProgress = ref.watch(playerHeightProvider);
final playerMaxHeight = MediaQuery.of(context).size.height;
var percentExpandedMiniPlayer =
(playerProgress - playerMinHeight) / (playerMaxHeight - playerMinHeight);
var percentExpandedMiniPlayer = (playerProgress - playerMinHeight) /
(playerMaxHeight - playerMinHeight);
// Clamp the value between 0 and 1
percentExpandedMiniPlayer = percentExpandedMiniPlayer.clamp(0.0, 1.0);
return Opacity(
@ -193,9 +198,13 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
isDestinationLibrary ? libraryIcon ?? item.icon : item.icon,
),
selectedIcon: Icon(
isDestinationLibrary ? libraryIcon ?? item.activeIcon : item.activeIcon,
isDestinationLibrary
? libraryIcon ?? item.activeIcon
: item.activeIcon,
),
label: isDestinationLibrary ? currentLibrary?.name ?? item.name : item.name,
label: isDestinationLibrary
? currentLibrary?.name ?? item.name
: item.name,
tooltip: item.tooltip,
);
if (isDestinationLibrary) {

View file

@ -18,11 +18,13 @@ class AppSettings with _$AppSettings {
@Default(SleepTimerSettings()) SleepTimerSettings sleepTimerSettings,
@Default(DownloadSettings()) DownloadSettings downloadSettings,
@Default(NotificationSettings()) NotificationSettings notificationSettings,
@Default(ShakeDetectionSettings()) ShakeDetectionSettings shakeDetectionSettings,
@Default(ShakeDetectionSettings())
ShakeDetectionSettings shakeDetectionSettings,
@Default(HomePageSettings()) HomePageSettings homePageSettings,
}) = _AppSettings;
factory AppSettings.fromJson(Map<String, dynamic> json) => _$AppSettingsFromJson(json);
factory AppSettings.fromJson(Map<String, dynamic> json) =>
_$AppSettingsFromJson(json);
}
@freezed
@ -36,14 +38,17 @@ class ThemeSettings with _$ThemeSettings {
@Default(true) bool useCurrentPlayerThemeThroughoutApp,
}) = _ThemeSettings;
factory ThemeSettings.fromJson(Map<String, dynamic> json) => _$ThemeSettingsFromJson(json);
factory ThemeSettings.fromJson(Map<String, dynamic> json) =>
_$ThemeSettingsFromJson(json);
}
@freezed
class PlayerSettings with _$PlayerSettings {
const factory PlayerSettings({
@Default(MinimizedPlayerSettings()) MinimizedPlayerSettings miniPlayerSettings,
@Default(ExpandedPlayerSettings()) ExpandedPlayerSettings expandedPlayerSettings,
@Default(MinimizedPlayerSettings())
MinimizedPlayerSettings miniPlayerSettings,
@Default(ExpandedPlayerSettings())
ExpandedPlayerSettings expandedPlayerSettings,
@Default(1) double preferredDefaultVolume,
@Default(1) double preferredDefaultSpeed,
@Default([1, 1.25, 1.5, 1.75, 2]) List<double> speedOptions,
@ -56,7 +61,8 @@ class PlayerSettings with _$PlayerSettings {
@Default(true) bool configurePlayerForEveryBook,
}) = _PlayerSettings;
factory PlayerSettings.fromJson(Map<String, dynamic> json) => _$PlayerSettingsFromJson(json);
factory PlayerSettings.fromJson(Map<String, dynamic> json) =>
_$PlayerSettingsFromJson(json);
}
@freezed
@ -139,7 +145,8 @@ class DownloadSettings with _$DownloadSettings {
@Default(3) int maxConcurrentByGroup,
}) = _DownloadSettings;
factory DownloadSettings.fromJson(Map<String, dynamic> json) => _$DownloadSettingsFromJson(json);
factory DownloadSettings.fromJson(Map<String, dynamic> json) =>
_$DownloadSettingsFromJson(json);
}
@freezed
@ -196,7 +203,8 @@ class ShakeDetectionSettings with _$ShakeDetectionSettings {
@Default(ShakeDirection.horizontal) ShakeDirection direction,
@Default(5) double threshold,
@Default(ShakeAction.resetSleepTimer) ShakeAction shakeAction,
@Default({ShakeDetectedFeedback.vibrate}) Set<ShakeDetectedFeedback> feedback,
@Default({ShakeDetectedFeedback.vibrate})
Set<ShakeDetectedFeedback> feedback,
@Default(0.5) double beepVolume,
/// the duration to wait before the shake detection is enabled again
@ -234,5 +242,6 @@ class HomePageSettings with _$HomePageSettings {
@Default(false) bool showPlayButtonOnListenAgainShelf,
}) = _HomePageSettings;
factory HomePageSettings.fromJson(Map<String, dynamic> json) => _$HomePageSettingsFromJson(json);
factory HomePageSettings.fromJson(Map<String, dynamic> json) =>
_$HomePageSettingsFromJson(json);
}

View file

@ -128,7 +128,8 @@ class AppSettingsPage extends HookConsumerWidget {
SettingsTile(
title: Text(S.of(context).notificationMediaPlayer),
leading: const Icon(Icons.play_lesson),
description: Text(S.of(context).notificationMediaPlayerDescription),
description:
Text(S.of(context).notificationMediaPlayerDescription),
onPressed: (context) {
context.pushNamed(Routes.notificationSettings.name);
},

View file

@ -51,7 +51,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
title: Text(S.of(context).playerSettingsSpeedDefault),
trailing: Text(
'${playerSettings.preferredDefaultSpeed}x',
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
style:
TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
),
leading: const Icon(Icons.speed),
onPressed: (context) async {
@ -75,7 +76,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
title: Text(S.of(context).playerSettingsSpeedOptions),
description: Text(
playerSettings.speedOptions.map((e) => '${e}x').join(', '),
style: TextStyle(fontWeight: FontWeight.bold, color: primaryColor),
style:
TextStyle(fontWeight: FontWeight.bold, color: primaryColor),
),
leading: const Icon(Icons.speed),
onPressed: (context) async {
@ -105,17 +107,22 @@ class PlayerSettingsPage extends HookConsumerWidget {
title: Text(S.of(context).playerSettingsPlaybackReportingMinimum),
description: Text.rich(
TextSpan(
text: S.of(context).playerSettingsPlaybackReportingMinimumDescriptionHead,
text: S
.of(context)
.playerSettingsPlaybackReportingMinimumDescriptionHead,
children: [
TextSpan(
text: playerSettings.minimumPositionForReporting.smartBinaryFormat,
text: playerSettings
.minimumPositionForReporting.smartBinaryFormat,
style: TextStyle(
fontWeight: FontWeight.bold,
color: primaryColor,
),
),
TextSpan(
text: S.of(context).playerSettingsPlaybackReportingMinimumDescriptionTail),
text: S
.of(context)
.playerSettingsPlaybackReportingMinimumDescriptionTail),
],
),
),
@ -125,7 +132,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
context: context,
builder: (context) {
return TimeDurationSelector(
title: Text(S.of(context).playerSettingsPlaybackReportingIgnore),
title: Text(
S.of(context).playerSettingsPlaybackReportingIgnore),
baseUnit: BaseUnit.second,
initialValue: playerSettings.minimumPositionForReporting,
);
@ -148,7 +156,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
text: 'Mark complete when less than ',
children: [
TextSpan(
text: playerSettings.markCompleteWhenTimeLeft.smartBinaryFormat,
text: playerSettings
.markCompleteWhenTimeLeft.smartBinaryFormat,
style: TextStyle(
fontWeight: FontWeight.bold,
color: primaryColor,
@ -187,7 +196,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
text: 'Report progress every ',
children: [
TextSpan(
text: playerSettings.playbackReportInterval.smartBinaryFormat,
text: playerSettings
.playbackReportInterval.smartBinaryFormat,
style: TextStyle(
fontWeight: FontWeight.bold,
color: primaryColor,
@ -231,7 +241,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
description: const Text(
'Show the total progress of the book in the player',
),
initialValue: playerSettings.expandedPlayerSettings.showTotalProgress,
initialValue:
playerSettings.expandedPlayerSettings.showTotalProgress,
onToggle: (value) {
ref.read(appSettingsProvider.notifier).update(
appSettings.copyWith.playerSettings
@ -246,11 +257,13 @@ class PlayerSettingsPage extends HookConsumerWidget {
description: const Text(
'Show the progress of the current chapter in the player',
),
initialValue: playerSettings.expandedPlayerSettings.showChapterProgress,
initialValue:
playerSettings.expandedPlayerSettings.showChapterProgress,
onToggle: (value) {
ref.read(appSettingsProvider.notifier).update(
appSettings.copyWith.playerSettings(
expandedPlayerSettings: playerSettings.expandedPlayerSettings
expandedPlayerSettings: playerSettings
.expandedPlayerSettings
.copyWith(showChapterProgress: value),
),
);
@ -309,7 +322,8 @@ class SpeedPicker extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final speedController = useTextEditingController(text: initialValue.toString());
final speedController =
useTextEditingController(text: initialValue.toString());
final speed = useState<double?>(initialValue);
return AlertDialog(
title: const Text('Select Speed'),
@ -368,7 +382,8 @@ class SpeedOptionsPicker extends HookConsumerWidget {
onDeleted: speed == 1
? null
: () {
speedOptions.value = speedOptions.value.where((element) {
speedOptions.value =
speedOptions.value.where((element) {
// speed option 1 can't be removed
return element != speed;
}).toList();

View file

@ -99,7 +99,8 @@ class BookOnShelf extends HookConsumerWidget {
onTap: handleTapOnBook,
borderRadius: BorderRadius.circular(10),
child: Padding(
padding: const EdgeInsets.only(bottom: 8.0, right: 4.0, left: 4.0),
padding:
const EdgeInsets.only(bottom: 8.0, right: 4.0, left: 4.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -111,7 +112,9 @@ class BookOnShelf extends HookConsumerWidget {
alignment: Alignment.bottomRight,
children: [
Hero(
tag: HeroTagPrefixes.bookCover + item.id + heroTagSuffix,
tag: HeroTagPrefixes.bookCover +
item.id +
heroTagSuffix,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: AnimatedSwitcher(
@ -125,13 +128,17 @@ class BookOnShelf extends HookConsumerWidget {
var imageWidget = Image.memory(
image,
fit: BoxFit.fill,
cacheWidth:
(height * 1.2 * MediaQuery.of(context).devicePixelRatio)
.round(),
cacheWidth: (height *
1.2 *
MediaQuery.of(context)
.devicePixelRatio)
.round(),
);
return Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.onPrimaryContainer,
color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
),
child: imageWidget,
);
@ -206,7 +213,8 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final me = ref.watch(meProvider);
final player = ref.watch(audiobookPlayerProvider);
final isCurrentBookSetInPlayer = player.book?.libraryItemId == libraryItemId;
final isCurrentBookSetInPlayer =
player.book?.libraryItemId == libraryItemId;
final isPlayingThisBook = player.playing && isCurrentBookSetInPlayer;
final userProgress = me.valueOrNull?.mediaProgress
@ -234,7 +242,8 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
return Theme(
// if current book is set in player, get theme from the cover image
data: ThemeData(
colorScheme: coverColorScheme.valueOrNull ?? Theme.of(context).colorScheme,
colorScheme:
coverColorScheme.valueOrNull ?? Theme.of(context).colorScheme,
),
child: Padding(
padding: EdgeInsets.all(strokeWidth / 2 + 2),
@ -249,7 +258,10 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
child: CircularProgressIndicator(
value: userProgress.progress,
strokeWidth: strokeWidth,
backgroundColor: Theme.of(context).colorScheme.onPrimary.withValues(alpha: 0.8),
backgroundColor: Theme.of(context)
.colorScheme
.onPrimary
.withValues(alpha: 0.8),
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).colorScheme.primary,
),
@ -267,11 +279,15 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
const Size(size, size),
),
backgroundColor: WidgetStateProperty.all(
Theme.of(context).colorScheme.onPrimary.withValues(alpha: 0.9),
Theme.of(context)
.colorScheme
.onPrimary
.withValues(alpha: 0.9),
),
),
onPressed: () async {
final book = await ref.watch(libraryItemProvider(libraryItemId).future);
final book =
await ref.watch(libraryItemProvider(libraryItemId).future);
libraryItemPlayButtonOnPressed(
ref: ref,
@ -308,8 +324,10 @@ class BookCoverSkeleton extends StatelessWidget {
child: SizedBox(
width: 150,
child: Shimmer.fromColors(
baseColor: Theme.of(context).colorScheme.surface.withValues(alpha: 0.3),
highlightColor: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.1),
baseColor:
Theme.of(context).colorScheme.surface.withValues(alpha: 0.3),
highlightColor:
Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.1),
child: Container(
color: Theme.of(context).colorScheme.surface,
),