mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2026-02-16 06:19:35 +00:00
格式化代码
This commit is contained in:
parent
a28547685b
commit
b3a9d76c78
24 changed files with 611 additions and 451 deletions
|
|
@ -26,8 +26,8 @@ class ExplorePage extends HookConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
// hooks for the dark mode
|
// hooks for the dark mode
|
||||||
final settings = ref.watch(appSettingsProvider);
|
ref.watch(appSettingsProvider);
|
||||||
final api = ref.watch(authenticatedApiProvider);
|
// final api = ref.watch(authenticatedApiProvider);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(S.of(context).explore),
|
title: Text(S.of(context).explore),
|
||||||
|
|
@ -62,8 +62,8 @@ class MySearchBar extends HookConsumerWidget {
|
||||||
currentQuery = query;
|
currentQuery = query;
|
||||||
|
|
||||||
// In a real application, there should be some error handling here.
|
// In a real application, there should be some error handling here.
|
||||||
final options =
|
final options = await api.libraries
|
||||||
await api.libraries.search(libraryId: settings.activeLibraryId!, query: query, limit: 3);
|
.search(libraryId: settings.activeLibraryId!, query: query, limit: 3);
|
||||||
|
|
||||||
// If another search happened after this one, throw away these options.
|
// If another search happened after this one, throw away these options.
|
||||||
if (currentQuery != query) {
|
if (currentQuery != query) {
|
||||||
|
|
@ -98,7 +98,10 @@ class MySearchBar extends HookConsumerWidget {
|
||||||
// opacity: 0.5 for the hint text
|
// opacity: 0.5 for the hint text
|
||||||
hintStyle: WidgetStatePropertyAll(
|
hintStyle: WidgetStatePropertyAll(
|
||||||
Theme.of(context).textTheme.bodyMedium!.copyWith(
|
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,
|
textInputAction: TextInputAction.search,
|
||||||
|
|
@ -231,8 +234,9 @@ class BookSearchResultMini extends HookConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final item = ref.watch(libraryItemProvider(book.libraryItemId)).valueOrNull;
|
final item = ref.watch(libraryItemProvider(book.libraryItemId)).valueOrNull;
|
||||||
final image =
|
final image = item == null
|
||||||
item == null ? const AsyncValue.loading() : ref.watch(coverImageProvider(item.id));
|
? const AsyncValue.loading()
|
||||||
|
: ref.watch(coverImageProvider(item.id));
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: SizedBox(
|
leading: SizedBox(
|
||||||
width: 50,
|
width: 50,
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,11 @@ class LibraryItemActions extends HookConsumerWidget {
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
appLogger.fine('Sharing');
|
appLogger.fine('Sharing');
|
||||||
var currentServerUrl = apiSettings.activeServer!.serverUrl;
|
var currentServerUrl =
|
||||||
|
apiSettings.activeServer!.serverUrl;
|
||||||
if (!currentServerUrl.hasScheme) {
|
if (!currentServerUrl.hasScheme) {
|
||||||
currentServerUrl = Uri.https(currentServerUrl.toString());
|
currentServerUrl =
|
||||||
|
Uri.https(currentServerUrl.toString());
|
||||||
}
|
}
|
||||||
handleLaunchUrl(
|
handleLaunchUrl(
|
||||||
Uri.parse(
|
Uri.parse(
|
||||||
|
|
@ -138,7 +140,8 @@ class LibraryItemActions extends HookConsumerWidget {
|
||||||
FileDownloader()
|
FileDownloader()
|
||||||
.database
|
.database
|
||||||
.deleteRecordWithId(
|
.deleteRecordWithId(
|
||||||
record.task.taskId,
|
record
|
||||||
|
.task.taskId,
|
||||||
);
|
);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
|
|
@ -157,7 +160,8 @@ class LibraryItemActions extends HookConsumerWidget {
|
||||||
},
|
},
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// open the file location
|
// open the file location
|
||||||
final didOpen = await FileDownloader().openFile(
|
final didOpen =
|
||||||
|
await FileDownloader().openFile(
|
||||||
task: record.task,
|
task: record.task,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -226,7 +230,9 @@ class LibItemDownloadButton extends HookConsumerWidget {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
appLogger.fine('Pressed download button');
|
appLogger.fine('Pressed download button');
|
||||||
|
|
||||||
ref.read(downloadManagerProvider.notifier).queueAudioBookDownload(item);
|
ref
|
||||||
|
.read(downloadManagerProvider.notifier)
|
||||||
|
.queueAudioBookDownload(item);
|
||||||
},
|
},
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.download_rounded,
|
Icons.download_rounded,
|
||||||
|
|
@ -245,7 +251,10 @@ class ItemCurrentlyInDownloadQueue extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
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) {
|
if (progress == 1) {
|
||||||
return AlreadyItemDownloadedButton(item: item);
|
return AlreadyItemDownloadedButton(item: item);
|
||||||
|
|
@ -333,7 +342,7 @@ class DownloadSheet extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final manager = ref.watch(downloadManagerProvider);
|
// final manager = ref.watch(downloadManagerProvider);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
|
@ -377,7 +386,9 @@ class DownloadSheet extends HookConsumerWidget {
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// delete the file
|
// delete the file
|
||||||
ref.read(downloadManagerProvider.notifier).deleteDownloadedItem(
|
ref
|
||||||
|
.read(downloadManagerProvider.notifier)
|
||||||
|
.deleteDownloadedItem(
|
||||||
item,
|
item,
|
||||||
);
|
);
|
||||||
GoRouter.of(context).pop(true);
|
GoRouter.of(context).pop(true);
|
||||||
|
|
@ -396,7 +407,8 @@ class DownloadSheet extends HookConsumerWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (wasDeleted ?? false) {
|
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();
|
GoRouter.of(context).pop();
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
|
|
@ -520,7 +532,8 @@ Future<void> libraryItemPlayButtonOnPressed({
|
||||||
appLogger.info('Setting the book ${book.libraryItemId}');
|
appLogger.info('Setting the book ${book.libraryItemId}');
|
||||||
appLogger.info('Initial position: ${userMediaProgress?.currentTime}');
|
appLogger.info('Initial position: ${userMediaProgress?.currentTime}');
|
||||||
final downloadManager = ref.watch(simpleDownloadManagerProvider);
|
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);
|
final downloadedUris = await downloadManager.getDownloadedFilesUri(libItem);
|
||||||
setSourceFuture = player.setSourceAudiobook(
|
setSourceFuture = player.setSourceAudiobook(
|
||||||
book,
|
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
|
// 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 appPlayerSettings = ref.read(appSettingsProvider).playerSettings;
|
||||||
|
|
||||||
var configurePlayerForEveryBook = appPlayerSettings.configurePlayerForEveryBook;
|
var configurePlayerForEveryBook =
|
||||||
|
appPlayerSettings.configurePlayerForEveryBook;
|
||||||
|
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
setSourceFuture ?? Future.value(),
|
setSourceFuture ?? Future.value(),
|
||||||
// set the volume
|
// set the volume
|
||||||
player.setVolume(
|
player.setVolume(
|
||||||
configurePlayerForEveryBook
|
configurePlayerForEveryBook
|
||||||
? bookPlayerSettings.preferredDefaultVolume ?? appPlayerSettings.preferredDefaultVolume
|
? bookPlayerSettings.preferredDefaultVolume ??
|
||||||
|
appPlayerSettings.preferredDefaultVolume
|
||||||
: appPlayerSettings.preferredDefaultVolume,
|
: appPlayerSettings.preferredDefaultVolume,
|
||||||
),
|
),
|
||||||
// set the speed
|
// set the speed
|
||||||
player.setSpeed(
|
player.setSpeed(
|
||||||
configurePlayerForEveryBook
|
configurePlayerForEveryBook
|
||||||
? bookPlayerSettings.preferredDefaultSpeed ?? appPlayerSettings.preferredDefaultSpeed
|
? bookPlayerSettings.preferredDefaultSpeed ??
|
||||||
|
appPlayerSettings.preferredDefaultSpeed
|
||||||
: appPlayerSettings.preferredDefaultSpeed,
|
: appPlayerSettings.preferredDefaultSpeed,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,9 @@ class LibraryItemMetadata extends HookConsumerWidget {
|
||||||
if (book == null) {
|
if (book == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final duration =
|
final duration = book.audioFiles
|
||||||
book.audioFiles.map((e) => e.duration).reduce((value, element) => value + element);
|
.map((e) => e.duration)
|
||||||
|
.reduce((value, element) => value + element);
|
||||||
final hours = duration.inHours;
|
final hours = duration.inHours;
|
||||||
final minutes = duration.inMinutes.remainder(60);
|
final minutes = duration.inMinutes.remainder(60);
|
||||||
return '${hours}h ${minutes}m';
|
return '${hours}h ${minutes}m';
|
||||||
|
|
@ -41,8 +42,9 @@ class LibraryItemMetadata extends HookConsumerWidget {
|
||||||
if (book == null) {
|
if (book == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final size =
|
final size = book.audioFiles
|
||||||
book.audioFiles.map((e) => e.metadata.size).reduce((value, element) => value + element);
|
.map((e) => e.metadata.size)
|
||||||
|
.reduce((value, element) => value + element);
|
||||||
if (size / 1024 / 1024 < 1024) {
|
if (size / 1024 / 1024 < 1024) {
|
||||||
return '${(size / 1024 / 1024).toStringAsFixed(2)} MB';
|
return '${(size / 1024 / 1024).toStringAsFixed(2)} MB';
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +100,10 @@ class LibraryItemMetadata extends HookConsumerWidget {
|
||||||
return VerticalDivider(
|
return VerticalDivider(
|
||||||
indent: 6,
|
indent: 6,
|
||||||
endIndent: 6,
|
endIndent: 6,
|
||||||
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.6),
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onSurface
|
||||||
|
.withValues(alpha: 0.6),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ class LibraryItemPage extends HookConsumerWidget {
|
||||||
static const double _showFabThreshold = 300.0;
|
static const double _showFabThreshold = 300.0;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
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 scrollController = useScrollController();
|
||||||
final showFab = useState(false);
|
final showFab = useState(false);
|
||||||
|
|
||||||
|
|
@ -151,7 +152,8 @@ class LibraryItemDescription extends HookConsumerWidget {
|
||||||
}
|
}
|
||||||
return ExpandableDescription(
|
return ExpandableDescription(
|
||||||
title: S.of(context).bookAbout,
|
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,
|
readMoreText: S.of(context).readMore,
|
||||||
readLessText: S.of(context).readLess,
|
readLessText: S.of(context).readLess,
|
||||||
);
|
);
|
||||||
|
|
@ -168,8 +170,10 @@ double calculateWidth(
|
||||||
/// height ratio of the cover image to the available height
|
/// height ratio of the cover image to the available height
|
||||||
double maxHeightToUse = 0.25,
|
double maxHeightToUse = 0.25,
|
||||||
}) {
|
}) {
|
||||||
final availHeight = min(constraints.maxHeight, MediaQuery.of(context).size.height);
|
final availHeight =
|
||||||
final availWidth = min(constraints.maxWidth, MediaQuery.of(context).size.width);
|
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
|
// make the width widthRatio of the available width
|
||||||
var width = availWidth * widthRatio;
|
var width = availWidth * widthRatio;
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
|
||||||
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:vaani/api/library_provider.dart' show currentLibraryProvider;
|
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/generated/l10n.dart';
|
||||||
import 'package:vaani/router/router.dart' show Routes;
|
import 'package:vaani/router/router.dart' show Routes;
|
||||||
import 'package:vaani/shared/icons/abs_icons.dart' show AbsIcons;
|
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 {
|
class LibraryBrowserPage extends HookConsumerWidget {
|
||||||
const LibraryBrowserPage({super.key});
|
const LibraryBrowserPage({super.key});
|
||||||
|
|
@ -32,7 +34,9 @@ class LibraryBrowserPage extends HookConsumerWidget {
|
||||||
// true, // Optional: uncomment if you want snapping behavior (usually with floating: true)
|
// true, // Optional: uncomment if you want snapping behavior (usually with floating: true)
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: Icon(libraryIconData),
|
icon: Icon(libraryIconData),
|
||||||
tooltip: S.of(context).librarySwitchTooltip, // Helpful tooltip for users
|
tooltip: S
|
||||||
|
.of(context)
|
||||||
|
.librarySwitchTooltip, // Helpful tooltip for users
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showLibrarySwitcher(context, ref);
|
showLibrarySwitcher(context, ref);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:vaani/db/available_boxes.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';
|
import 'package:vaani/features/per_book_settings/models/nullable_player_settings.dart';
|
||||||
|
|
||||||
part 'book_settings_provider.g.dart';
|
part 'book_settings_provider.g.dart';
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,11 @@ class AudiobookPlayer extends AudioPlayer {
|
||||||
final trackToPlay = getTrackToPlay(book, initialPosition ?? Duration.zero);
|
final trackToPlay = getTrackToPlay(book, initialPosition ?? Duration.zero);
|
||||||
|
|
||||||
final initialIndex = book.tracks.indexOf(trackToPlay);
|
final initialIndex = book.tracks.indexOf(trackToPlay);
|
||||||
final initialPositionInTrack =
|
final initialPositionInTrack = initialPosition != null
|
||||||
initialPosition != null ? initialPosition - trackToPlay.startOffset : null;
|
? initialPosition - trackToPlay.startOffset
|
||||||
await setAudioSourceTrack(initialIndex, initialPosition: initialPositionInTrack);
|
: null;
|
||||||
|
await setAudioSourceTrack(initialIndex,
|
||||||
|
initialPosition: initialPositionInTrack);
|
||||||
// _logger.finer('Setting audioSource');
|
// _logger.finer('Setting audioSource');
|
||||||
// await setAudioSource(
|
// await setAudioSource(
|
||||||
// preload: preload,
|
// 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) {
|
if (_book == null) {
|
||||||
return stop();
|
return stop();
|
||||||
}
|
}
|
||||||
|
|
@ -168,9 +171,11 @@ class AudiobookPlayer extends AudioPlayer {
|
||||||
_currentIndex = index;
|
_currentIndex = index;
|
||||||
AudioTrack track = _book!.tracks[index];
|
AudioTrack track = _book!.tracks[index];
|
||||||
final appSettings = loadOrCreateAppSettings();
|
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(
|
await setAudioSource(
|
||||||
initialPosition: initialPosition == null || initialPosition <= Duration()
|
initialPosition: initialPosition == null || initialPosition <= Duration()
|
||||||
|
|
@ -185,8 +190,10 @@ class AudiobookPlayer extends AudioPlayer {
|
||||||
// Specify a unique ID for each media item:
|
// Specify a unique ID for each media item:
|
||||||
id: '${book?.libraryItemId}${track.index}',
|
id: '${book?.libraryItemId}${track.index}',
|
||||||
// Metadata to display in the notification:
|
// Metadata to display in the notification:
|
||||||
title: appSettings.notificationSettings.primaryTitle.formatNotificationTitle(book!),
|
title: appSettings.notificationSettings.primaryTitle
|
||||||
album: appSettings.notificationSettings.secondaryTitle.formatNotificationTitle(book!),
|
.formatNotificationTitle(book!),
|
||||||
|
album: appSettings.notificationSettings.secondaryTitle
|
||||||
|
.formatNotificationTitle(book!),
|
||||||
artUri: Uri.parse(
|
artUri: Uri.parse(
|
||||||
'$baseUrl/api/items/${book?.libraryItemId}/cover?token=$token&width=800',
|
'$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 {
|
extension FormatNotificationTitle on String {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ class AudiobookPlayer extends HookConsumerWidget {
|
||||||
if (currentBook == null) {
|
if (currentBook == null) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
final itemBeingPlayed = ref.watch(libraryItemProvider(currentBook.libraryItemId));
|
final itemBeingPlayed =
|
||||||
|
ref.watch(libraryItemProvider(currentBook.libraryItemId));
|
||||||
final player = ref.watch(audiobookPlayerProvider);
|
final player = ref.watch(audiobookPlayerProvider);
|
||||||
final imageOfItemBeingPlayed = itemBeingPlayed.valueOrNull != null
|
final imageOfItemBeingPlayed = itemBeingPlayed.valueOrNull != null
|
||||||
? ref.watch(
|
? ref.watch(
|
||||||
|
|
@ -64,7 +65,8 @@ class AudiobookPlayer extends HookConsumerWidget {
|
||||||
themeOfLibraryItemProvider(
|
themeOfLibraryItemProvider(
|
||||||
itemBeingPlayed.valueOrNull?.id,
|
itemBeingPlayed.valueOrNull?.id,
|
||||||
brightness: Theme.of(context).brightness,
|
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 {
|
onDragDown: (percentage) async {
|
||||||
// preferred volume
|
// preferred volume
|
||||||
// set volume to 0 when dragging down
|
// 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,
|
minHeight: playerMinHeight,
|
||||||
// subtract the height of notches and other system UI
|
// 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
|
// 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
|
// also at this point the image should be at its max size and in the center of the player
|
||||||
final miniplayerPercentageDeclaration =
|
final miniplayerPercentageDeclaration =
|
||||||
(maxImgSize - playerMinHeight) / (playerMaxHeight - playerMinHeight);
|
(maxImgSize - playerMinHeight) /
|
||||||
final bool isFormMiniplayer = percentage < miniplayerPercentageDeclaration;
|
(playerMaxHeight - playerMinHeight);
|
||||||
|
final bool isFormMiniplayer =
|
||||||
|
percentage < miniplayerPercentageDeclaration;
|
||||||
|
|
||||||
if (!isFormMiniplayer) {
|
if (!isFormMiniplayer) {
|
||||||
// this calculation needs a refactor
|
// this calculation needs a refactor
|
||||||
|
|
@ -207,14 +212,17 @@ class AudiobookChapterProgressBar extends HookConsumerWidget {
|
||||||
|
|
||||||
// now find the chapter that corresponds to the current time
|
// now find the chapter that corresponds to the current time
|
||||||
// and calculate the progress of the current chapter
|
// and calculate the progress of the current chapter
|
||||||
final currentChapterProgress =
|
final currentChapterProgress = currentChapter == null
|
||||||
currentChapter == null ? null : (player.positionInBook - currentChapter.start);
|
? null
|
||||||
|
: (player.positionInBook - currentChapter.start);
|
||||||
|
|
||||||
final currentChapterBuffered =
|
final currentChapterBuffered = currentChapter == null
|
||||||
currentChapter == null ? null : (player.bufferedPositionInBook - currentChapter.start);
|
? null
|
||||||
|
: (player.bufferedPositionInBook - currentChapter.start);
|
||||||
|
|
||||||
return ProgressBar(
|
return ProgressBar(
|
||||||
progress: currentChapterProgress ?? position.data ?? const Duration(seconds: 0),
|
progress:
|
||||||
|
currentChapterProgress ?? position.data ?? const Duration(seconds: 0),
|
||||||
total: currentChapter == null
|
total: currentChapter == null
|
||||||
? player.book?.duration ?? const Duration(seconds: 0)
|
? player.book?.duration ?? const Duration(seconds: 0)
|
||||||
: currentChapter.end - currentChapter.start,
|
: currentChapter.end - currentChapter.start,
|
||||||
|
|
@ -226,7 +234,8 @@ class AudiobookChapterProgressBar extends HookConsumerWidget {
|
||||||
player.seek(duration);
|
player.seek(duration);
|
||||||
},
|
},
|
||||||
thumbRadius: 8,
|
thumbRadius: 8,
|
||||||
buffered: currentChapterBuffered ?? buffered.data ?? const Duration(seconds: 0),
|
buffered:
|
||||||
|
currentChapterBuffered ?? buffered.data ?? const Duration(seconds: 0),
|
||||||
bufferedBarColor: Theme.of(context).colorScheme.secondary,
|
bufferedBarColor: Theme.of(context).colorScheme.secondary,
|
||||||
timeLabelType: TimeLabelType.remainingTime,
|
timeLabelType: TimeLabelType.remainingTime,
|
||||||
timeLabelLocation: TimeLabelLocation.below,
|
timeLabelLocation: TimeLabelLocation.below,
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,10 @@ class PlayerWhenExpanded extends HookConsumerWidget {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
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,
|
blurRadius: 32 * earlyPercentage,
|
||||||
spreadRadius: 8 * earlyPercentage,
|
spreadRadius: 8 * earlyPercentage,
|
||||||
// offset: Offset(0, 16 * earlyPercentage),
|
// offset: Offset(0, 16 * earlyPercentage),
|
||||||
|
|
@ -171,7 +174,10 @@ class PlayerWhenExpanded extends HookConsumerWidget {
|
||||||
currentBookMetadata?.authorName ?? '',
|
currentBookMetadata?.authorName ?? '',
|
||||||
].join(' - '),
|
].join(' - '),
|
||||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
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,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ class PlayerWhenMinimized extends HookConsumerWidget {
|
||||||
final currentChapter = ref.watch(currentPlayingChapterProvider);
|
final currentChapter = ref.watch(currentPlayingChapterProvider);
|
||||||
|
|
||||||
final vanishingPercentage = 1 - percentageMiniplayer;
|
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);
|
final bookMetaExpanded = ref.watch(currentBookMetadataProvider);
|
||||||
|
|
||||||
|
|
@ -56,7 +57,8 @@ class PlayerWhenMinimized extends HookConsumerWidget {
|
||||||
context.pushNamed(
|
context.pushNamed(
|
||||||
Routes.libraryItem.name,
|
Routes.libraryItem.name,
|
||||||
pathParameters: {
|
pathParameters: {
|
||||||
Routes.libraryItem.pathParamName!: player.book!.libraryItemId,
|
Routes.libraryItem.pathParamName!:
|
||||||
|
player.book!.libraryItemId,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -90,7 +92,10 @@ class PlayerWhenMinimized extends HookConsumerWidget {
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
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(
|
SizedBox(
|
||||||
height: barHeight,
|
height: barHeight,
|
||||||
child: LinearProgressIndicator(
|
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,
|
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.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'
|
import 'package:vaani/features/player/providers/currently_playing_provider.dart'
|
||||||
show currentPlayingChapterProvider, currentlyPlayingBookProvider;
|
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/features/player/view/widgets/playing_indicator_icon.dart';
|
||||||
import 'package:vaani/main.dart' show appLogger;
|
import 'package:vaani/main.dart' show appLogger;
|
||||||
import 'package:vaani/shared/extensions/chapter.dart' show ChapterDuration;
|
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;
|
import 'package:vaani/shared/hooks.dart' show useTimer;
|
||||||
|
|
||||||
class ChapterSelectionButton extends HookConsumerWidget {
|
class ChapterSelectionButton extends HookConsumerWidget {
|
||||||
|
|
@ -88,11 +91,13 @@ class ChapterSelectionModal extends HookConsumerWidget {
|
||||||
children: currentBook!.chapters.map(
|
children: currentBook!.chapters.map(
|
||||||
(chapter) {
|
(chapter) {
|
||||||
final isCurrent = currentChapterIndex == chapter.id;
|
final isCurrent = currentChapterIndex == chapter.id;
|
||||||
final isPlayed =
|
final isPlayed = currentChapterIndex != null &&
|
||||||
currentChapterIndex != null && chapter.id < currentChapterIndex;
|
chapter.id < currentChapterIndex;
|
||||||
return ListTile(
|
return ListTile(
|
||||||
autofocus: isCurrent,
|
autofocus: isCurrent,
|
||||||
iconColor: isPlayed && !isCurrent ? theme.disabledColor : null,
|
iconColor: isPlayed && !isCurrent
|
||||||
|
? theme.disabledColor
|
||||||
|
: null,
|
||||||
title: Text(
|
title: Text(
|
||||||
chapter.title,
|
chapter.title,
|
||||||
style: isPlayed && !isCurrent
|
style: isPlayed && !isCurrent
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ class PlayerSkipChapterStartEnd extends HookConsumerWidget {
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('跳过片头 ${bookSettings.playerSettings.skipChapterStart.inSeconds}s'),
|
title: Text(
|
||||||
|
'跳过片头 ${bookSettings.playerSettings.skipChapterStart.inSeconds}s'),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TimeIntervalSlider(
|
child: TimeIntervalSlider(
|
||||||
|
|
@ -65,14 +66,16 @@ class PlayerSkipChapterStartEnd extends HookConsumerWidget {
|
||||||
bookSettingsProvider(bookId).notifier,
|
bookSettingsProvider(bookId).notifier,
|
||||||
)
|
)
|
||||||
.update(
|
.update(
|
||||||
bookSettings.copyWith.playerSettings(skipChapterStart: interval),
|
bookSettings.copyWith
|
||||||
|
.playerSettings(skipChapterStart: interval),
|
||||||
);
|
);
|
||||||
ref.read(audiobookPlayerProvider).setClip(start: interval);
|
ref.read(audiobookPlayerProvider).setClip(start: interval);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('跳过片尾 ${bookSettings.playerSettings.skipChapterEnd.inSeconds}s'),
|
title: Text(
|
||||||
|
'跳过片尾 ${bookSettings.playerSettings.skipChapterEnd.inSeconds}s'),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TimeIntervalSlider(
|
child: TimeIntervalSlider(
|
||||||
|
|
@ -87,7 +90,8 @@ class PlayerSkipChapterStartEnd extends HookConsumerWidget {
|
||||||
bookSettingsProvider(bookId).notifier,
|
bookSettingsProvider(bookId).notifier,
|
||||||
)
|
)
|
||||||
.update(
|
.update(
|
||||||
bookSettings.copyWith.playerSettings(skipChapterEnd: interval),
|
bookSettings.copyWith
|
||||||
|
.playerSettings(skipChapterEnd: interval),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:shelfsdk/audiobookshelf_api.dart' show Library;
|
import 'package:shelfsdk/audiobookshelf_api.dart' show Library;
|
||||||
import 'package:vaani/api/library_provider.dart';
|
import 'package:vaani/api/library_provider.dart';
|
||||||
import 'package:vaani/generated/l10n.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 'package:vaani/shared/icons/abs_icons.dart';
|
||||||
import 'dart:io' show Platform;
|
import 'dart:io' show Platform;
|
||||||
|
|
||||||
|
|
@ -99,7 +100,8 @@ void showLibrarySwitcher(
|
||||||
// Make it scrollable and control height
|
// Make it scrollable and control height
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
constraints: BoxConstraints(
|
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(
|
builder: (sheetContext) => Padding(
|
||||||
// Add padding within the bottom sheet
|
// Add padding within the bottom sheet
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,8 @@ class YouPage extends HookConsumerWidget {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
librariesAsyncValue.when(
|
librariesAsyncValue.when(
|
||||||
data: (libraries) => LibrarySwitchChip(libraries: libraries),
|
data: (libraries) =>
|
||||||
|
LibrarySwitchChip(libraries: libraries),
|
||||||
loading: () => const ActionChip(
|
loading: () => const ActionChip(
|
||||||
avatar: SizedBox(
|
avatar: SizedBox(
|
||||||
width: 18,
|
width: 18,
|
||||||
|
|
@ -88,7 +89,8 @@ class YouPage extends HookConsumerWidget {
|
||||||
// Maybe show error details or allow retry
|
// Maybe show error details or allow retry
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
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),
|
icon: const Icon(Icons.info),
|
||||||
applicationName: AppMetadata.appName,
|
applicationName: AppMetadata.appName,
|
||||||
applicationVersion: AppMetadata.version,
|
applicationVersion: AppMetadata.version,
|
||||||
applicationLegalese: 'Made with ❤️ by ${AppMetadata.author}',
|
applicationLegalese:
|
||||||
|
'Made with ❤️ by ${AppMetadata.author}',
|
||||||
aboutBoxChildren: [
|
aboutBoxChildren: [
|
||||||
// link to github repo
|
// link to github repo
|
||||||
ListTile(
|
ListTile(
|
||||||
|
|
@ -216,7 +219,8 @@ class UserBar extends HookConsumerWidget {
|
||||||
Text(
|
Text(
|
||||||
api.baseUrl.toString(),
|
api.baseUrl.toString(),
|
||||||
style: textTheme.bodyMedium?.copyWith(
|
style: textTheme.bodyMedium?.copyWith(
|
||||||
color: themeData.colorScheme.onSurface.withValues(alpha: 0.6),
|
color:
|
||||||
|
themeData.colorScheme.onSurface.withValues(alpha: 0.6),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -28,199 +28,207 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
|
|
||||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
"account": MessageLookupByLibrary.simpleMessage("Account"),
|
"account": MessageLookupByLibrary.simpleMessage("Account"),
|
||||||
"accountSwitch": MessageLookupByLibrary.simpleMessage("Switch Account"),
|
"accountSwitch": MessageLookupByLibrary.simpleMessage("Switch Account"),
|
||||||
"appSettings": MessageLookupByLibrary.simpleMessage("App Settings"),
|
"appSettings": MessageLookupByLibrary.simpleMessage("App Settings"),
|
||||||
"appearance": MessageLookupByLibrary.simpleMessage("Appearance"),
|
"appearance": MessageLookupByLibrary.simpleMessage("Appearance"),
|
||||||
"autoTurnOnSleepTimer": MessageLookupByLibrary.simpleMessage(
|
"autoTurnOnSleepTimer": MessageLookupByLibrary.simpleMessage(
|
||||||
"Auto Turn On Sleep Timer",
|
"Auto Turn On Sleep Timer",
|
||||||
),
|
),
|
||||||
"automaticallyDescription": MessageLookupByLibrary.simpleMessage(
|
"automaticallyDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"Automatically turn on the sleep timer based on the time of day",
|
"Automatically turn on the sleep timer based on the time of day",
|
||||||
),
|
),
|
||||||
"backup": MessageLookupByLibrary.simpleMessage("Backup"),
|
"backup": MessageLookupByLibrary.simpleMessage("Backup"),
|
||||||
"backupAndRestore": MessageLookupByLibrary.simpleMessage(
|
"backupAndRestore": MessageLookupByLibrary.simpleMessage(
|
||||||
"Backup and Restore",
|
"Backup and Restore",
|
||||||
),
|
),
|
||||||
"bookAbout": MessageLookupByLibrary.simpleMessage("About the Book"),
|
"bookAbout": MessageLookupByLibrary.simpleMessage("About the Book"),
|
||||||
"bookAboutDefault": MessageLookupByLibrary.simpleMessage(
|
"bookAboutDefault": MessageLookupByLibrary.simpleMessage(
|
||||||
"Sorry, no description found",
|
"Sorry, no description found",
|
||||||
),
|
),
|
||||||
"bookAuthors": MessageLookupByLibrary.simpleMessage("Authors"),
|
"bookAuthors": MessageLookupByLibrary.simpleMessage("Authors"),
|
||||||
"bookDownloads": MessageLookupByLibrary.simpleMessage("Downloads"),
|
"bookDownloads": MessageLookupByLibrary.simpleMessage("Downloads"),
|
||||||
"bookGenres": MessageLookupByLibrary.simpleMessage("Genres"),
|
"bookGenres": MessageLookupByLibrary.simpleMessage("Genres"),
|
||||||
"bookMetadataAbridged": MessageLookupByLibrary.simpleMessage("Abridged"),
|
"bookMetadataAbridged":
|
||||||
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("Length"),
|
MessageLookupByLibrary.simpleMessage("Abridged"),
|
||||||
"bookMetadataPublished": MessageLookupByLibrary.simpleMessage("Published"),
|
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("Length"),
|
||||||
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage(
|
"bookMetadataPublished":
|
||||||
"Unabridged",
|
MessageLookupByLibrary.simpleMessage("Published"),
|
||||||
),
|
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage(
|
||||||
"bookSeries": MessageLookupByLibrary.simpleMessage("Series"),
|
"Unabridged",
|
||||||
"bookShelveEmpty": MessageLookupByLibrary.simpleMessage("Try again"),
|
),
|
||||||
"bookShelveEmptyText": MessageLookupByLibrary.simpleMessage(
|
"bookSeries": MessageLookupByLibrary.simpleMessage("Series"),
|
||||||
"No shelves to display",
|
"bookShelveEmpty": MessageLookupByLibrary.simpleMessage("Try again"),
|
||||||
),
|
"bookShelveEmptyText": MessageLookupByLibrary.simpleMessage(
|
||||||
"cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
|
"No shelves to display",
|
||||||
"copyToClipboard": MessageLookupByLibrary.simpleMessage(
|
),
|
||||||
"Copy to Clipboard",
|
"cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
|
||||||
),
|
"copyToClipboard": MessageLookupByLibrary.simpleMessage(
|
||||||
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
|
"Copy to Clipboard",
|
||||||
"Copy the app settings to the clipboard",
|
),
|
||||||
),
|
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"copyToClipboardToast": MessageLookupByLibrary.simpleMessage(
|
"Copy the app settings to the clipboard",
|
||||||
"Settings copied to clipboard",
|
),
|
||||||
),
|
"copyToClipboardToast": MessageLookupByLibrary.simpleMessage(
|
||||||
"delete": MessageLookupByLibrary.simpleMessage("Delete"),
|
"Settings copied to clipboard",
|
||||||
"deleteDialog": m0,
|
),
|
||||||
"deleted": m1,
|
"delete": MessageLookupByLibrary.simpleMessage("Delete"),
|
||||||
"explore": MessageLookupByLibrary.simpleMessage("explore"),
|
"deleteDialog": m0,
|
||||||
"exploreHint": MessageLookupByLibrary.simpleMessage(
|
"deleted": m1,
|
||||||
"Seek and you shall discover...",
|
"explore": MessageLookupByLibrary.simpleMessage("explore"),
|
||||||
),
|
"exploreHint": MessageLookupByLibrary.simpleMessage(
|
||||||
"exploreTooltip": MessageLookupByLibrary.simpleMessage(
|
"Seek and you shall discover...",
|
||||||
"Search and Explore",
|
),
|
||||||
),
|
"exploreTooltip": MessageLookupByLibrary.simpleMessage(
|
||||||
"general": MessageLookupByLibrary.simpleMessage("General"),
|
"Search and Explore",
|
||||||
"help": MessageLookupByLibrary.simpleMessage("Help"),
|
),
|
||||||
"home": MessageLookupByLibrary.simpleMessage("Home"),
|
"general": MessageLookupByLibrary.simpleMessage("General"),
|
||||||
"homeBookContinueListening": MessageLookupByLibrary.simpleMessage(
|
"help": MessageLookupByLibrary.simpleMessage("Help"),
|
||||||
"Continue Listening",
|
"home": MessageLookupByLibrary.simpleMessage("Home"),
|
||||||
),
|
"homeBookContinueListening": MessageLookupByLibrary.simpleMessage(
|
||||||
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage(
|
"Continue Listening",
|
||||||
"Continue Series",
|
),
|
||||||
),
|
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage(
|
||||||
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("Discover"),
|
"Continue Series",
|
||||||
"homeBookListenAgain": MessageLookupByLibrary.simpleMessage("Listen Again"),
|
),
|
||||||
"homeBookNewestAuthors": MessageLookupByLibrary.simpleMessage(
|
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("Discover"),
|
||||||
"Newest Authors",
|
"homeBookListenAgain":
|
||||||
),
|
MessageLookupByLibrary.simpleMessage("Listen Again"),
|
||||||
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage(
|
"homeBookNewestAuthors": MessageLookupByLibrary.simpleMessage(
|
||||||
"Recently Added",
|
"Newest Authors",
|
||||||
),
|
),
|
||||||
"homeBookRecommended": MessageLookupByLibrary.simpleMessage("Recommended"),
|
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage(
|
||||||
"homeContinueListening": MessageLookupByLibrary.simpleMessage(
|
"Recently Added",
|
||||||
"Continue Listening",
|
),
|
||||||
),
|
"homeBookRecommended":
|
||||||
"homeListenAgain": MessageLookupByLibrary.simpleMessage("Listen Again"),
|
MessageLookupByLibrary.simpleMessage("Recommended"),
|
||||||
"homePageSettings": MessageLookupByLibrary.simpleMessage(
|
"homeContinueListening": MessageLookupByLibrary.simpleMessage(
|
||||||
"Home Page Settings",
|
"Continue Listening",
|
||||||
),
|
),
|
||||||
"homePageSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
"homeListenAgain": MessageLookupByLibrary.simpleMessage("Listen Again"),
|
||||||
"Customize the home page",
|
"homePageSettings": MessageLookupByLibrary.simpleMessage(
|
||||||
),
|
"Home Page Settings",
|
||||||
"homeStartListening": MessageLookupByLibrary.simpleMessage(
|
),
|
||||||
"Start Listening",
|
"homePageSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
),
|
"Customize the home page",
|
||||||
"language": MessageLookupByLibrary.simpleMessage("Language"),
|
),
|
||||||
"languageDescription": MessageLookupByLibrary.simpleMessage(
|
"homeStartListening": MessageLookupByLibrary.simpleMessage(
|
||||||
"Language switch",
|
"Start Listening",
|
||||||
),
|
),
|
||||||
"library": MessageLookupByLibrary.simpleMessage("Library"),
|
"language": MessageLookupByLibrary.simpleMessage("Language"),
|
||||||
"libraryChange": MessageLookupByLibrary.simpleMessage("Change Library"),
|
"languageDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"libraryEmpty": MessageLookupByLibrary.simpleMessage(
|
"Language switch",
|
||||||
"No libraries available.",
|
),
|
||||||
),
|
"library": MessageLookupByLibrary.simpleMessage("Library"),
|
||||||
"libraryLoadError": m2,
|
"libraryChange": MessageLookupByLibrary.simpleMessage("Change Library"),
|
||||||
"librarySelect": MessageLookupByLibrary.simpleMessage("Select Library"),
|
"libraryEmpty": MessageLookupByLibrary.simpleMessage(
|
||||||
"librarySwitchTooltip": MessageLookupByLibrary.simpleMessage(
|
"No libraries available.",
|
||||||
"Switch Library",
|
),
|
||||||
),
|
"libraryLoadError": m2,
|
||||||
"libraryTooltip": MessageLookupByLibrary.simpleMessage(
|
"librarySelect": MessageLookupByLibrary.simpleMessage("Select Library"),
|
||||||
"Browse your library",
|
"librarySwitchTooltip": MessageLookupByLibrary.simpleMessage(
|
||||||
),
|
"Switch Library",
|
||||||
"loading": MessageLookupByLibrary.simpleMessage("Loading..."),
|
),
|
||||||
"logs": MessageLookupByLibrary.simpleMessage("Logs"),
|
"libraryTooltip": MessageLookupByLibrary.simpleMessage(
|
||||||
"no": MessageLookupByLibrary.simpleMessage("No"),
|
"Browse your library",
|
||||||
"notImplemented": MessageLookupByLibrary.simpleMessage("Not implemented"),
|
),
|
||||||
"notificationMediaPlayer": MessageLookupByLibrary.simpleMessage(
|
"loading": MessageLookupByLibrary.simpleMessage("Loading..."),
|
||||||
"Notification Media Player",
|
"logs": MessageLookupByLibrary.simpleMessage("Logs"),
|
||||||
),
|
"no": MessageLookupByLibrary.simpleMessage("No"),
|
||||||
"notificationMediaPlayerDescription": MessageLookupByLibrary.simpleMessage(
|
"notImplemented":
|
||||||
"Customize the media player in notifications",
|
MessageLookupByLibrary.simpleMessage("Not implemented"),
|
||||||
),
|
"notificationMediaPlayer": MessageLookupByLibrary.simpleMessage(
|
||||||
"ok": MessageLookupByLibrary.simpleMessage("OK"),
|
"Notification Media Player",
|
||||||
"pause": MessageLookupByLibrary.simpleMessage("Pause"),
|
),
|
||||||
"play": MessageLookupByLibrary.simpleMessage("Play"),
|
"notificationMediaPlayerDescription":
|
||||||
"playerSettings": MessageLookupByLibrary.simpleMessage("Player Settings"),
|
MessageLookupByLibrary.simpleMessage(
|
||||||
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
"Customize the media player in notifications",
|
||||||
"Customize the player settings",
|
),
|
||||||
),
|
"ok": MessageLookupByLibrary.simpleMessage("OK"),
|
||||||
"playerSettingsPlaybackReporting": MessageLookupByLibrary.simpleMessage(
|
"pause": MessageLookupByLibrary.simpleMessage("Pause"),
|
||||||
"Playback Reporting",
|
"play": MessageLookupByLibrary.simpleMessage("Play"),
|
||||||
),
|
"playerSettings":
|
||||||
"playerSettingsPlaybackReportingIgnore":
|
MessageLookupByLibrary.simpleMessage("Player Settings"),
|
||||||
MessageLookupByLibrary.simpleMessage(
|
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Customize the player settings",
|
||||||
|
),
|
||||||
|
"playerSettingsPlaybackReporting": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Playback Reporting",
|
||||||
|
),
|
||||||
|
"playerSettingsPlaybackReportingIgnore":
|
||||||
|
MessageLookupByLibrary.simpleMessage(
|
||||||
"Ignore Playback Position Less Than",
|
"Ignore Playback Position Less Than",
|
||||||
),
|
),
|
||||||
"playerSettingsPlaybackReportingMinimum":
|
"playerSettingsPlaybackReportingMinimum":
|
||||||
MessageLookupByLibrary.simpleMessage("Minimum Position to Report"),
|
MessageLookupByLibrary.simpleMessage("Minimum Position to Report"),
|
||||||
"playerSettingsPlaybackReportingMinimumDescriptionHead":
|
"playerSettingsPlaybackReportingMinimumDescriptionHead":
|
||||||
MessageLookupByLibrary.simpleMessage(
|
MessageLookupByLibrary.simpleMessage(
|
||||||
"Do not report playback for the first ",
|
"Do not report playback for the first ",
|
||||||
),
|
),
|
||||||
"playerSettingsPlaybackReportingMinimumDescriptionTail":
|
"playerSettingsPlaybackReportingMinimumDescriptionTail":
|
||||||
MessageLookupByLibrary.simpleMessage("of the book"),
|
MessageLookupByLibrary.simpleMessage("of the book"),
|
||||||
"playerSettingsRememberForEveryBook": MessageLookupByLibrary.simpleMessage(
|
"playerSettingsRememberForEveryBook":
|
||||||
"Remember Player Settings for Every Book",
|
MessageLookupByLibrary.simpleMessage(
|
||||||
),
|
"Remember Player Settings for Every Book",
|
||||||
"playerSettingsRememberForEveryBookDescription":
|
),
|
||||||
MessageLookupByLibrary.simpleMessage(
|
"playerSettingsRememberForEveryBookDescription":
|
||||||
|
MessageLookupByLibrary.simpleMessage(
|
||||||
"Settings like speed, loudness, etc. will be remembered for every book",
|
"Settings like speed, loudness, etc. will be remembered for every book",
|
||||||
),
|
),
|
||||||
"playerSettingsSpeedDefault": MessageLookupByLibrary.simpleMessage(
|
"playerSettingsSpeedDefault": MessageLookupByLibrary.simpleMessage(
|
||||||
"Default Speed",
|
"Default Speed",
|
||||||
),
|
),
|
||||||
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
|
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
|
||||||
"Speed Options",
|
"Speed Options",
|
||||||
),
|
),
|
||||||
"playlistsMine": MessageLookupByLibrary.simpleMessage("My Playlists"),
|
"playlistsMine": MessageLookupByLibrary.simpleMessage("My Playlists"),
|
||||||
"readLess": MessageLookupByLibrary.simpleMessage("Read Less"),
|
"readLess": MessageLookupByLibrary.simpleMessage("Read Less"),
|
||||||
"readMore": MessageLookupByLibrary.simpleMessage("Read More"),
|
"readMore": MessageLookupByLibrary.simpleMessage("Read More"),
|
||||||
"refresh": MessageLookupByLibrary.simpleMessage("Refresh"),
|
"refresh": MessageLookupByLibrary.simpleMessage("Refresh"),
|
||||||
"reset": MessageLookupByLibrary.simpleMessage("Reset"),
|
"reset": MessageLookupByLibrary.simpleMessage("Reset"),
|
||||||
"resetAppSettings": MessageLookupByLibrary.simpleMessage(
|
"resetAppSettings": MessageLookupByLibrary.simpleMessage(
|
||||||
"Reset App Settings",
|
"Reset App Settings",
|
||||||
),
|
),
|
||||||
"resetAppSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
"resetAppSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"Reset the app settings to the default values",
|
"Reset the app settings to the default values",
|
||||||
),
|
),
|
||||||
"resetAppSettingsDialog": MessageLookupByLibrary.simpleMessage(
|
"resetAppSettingsDialog": MessageLookupByLibrary.simpleMessage(
|
||||||
"Are you sure you want to reset the app settings?",
|
"Are you sure you want to reset the app settings?",
|
||||||
),
|
),
|
||||||
"restore": MessageLookupByLibrary.simpleMessage("Restore"),
|
"restore": MessageLookupByLibrary.simpleMessage("Restore"),
|
||||||
"restoreBackup": MessageLookupByLibrary.simpleMessage("Restore Backup"),
|
"restoreBackup": MessageLookupByLibrary.simpleMessage("Restore Backup"),
|
||||||
"restoreBackupHint": MessageLookupByLibrary.simpleMessage(
|
"restoreBackupHint": MessageLookupByLibrary.simpleMessage(
|
||||||
"Paste the backup here",
|
"Paste the backup here",
|
||||||
),
|
),
|
||||||
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage(
|
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage(
|
||||||
"Invalid backup",
|
"Invalid backup",
|
||||||
),
|
),
|
||||||
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage(
|
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage(
|
||||||
"Settings restored",
|
"Settings restored",
|
||||||
),
|
),
|
||||||
"restoreBackupValidator": MessageLookupByLibrary.simpleMessage(
|
"restoreBackupValidator": MessageLookupByLibrary.simpleMessage(
|
||||||
"Please paste the backup here",
|
"Please paste the backup here",
|
||||||
),
|
),
|
||||||
"restoreDescription": MessageLookupByLibrary.simpleMessage(
|
"restoreDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"Restore the app settings from the backup",
|
"Restore the app settings from the backup",
|
||||||
),
|
),
|
||||||
"resume": MessageLookupByLibrary.simpleMessage("Resume"),
|
"resume": MessageLookupByLibrary.simpleMessage("Resume"),
|
||||||
"retry": MessageLookupByLibrary.simpleMessage("Retry"),
|
"retry": MessageLookupByLibrary.simpleMessage("Retry"),
|
||||||
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
|
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
|
||||||
"shakeDetector": MessageLookupByLibrary.simpleMessage("Shake Detector"),
|
"shakeDetector": MessageLookupByLibrary.simpleMessage("Shake Detector"),
|
||||||
"shakeDetectorDescription": MessageLookupByLibrary.simpleMessage(
|
"shakeDetectorDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"Customize the shake detector settings",
|
"Customize the shake detector settings",
|
||||||
),
|
),
|
||||||
"themeSettings": MessageLookupByLibrary.simpleMessage("Theme Settings"),
|
"themeSettings": MessageLookupByLibrary.simpleMessage("Theme Settings"),
|
||||||
"themeSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
"themeSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"Customize the app theme",
|
"Customize the app theme",
|
||||||
),
|
),
|
||||||
"unknown": MessageLookupByLibrary.simpleMessage("Unknown"),
|
"unknown": MessageLookupByLibrary.simpleMessage("Unknown"),
|
||||||
"webVersion": MessageLookupByLibrary.simpleMessage("Web Version"),
|
"webVersion": MessageLookupByLibrary.simpleMessage("Web Version"),
|
||||||
"yes": MessageLookupByLibrary.simpleMessage("Yes"),
|
"yes": MessageLookupByLibrary.simpleMessage("Yes"),
|
||||||
"you": MessageLookupByLibrary.simpleMessage("You"),
|
"you": MessageLookupByLibrary.simpleMessage("You"),
|
||||||
"youTooltip": MessageLookupByLibrary.simpleMessage(
|
"youTooltip": MessageLookupByLibrary.simpleMessage(
|
||||||
"Your Profile and Settings",
|
"Your Profile and Settings",
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,135 +28,144 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
|
|
||||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
"account": MessageLookupByLibrary.simpleMessage("账户"),
|
"account": MessageLookupByLibrary.simpleMessage("账户"),
|
||||||
"accountSwitch": MessageLookupByLibrary.simpleMessage("切换账户"),
|
"accountSwitch": MessageLookupByLibrary.simpleMessage("切换账户"),
|
||||||
"appSettings": MessageLookupByLibrary.simpleMessage("应用设置"),
|
"appSettings": MessageLookupByLibrary.simpleMessage("应用设置"),
|
||||||
"appearance": MessageLookupByLibrary.simpleMessage("外观"),
|
"appearance": MessageLookupByLibrary.simpleMessage("外观"),
|
||||||
"autoTurnOnSleepTimer": MessageLookupByLibrary.simpleMessage("自动开启睡眠定时器"),
|
"autoTurnOnSleepTimer":
|
||||||
"automaticallyDescription": MessageLookupByLibrary.simpleMessage(
|
MessageLookupByLibrary.simpleMessage("自动开启睡眠定时器"),
|
||||||
"根据一天中的时间自动打开睡眠定时器",
|
"automaticallyDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
),
|
"根据一天中的时间自动打开睡眠定时器",
|
||||||
"backup": MessageLookupByLibrary.simpleMessage("备份"),
|
),
|
||||||
"backupAndRestore": MessageLookupByLibrary.simpleMessage("备份与恢复"),
|
"backup": MessageLookupByLibrary.simpleMessage("备份"),
|
||||||
"bookAbout": MessageLookupByLibrary.simpleMessage("关于本书"),
|
"backupAndRestore": MessageLookupByLibrary.simpleMessage("备份与恢复"),
|
||||||
"bookAboutDefault": MessageLookupByLibrary.simpleMessage("抱歉,找不到描述"),
|
"bookAbout": MessageLookupByLibrary.simpleMessage("关于本书"),
|
||||||
"bookAuthors": MessageLookupByLibrary.simpleMessage("作者"),
|
"bookAboutDefault": MessageLookupByLibrary.simpleMessage("抱歉,找不到描述"),
|
||||||
"bookDownloads": MessageLookupByLibrary.simpleMessage("下载"),
|
"bookAuthors": MessageLookupByLibrary.simpleMessage("作者"),
|
||||||
"bookGenres": MessageLookupByLibrary.simpleMessage("风格"),
|
"bookDownloads": MessageLookupByLibrary.simpleMessage("下载"),
|
||||||
"bookMetadataAbridged": MessageLookupByLibrary.simpleMessage("删节版"),
|
"bookGenres": MessageLookupByLibrary.simpleMessage("风格"),
|
||||||
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("持续时间"),
|
"bookMetadataAbridged": MessageLookupByLibrary.simpleMessage("删节版"),
|
||||||
"bookMetadataPublished": MessageLookupByLibrary.simpleMessage("发布年份"),
|
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("持续时间"),
|
||||||
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage("未删节版"),
|
"bookMetadataPublished": MessageLookupByLibrary.simpleMessage("发布年份"),
|
||||||
"bookSeries": MessageLookupByLibrary.simpleMessage("系列"),
|
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage("未删节版"),
|
||||||
"bookShelveEmpty": MessageLookupByLibrary.simpleMessage("重试"),
|
"bookSeries": MessageLookupByLibrary.simpleMessage("系列"),
|
||||||
"bookShelveEmptyText": MessageLookupByLibrary.simpleMessage("未查询到书架"),
|
"bookShelveEmpty": MessageLookupByLibrary.simpleMessage("重试"),
|
||||||
"cancel": MessageLookupByLibrary.simpleMessage("取消"),
|
"bookShelveEmptyText": MessageLookupByLibrary.simpleMessage("未查询到书架"),
|
||||||
"copyToClipboard": MessageLookupByLibrary.simpleMessage("复制到剪贴板"),
|
"cancel": MessageLookupByLibrary.simpleMessage("取消"),
|
||||||
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
|
"copyToClipboard": MessageLookupByLibrary.simpleMessage("复制到剪贴板"),
|
||||||
"将应用程序设置复制到剪贴板",
|
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
),
|
"将应用程序设置复制到剪贴板",
|
||||||
"copyToClipboardToast": MessageLookupByLibrary.simpleMessage("设置已复制到剪贴板"),
|
),
|
||||||
"delete": MessageLookupByLibrary.simpleMessage("删除"),
|
"copyToClipboardToast":
|
||||||
"deleteDialog": m0,
|
MessageLookupByLibrary.simpleMessage("设置已复制到剪贴板"),
|
||||||
"deleted": m1,
|
"delete": MessageLookupByLibrary.simpleMessage("删除"),
|
||||||
"explore": MessageLookupByLibrary.simpleMessage("探索"),
|
"deleteDialog": m0,
|
||||||
"exploreHint": MessageLookupByLibrary.simpleMessage("搜索与探索..."),
|
"deleted": m1,
|
||||||
"exploreTooltip": MessageLookupByLibrary.simpleMessage("搜索和探索"),
|
"explore": MessageLookupByLibrary.simpleMessage("探索"),
|
||||||
"general": MessageLookupByLibrary.simpleMessage("通用"),
|
"exploreHint": MessageLookupByLibrary.simpleMessage("搜索与探索..."),
|
||||||
"help": MessageLookupByLibrary.simpleMessage("Help"),
|
"exploreTooltip": MessageLookupByLibrary.simpleMessage("搜索和探索"),
|
||||||
"home": MessageLookupByLibrary.simpleMessage("首页"),
|
"general": MessageLookupByLibrary.simpleMessage("通用"),
|
||||||
"homeBookContinueListening": MessageLookupByLibrary.simpleMessage("继续收听"),
|
"help": MessageLookupByLibrary.simpleMessage("Help"),
|
||||||
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage("继续系列"),
|
"home": MessageLookupByLibrary.simpleMessage("首页"),
|
||||||
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("发现"),
|
"homeBookContinueListening":
|
||||||
"homeBookListenAgain": MessageLookupByLibrary.simpleMessage("再听一遍"),
|
MessageLookupByLibrary.simpleMessage("继续收听"),
|
||||||
"homeBookNewestAuthors": MessageLookupByLibrary.simpleMessage("最新作者"),
|
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage("继续系列"),
|
||||||
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage("最近添加"),
|
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("发现"),
|
||||||
"homeBookRecommended": MessageLookupByLibrary.simpleMessage("推荐"),
|
"homeBookListenAgain": MessageLookupByLibrary.simpleMessage("再听一遍"),
|
||||||
"homeContinueListening": MessageLookupByLibrary.simpleMessage("继续收听"),
|
"homeBookNewestAuthors": MessageLookupByLibrary.simpleMessage("最新作者"),
|
||||||
"homeListenAgain": MessageLookupByLibrary.simpleMessage("再听一遍"),
|
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage("最近添加"),
|
||||||
"homePageSettings": MessageLookupByLibrary.simpleMessage("主页设置"),
|
"homeBookRecommended": MessageLookupByLibrary.simpleMessage("推荐"),
|
||||||
"homePageSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
"homeContinueListening": MessageLookupByLibrary.simpleMessage("继续收听"),
|
||||||
"自定义主页",
|
"homeListenAgain": MessageLookupByLibrary.simpleMessage("再听一遍"),
|
||||||
),
|
"homePageSettings": MessageLookupByLibrary.simpleMessage("主页设置"),
|
||||||
"homeStartListening": MessageLookupByLibrary.simpleMessage("开始收听"),
|
"homePageSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"language": MessageLookupByLibrary.simpleMessage("语言"),
|
"自定义主页",
|
||||||
"languageDescription": MessageLookupByLibrary.simpleMessage("语言切换"),
|
),
|
||||||
"library": MessageLookupByLibrary.simpleMessage("媒体库"),
|
"homeStartListening": MessageLookupByLibrary.simpleMessage("开始收听"),
|
||||||
"libraryChange": MessageLookupByLibrary.simpleMessage("更改媒体库"),
|
"language": MessageLookupByLibrary.simpleMessage("语言"),
|
||||||
"libraryEmpty": MessageLookupByLibrary.simpleMessage("没有可用的库。"),
|
"languageDescription": MessageLookupByLibrary.simpleMessage("语言切换"),
|
||||||
"libraryLoadError": m2,
|
"library": MessageLookupByLibrary.simpleMessage("媒体库"),
|
||||||
"librarySelect": MessageLookupByLibrary.simpleMessage("选择媒体库"),
|
"libraryChange": MessageLookupByLibrary.simpleMessage("更改媒体库"),
|
||||||
"librarySwitchTooltip": MessageLookupByLibrary.simpleMessage("切换媒体库"),
|
"libraryEmpty": MessageLookupByLibrary.simpleMessage("没有可用的库。"),
|
||||||
"libraryTooltip": MessageLookupByLibrary.simpleMessage("浏览您的媒体库"),
|
"libraryLoadError": m2,
|
||||||
"loading": MessageLookupByLibrary.simpleMessage("加载中..."),
|
"librarySelect": MessageLookupByLibrary.simpleMessage("选择媒体库"),
|
||||||
"logs": MessageLookupByLibrary.simpleMessage("日志"),
|
"librarySwitchTooltip": MessageLookupByLibrary.simpleMessage("切换媒体库"),
|
||||||
"no": MessageLookupByLibrary.simpleMessage("否"),
|
"libraryTooltip": MessageLookupByLibrary.simpleMessage("浏览您的媒体库"),
|
||||||
"notImplemented": MessageLookupByLibrary.simpleMessage("未实现"),
|
"loading": MessageLookupByLibrary.simpleMessage("加载中..."),
|
||||||
"notificationMediaPlayer": MessageLookupByLibrary.simpleMessage("通知媒体播放器"),
|
"logs": MessageLookupByLibrary.simpleMessage("日志"),
|
||||||
"notificationMediaPlayerDescription": MessageLookupByLibrary.simpleMessage(
|
"no": MessageLookupByLibrary.simpleMessage("否"),
|
||||||
"在通知中自定义媒体播放器",
|
"notImplemented": MessageLookupByLibrary.simpleMessage("未实现"),
|
||||||
),
|
"notificationMediaPlayer":
|
||||||
"ok": MessageLookupByLibrary.simpleMessage("确定"),
|
MessageLookupByLibrary.simpleMessage("通知媒体播放器"),
|
||||||
"pause": MessageLookupByLibrary.simpleMessage("暂停"),
|
"notificationMediaPlayerDescription":
|
||||||
"play": MessageLookupByLibrary.simpleMessage("播放"),
|
MessageLookupByLibrary.simpleMessage(
|
||||||
"playerSettings": MessageLookupByLibrary.simpleMessage("播放器设置"),
|
"在通知中自定义媒体播放器",
|
||||||
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
),
|
||||||
"自定义播放器设置",
|
"ok": MessageLookupByLibrary.simpleMessage("确定"),
|
||||||
),
|
"pause": MessageLookupByLibrary.simpleMessage("暂停"),
|
||||||
"playerSettingsPlaybackReporting": MessageLookupByLibrary.simpleMessage(
|
"play": MessageLookupByLibrary.simpleMessage("播放"),
|
||||||
"回放报告",
|
"playerSettings": MessageLookupByLibrary.simpleMessage("播放器设置"),
|
||||||
),
|
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"playerSettingsPlaybackReportingIgnore":
|
"自定义播放器设置",
|
||||||
MessageLookupByLibrary.simpleMessage("忽略播放位置小于"),
|
),
|
||||||
"playerSettingsPlaybackReportingMinimum":
|
"playerSettingsPlaybackReporting": MessageLookupByLibrary.simpleMessage(
|
||||||
MessageLookupByLibrary.simpleMessage("回放报告最小位置"),
|
"回放报告",
|
||||||
"playerSettingsPlaybackReportingMinimumDescriptionHead":
|
),
|
||||||
MessageLookupByLibrary.simpleMessage("不要报告本书前 "),
|
"playerSettingsPlaybackReportingIgnore":
|
||||||
"playerSettingsPlaybackReportingMinimumDescriptionTail":
|
MessageLookupByLibrary.simpleMessage("忽略播放位置小于"),
|
||||||
MessageLookupByLibrary.simpleMessage(" 的播放"),
|
"playerSettingsPlaybackReportingMinimum":
|
||||||
"playerSettingsRememberForEveryBook": MessageLookupByLibrary.simpleMessage(
|
MessageLookupByLibrary.simpleMessage("回放报告最小位置"),
|
||||||
"记住每本书的播放器设置",
|
"playerSettingsPlaybackReportingMinimumDescriptionHead":
|
||||||
),
|
MessageLookupByLibrary.simpleMessage("不要报告本书前 "),
|
||||||
"playerSettingsRememberForEveryBookDescription":
|
"playerSettingsPlaybackReportingMinimumDescriptionTail":
|
||||||
MessageLookupByLibrary.simpleMessage("每本书都会记住播放速度、音量等设置"),
|
MessageLookupByLibrary.simpleMessage(" 的播放"),
|
||||||
"playerSettingsSpeedDefault": MessageLookupByLibrary.simpleMessage(
|
"playerSettingsRememberForEveryBook":
|
||||||
"默认播放速度",
|
MessageLookupByLibrary.simpleMessage(
|
||||||
),
|
"记住每本书的播放器设置",
|
||||||
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
|
),
|
||||||
"播放速度选项",
|
"playerSettingsRememberForEveryBookDescription":
|
||||||
),
|
MessageLookupByLibrary.simpleMessage("每本书都会记住播放速度、音量等设置"),
|
||||||
"playlistsMine": MessageLookupByLibrary.simpleMessage("播放列表"),
|
"playerSettingsSpeedDefault": MessageLookupByLibrary.simpleMessage(
|
||||||
"readLess": MessageLookupByLibrary.simpleMessage("折叠"),
|
"默认播放速度",
|
||||||
"readMore": MessageLookupByLibrary.simpleMessage("展开"),
|
),
|
||||||
"refresh": MessageLookupByLibrary.simpleMessage("刷新"),
|
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
|
||||||
"reset": MessageLookupByLibrary.simpleMessage("重置"),
|
"播放速度选项",
|
||||||
"resetAppSettings": MessageLookupByLibrary.simpleMessage("重置应用程序设置"),
|
),
|
||||||
"resetAppSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
"playlistsMine": MessageLookupByLibrary.simpleMessage("播放列表"),
|
||||||
"将应用程序设置重置为默认值",
|
"readLess": MessageLookupByLibrary.simpleMessage("折叠"),
|
||||||
),
|
"readMore": MessageLookupByLibrary.simpleMessage("展开"),
|
||||||
"resetAppSettingsDialog": MessageLookupByLibrary.simpleMessage(
|
"refresh": MessageLookupByLibrary.simpleMessage("刷新"),
|
||||||
"您确定要重置应用程序设置吗?",
|
"reset": MessageLookupByLibrary.simpleMessage("重置"),
|
||||||
),
|
"resetAppSettings": MessageLookupByLibrary.simpleMessage("重置应用程序设置"),
|
||||||
"restore": MessageLookupByLibrary.simpleMessage("恢复"),
|
"resetAppSettingsDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"restoreBackup": MessageLookupByLibrary.simpleMessage("恢复备份"),
|
"将应用程序设置重置为默认值",
|
||||||
"restoreBackupHint": MessageLookupByLibrary.simpleMessage("将备份粘贴到此处"),
|
),
|
||||||
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage("无效备份"),
|
"resetAppSettingsDialog": MessageLookupByLibrary.simpleMessage(
|
||||||
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage("设置已恢复"),
|
"您确定要重置应用程序设置吗?",
|
||||||
"restoreBackupValidator": MessageLookupByLibrary.simpleMessage("请将备份粘贴到此处"),
|
),
|
||||||
"restoreDescription": MessageLookupByLibrary.simpleMessage("从备份中还原应用程序设置"),
|
"restore": MessageLookupByLibrary.simpleMessage("恢复"),
|
||||||
"resume": MessageLookupByLibrary.simpleMessage("继续"),
|
"restoreBackup": MessageLookupByLibrary.simpleMessage("恢复备份"),
|
||||||
"retry": MessageLookupByLibrary.simpleMessage("重试"),
|
"restoreBackupHint": MessageLookupByLibrary.simpleMessage("将备份粘贴到此处"),
|
||||||
"settings": MessageLookupByLibrary.simpleMessage("设置"),
|
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage("无效备份"),
|
||||||
"shakeDetector": MessageLookupByLibrary.simpleMessage("抖动检测器"),
|
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage("设置已恢复"),
|
||||||
"shakeDetectorDescription": MessageLookupByLibrary.simpleMessage(
|
"restoreBackupValidator":
|
||||||
"自定义抖动检测器设置",
|
MessageLookupByLibrary.simpleMessage("请将备份粘贴到此处"),
|
||||||
),
|
"restoreDescription":
|
||||||
"themeSettings": MessageLookupByLibrary.simpleMessage("主题设置"),
|
MessageLookupByLibrary.simpleMessage("从备份中还原应用程序设置"),
|
||||||
"themeSettingsDescription": MessageLookupByLibrary.simpleMessage("自定义应用主题"),
|
"resume": MessageLookupByLibrary.simpleMessage("继续"),
|
||||||
"unknown": MessageLookupByLibrary.simpleMessage("未知"),
|
"retry": MessageLookupByLibrary.simpleMessage("重试"),
|
||||||
"webVersion": MessageLookupByLibrary.simpleMessage("Web版本"),
|
"settings": MessageLookupByLibrary.simpleMessage("设置"),
|
||||||
"yes": MessageLookupByLibrary.simpleMessage("是"),
|
"shakeDetector": MessageLookupByLibrary.simpleMessage("抖动检测器"),
|
||||||
"you": MessageLookupByLibrary.simpleMessage("我的"),
|
"shakeDetectorDescription": MessageLookupByLibrary.simpleMessage(
|
||||||
"youTooltip": MessageLookupByLibrary.simpleMessage("您的个人资料和设置"),
|
"自定义抖动检测器设置",
|
||||||
};
|
),
|
||||||
|
"themeSettings": MessageLookupByLibrary.simpleMessage("主题设置"),
|
||||||
|
"themeSettingsDescription":
|
||||||
|
MessageLookupByLibrary.simpleMessage("自定义应用主题"),
|
||||||
|
"unknown": MessageLookupByLibrary.simpleMessage("未知"),
|
||||||
|
"webVersion": MessageLookupByLibrary.simpleMessage("Web版本"),
|
||||||
|
"yes": MessageLookupByLibrary.simpleMessage("是"),
|
||||||
|
"you": MessageLookupByLibrary.simpleMessage("我的"),
|
||||||
|
"youTooltip": MessageLookupByLibrary.simpleMessage("您的个人资料和设置"),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@ class MyApp extends ConsumerWidget {
|
||||||
ColorScheme lightColorScheme = brandLightColorScheme;
|
ColorScheme lightColorScheme = brandLightColorScheme;
|
||||||
ColorScheme darkColorScheme = brandDarkColorScheme;
|
ColorScheme darkColorScheme = brandDarkColorScheme;
|
||||||
|
|
||||||
final shouldUseHighContrast = themeSettings.highContrast || MediaQuery.of(context).highContrast;
|
final shouldUseHighContrast =
|
||||||
|
themeSettings.highContrast || MediaQuery.of(context).highContrast;
|
||||||
|
|
||||||
if (shouldUseHighContrast) {
|
if (shouldUseHighContrast) {
|
||||||
lightColorScheme = lightColorScheme.copyWith(
|
lightColorScheme = lightColorScheme.copyWith(
|
||||||
|
|
@ -78,7 +79,8 @@ class MyApp extends ConsumerWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (themeSettings.useMaterialThemeFromSystem) {
|
if (themeSettings.useMaterialThemeFromSystem) {
|
||||||
var themes = ref.watch(systemThemeProvider(highContrast: shouldUseHighContrast));
|
var themes =
|
||||||
|
ref.watch(systemThemeProvider(highContrast: shouldUseHighContrast));
|
||||||
if (themes.valueOrNull != null) {
|
if (themes.valueOrNull != null) {
|
||||||
lightColorScheme = themes.valueOrNull!.$1;
|
lightColorScheme = themes.valueOrNull!.$1;
|
||||||
darkColorScheme = themes.valueOrNull!.$2;
|
darkColorScheme = themes.valueOrNull!.$2;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import 'package:vaani/generated/l10n.dart';
|
||||||
import 'package:vaani/main.dart';
|
import 'package:vaani/main.dart';
|
||||||
import 'package:vaani/router/router.dart';
|
import 'package:vaani/router/router.dart';
|
||||||
import 'package:vaani/settings/api_settings_provider.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 'package:vaani/settings/constants.dart';
|
||||||
|
|
||||||
import '../shared/widgets/shelves/home_shelf.dart';
|
import '../shared/widgets/shelves/home_shelf.dart';
|
||||||
|
|
@ -72,9 +73,12 @@ class HomePage extends HookConsumerWidget {
|
||||||
// check if showPlayButton is enabled for the shelf
|
// check if showPlayButton is enabled for the shelf
|
||||||
// using the id of the shelf
|
// using the id of the shelf
|
||||||
final showPlayButton = switch (shelf.id) {
|
final showPlayButton = switch (shelf.id) {
|
||||||
'continue-listening' => homePageSettings.showPlayButtonOnContinueListeningShelf,
|
'continue-listening' =>
|
||||||
'continue-series' => homePageSettings.showPlayButtonOnContinueSeriesShelf,
|
homePageSettings.showPlayButtonOnContinueListeningShelf,
|
||||||
'listen-again' => homePageSettings.showPlayButtonOnListenAgainShelf,
|
'continue-series' =>
|
||||||
|
homePageSettings.showPlayButtonOnContinueSeriesShelf,
|
||||||
|
'listen-again' =>
|
||||||
|
homePageSettings.showPlayButtonOnListenAgainShelf,
|
||||||
_ => homePageSettings.showPlayButtonOnAllRemainingShelves,
|
_ => homePageSettings.showPlayButtonOnAllRemainingShelves,
|
||||||
};
|
};
|
||||||
final showLabel = switch (shelf.label) {
|
final showLabel = switch (shelf.label) {
|
||||||
|
|
@ -111,7 +115,8 @@ class HomePage extends HookConsumerWidget {
|
||||||
},
|
},
|
||||||
loading: () => const HomePageSkeleton(),
|
loading: () => const HomePageSkeleton(),
|
||||||
error: (error, stack) {
|
error: (error, stack) {
|
||||||
if (apiSettings.activeUser == null || apiSettings.activeServer == null) {
|
if (apiSettings.activeUser == null ||
|
||||||
|
apiSettings.activeServer == null) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ import 'transitions/slide.dart';
|
||||||
|
|
||||||
part 'constants.dart';
|
part 'constants.dart';
|
||||||
|
|
||||||
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'root');
|
final GlobalKey<NavigatorState> rootNavigatorKey =
|
||||||
|
GlobalKey<NavigatorState>(debugLabel: 'root');
|
||||||
final GlobalKey<NavigatorState> sectionHomeNavigatorKey =
|
final GlobalKey<NavigatorState> sectionHomeNavigatorKey =
|
||||||
GlobalKey<NavigatorState>(debugLabel: 'HomeNavigator');
|
GlobalKey<NavigatorState>(debugLabel: 'HomeNavigator');
|
||||||
|
|
||||||
|
|
@ -93,8 +94,10 @@ class MyAppRouter {
|
||||||
// itemId: itemId, extra: state.extra);
|
// itemId: itemId, extra: state.extra);
|
||||||
// },
|
// },
|
||||||
pageBuilder: (context, state) {
|
pageBuilder: (context, state) {
|
||||||
final itemId = state.pathParameters[Routes.libraryItem.pathParamName]!;
|
final itemId = state
|
||||||
final child = LibraryItemPage(itemId: itemId, extra: state.extra);
|
.pathParameters[Routes.libraryItem.pathParamName]!;
|
||||||
|
final child =
|
||||||
|
LibraryItemPage(itemId: itemId, extra: state.extra);
|
||||||
return buildPageWithDefaultTransition(
|
return buildPageWithDefaultTransition(
|
||||||
context: context,
|
context: context,
|
||||||
state: state,
|
state: state,
|
||||||
|
|
@ -201,7 +204,8 @@ class MyAppRouter {
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: Routes.playerSettings.pathName,
|
path: Routes.playerSettings.pathName,
|
||||||
name: Routes.playerSettings.name,
|
name: Routes.playerSettings.name,
|
||||||
pageBuilder: defaultPageBuilder(const PlayerSettingsPage()),
|
pageBuilder:
|
||||||
|
defaultPageBuilder(const PlayerSettingsPage()),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: Routes.shakeDetectorSettings.pathName,
|
path: Routes.shakeDetectorSettings.pathName,
|
||||||
|
|
@ -249,7 +253,8 @@ class MyAppRouter {
|
||||||
final stateParam = state.uri.queryParameters['state'];
|
final stateParam = state.uri.queryParameters['state'];
|
||||||
appLogger.fine('deep linking callback: code: $code, state: $stateParam');
|
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(
|
return buildPageWithDefaultTransition(
|
||||||
context: context,
|
context: context,
|
||||||
state: state,
|
state: state,
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,8 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
|
||||||
// extended: false,
|
// extended: false,
|
||||||
destinations: _navigationItems(context).map((item) {
|
destinations: _navigationItems(context).map((item) {
|
||||||
final isDestinationLibrary = item.name == S.of(context).library;
|
final isDestinationLibrary = item.name == S.of(context).library;
|
||||||
var currentLibrary = ref.watch(currentLibraryProvider).valueOrNull;
|
var currentLibrary =
|
||||||
|
ref.watch(currentLibraryProvider).valueOrNull;
|
||||||
final libraryIcon = AbsIcons.getIconByName(
|
final libraryIcon = AbsIcons.getIconByName(
|
||||||
currentLibrary?.icon,
|
currentLibrary?.icon,
|
||||||
);
|
);
|
||||||
|
|
@ -125,9 +126,13 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
|
||||||
isDestinationLibrary ? libraryIcon ?? item.icon : item.icon,
|
isDestinationLibrary ? libraryIcon ?? item.icon : item.icon,
|
||||||
),
|
),
|
||||||
selectedIcon: 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,
|
// tooltip: item.tooltip,
|
||||||
);
|
);
|
||||||
// if (isDestinationLibrary) {
|
// if (isDestinationLibrary) {
|
||||||
|
|
@ -166,8 +171,8 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
|
||||||
// useValueListenable(ref.watch(playerExpandProgressNotifierProvider));
|
// useValueListenable(ref.watch(playerExpandProgressNotifierProvider));
|
||||||
final playerProgress = ref.watch(playerHeightProvider);
|
final playerProgress = ref.watch(playerHeightProvider);
|
||||||
final playerMaxHeight = MediaQuery.of(context).size.height;
|
final playerMaxHeight = MediaQuery.of(context).size.height;
|
||||||
var percentExpandedMiniPlayer =
|
var percentExpandedMiniPlayer = (playerProgress - playerMinHeight) /
|
||||||
(playerProgress - playerMinHeight) / (playerMaxHeight - playerMinHeight);
|
(playerMaxHeight - playerMinHeight);
|
||||||
// Clamp the value between 0 and 1
|
// Clamp the value between 0 and 1
|
||||||
percentExpandedMiniPlayer = percentExpandedMiniPlayer.clamp(0.0, 1.0);
|
percentExpandedMiniPlayer = percentExpandedMiniPlayer.clamp(0.0, 1.0);
|
||||||
return Opacity(
|
return Opacity(
|
||||||
|
|
@ -193,9 +198,13 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
|
||||||
isDestinationLibrary ? libraryIcon ?? item.icon : item.icon,
|
isDestinationLibrary ? libraryIcon ?? item.icon : item.icon,
|
||||||
),
|
),
|
||||||
selectedIcon: 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,
|
tooltip: item.tooltip,
|
||||||
);
|
);
|
||||||
if (isDestinationLibrary) {
|
if (isDestinationLibrary) {
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,13 @@ class AppSettings with _$AppSettings {
|
||||||
@Default(SleepTimerSettings()) SleepTimerSettings sleepTimerSettings,
|
@Default(SleepTimerSettings()) SleepTimerSettings sleepTimerSettings,
|
||||||
@Default(DownloadSettings()) DownloadSettings downloadSettings,
|
@Default(DownloadSettings()) DownloadSettings downloadSettings,
|
||||||
@Default(NotificationSettings()) NotificationSettings notificationSettings,
|
@Default(NotificationSettings()) NotificationSettings notificationSettings,
|
||||||
@Default(ShakeDetectionSettings()) ShakeDetectionSettings shakeDetectionSettings,
|
@Default(ShakeDetectionSettings())
|
||||||
|
ShakeDetectionSettings shakeDetectionSettings,
|
||||||
@Default(HomePageSettings()) HomePageSettings homePageSettings,
|
@Default(HomePageSettings()) HomePageSettings homePageSettings,
|
||||||
}) = _AppSettings;
|
}) = _AppSettings;
|
||||||
|
|
||||||
factory AppSettings.fromJson(Map<String, dynamic> json) => _$AppSettingsFromJson(json);
|
factory AppSettings.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AppSettingsFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
|
@ -36,14 +38,17 @@ class ThemeSettings with _$ThemeSettings {
|
||||||
@Default(true) bool useCurrentPlayerThemeThroughoutApp,
|
@Default(true) bool useCurrentPlayerThemeThroughoutApp,
|
||||||
}) = _ThemeSettings;
|
}) = _ThemeSettings;
|
||||||
|
|
||||||
factory ThemeSettings.fromJson(Map<String, dynamic> json) => _$ThemeSettingsFromJson(json);
|
factory ThemeSettings.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$ThemeSettingsFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class PlayerSettings with _$PlayerSettings {
|
class PlayerSettings with _$PlayerSettings {
|
||||||
const factory PlayerSettings({
|
const factory PlayerSettings({
|
||||||
@Default(MinimizedPlayerSettings()) MinimizedPlayerSettings miniPlayerSettings,
|
@Default(MinimizedPlayerSettings())
|
||||||
@Default(ExpandedPlayerSettings()) ExpandedPlayerSettings expandedPlayerSettings,
|
MinimizedPlayerSettings miniPlayerSettings,
|
||||||
|
@Default(ExpandedPlayerSettings())
|
||||||
|
ExpandedPlayerSettings expandedPlayerSettings,
|
||||||
@Default(1) double preferredDefaultVolume,
|
@Default(1) double preferredDefaultVolume,
|
||||||
@Default(1) double preferredDefaultSpeed,
|
@Default(1) double preferredDefaultSpeed,
|
||||||
@Default([1, 1.25, 1.5, 1.75, 2]) List<double> speedOptions,
|
@Default([1, 1.25, 1.5, 1.75, 2]) List<double> speedOptions,
|
||||||
|
|
@ -56,7 +61,8 @@ class PlayerSettings with _$PlayerSettings {
|
||||||
@Default(true) bool configurePlayerForEveryBook,
|
@Default(true) bool configurePlayerForEveryBook,
|
||||||
}) = _PlayerSettings;
|
}) = _PlayerSettings;
|
||||||
|
|
||||||
factory PlayerSettings.fromJson(Map<String, dynamic> json) => _$PlayerSettingsFromJson(json);
|
factory PlayerSettings.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$PlayerSettingsFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
|
@ -139,7 +145,8 @@ class DownloadSettings with _$DownloadSettings {
|
||||||
@Default(3) int maxConcurrentByGroup,
|
@Default(3) int maxConcurrentByGroup,
|
||||||
}) = _DownloadSettings;
|
}) = _DownloadSettings;
|
||||||
|
|
||||||
factory DownloadSettings.fromJson(Map<String, dynamic> json) => _$DownloadSettingsFromJson(json);
|
factory DownloadSettings.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$DownloadSettingsFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
|
@ -196,7 +203,8 @@ class ShakeDetectionSettings with _$ShakeDetectionSettings {
|
||||||
@Default(ShakeDirection.horizontal) ShakeDirection direction,
|
@Default(ShakeDirection.horizontal) ShakeDirection direction,
|
||||||
@Default(5) double threshold,
|
@Default(5) double threshold,
|
||||||
@Default(ShakeAction.resetSleepTimer) ShakeAction shakeAction,
|
@Default(ShakeAction.resetSleepTimer) ShakeAction shakeAction,
|
||||||
@Default({ShakeDetectedFeedback.vibrate}) Set<ShakeDetectedFeedback> feedback,
|
@Default({ShakeDetectedFeedback.vibrate})
|
||||||
|
Set<ShakeDetectedFeedback> feedback,
|
||||||
@Default(0.5) double beepVolume,
|
@Default(0.5) double beepVolume,
|
||||||
|
|
||||||
/// the duration to wait before the shake detection is enabled again
|
/// the duration to wait before the shake detection is enabled again
|
||||||
|
|
@ -234,5 +242,6 @@ class HomePageSettings with _$HomePageSettings {
|
||||||
@Default(false) bool showPlayButtonOnListenAgainShelf,
|
@Default(false) bool showPlayButtonOnListenAgainShelf,
|
||||||
}) = _HomePageSettings;
|
}) = _HomePageSettings;
|
||||||
|
|
||||||
factory HomePageSettings.fromJson(Map<String, dynamic> json) => _$HomePageSettingsFromJson(json);
|
factory HomePageSettings.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$HomePageSettingsFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,8 @@ class AppSettingsPage extends HookConsumerWidget {
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title: Text(S.of(context).notificationMediaPlayer),
|
title: Text(S.of(context).notificationMediaPlayer),
|
||||||
leading: const Icon(Icons.play_lesson),
|
leading: const Icon(Icons.play_lesson),
|
||||||
description: Text(S.of(context).notificationMediaPlayerDescription),
|
description:
|
||||||
|
Text(S.of(context).notificationMediaPlayerDescription),
|
||||||
onPressed: (context) {
|
onPressed: (context) {
|
||||||
context.pushNamed(Routes.notificationSettings.name);
|
context.pushNamed(Routes.notificationSettings.name);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
||||||
title: Text(S.of(context).playerSettingsSpeedDefault),
|
title: Text(S.of(context).playerSettingsSpeedDefault),
|
||||||
trailing: Text(
|
trailing: Text(
|
||||||
'${playerSettings.preferredDefaultSpeed}x',
|
'${playerSettings.preferredDefaultSpeed}x',
|
||||||
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
|
style:
|
||||||
|
TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
leading: const Icon(Icons.speed),
|
leading: const Icon(Icons.speed),
|
||||||
onPressed: (context) async {
|
onPressed: (context) async {
|
||||||
|
|
@ -75,7 +76,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
||||||
title: Text(S.of(context).playerSettingsSpeedOptions),
|
title: Text(S.of(context).playerSettingsSpeedOptions),
|
||||||
description: Text(
|
description: Text(
|
||||||
playerSettings.speedOptions.map((e) => '${e}x').join(', '),
|
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),
|
leading: const Icon(Icons.speed),
|
||||||
onPressed: (context) async {
|
onPressed: (context) async {
|
||||||
|
|
@ -105,17 +107,22 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
||||||
title: Text(S.of(context).playerSettingsPlaybackReportingMinimum),
|
title: Text(S.of(context).playerSettingsPlaybackReportingMinimum),
|
||||||
description: Text.rich(
|
description: Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: S.of(context).playerSettingsPlaybackReportingMinimumDescriptionHead,
|
text: S
|
||||||
|
.of(context)
|
||||||
|
.playerSettingsPlaybackReportingMinimumDescriptionHead,
|
||||||
children: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: playerSettings.minimumPositionForReporting.smartBinaryFormat,
|
text: playerSettings
|
||||||
|
.minimumPositionForReporting.smartBinaryFormat,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: S.of(context).playerSettingsPlaybackReportingMinimumDescriptionTail),
|
text: S
|
||||||
|
.of(context)
|
||||||
|
.playerSettingsPlaybackReportingMinimumDescriptionTail),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -125,7 +132,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return TimeDurationSelector(
|
return TimeDurationSelector(
|
||||||
title: Text(S.of(context).playerSettingsPlaybackReportingIgnore),
|
title: Text(
|
||||||
|
S.of(context).playerSettingsPlaybackReportingIgnore),
|
||||||
baseUnit: BaseUnit.second,
|
baseUnit: BaseUnit.second,
|
||||||
initialValue: playerSettings.minimumPositionForReporting,
|
initialValue: playerSettings.minimumPositionForReporting,
|
||||||
);
|
);
|
||||||
|
|
@ -148,7 +156,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
||||||
text: 'Mark complete when less than ',
|
text: 'Mark complete when less than ',
|
||||||
children: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: playerSettings.markCompleteWhenTimeLeft.smartBinaryFormat,
|
text: playerSettings
|
||||||
|
.markCompleteWhenTimeLeft.smartBinaryFormat,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
|
|
@ -187,7 +196,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
||||||
text: 'Report progress every ',
|
text: 'Report progress every ',
|
||||||
children: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: playerSettings.playbackReportInterval.smartBinaryFormat,
|
text: playerSettings
|
||||||
|
.playbackReportInterval.smartBinaryFormat,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
|
|
@ -231,7 +241,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
||||||
description: const Text(
|
description: const Text(
|
||||||
'Show the total progress of the book in the player',
|
'Show the total progress of the book in the player',
|
||||||
),
|
),
|
||||||
initialValue: playerSettings.expandedPlayerSettings.showTotalProgress,
|
initialValue:
|
||||||
|
playerSettings.expandedPlayerSettings.showTotalProgress,
|
||||||
onToggle: (value) {
|
onToggle: (value) {
|
||||||
ref.read(appSettingsProvider.notifier).update(
|
ref.read(appSettingsProvider.notifier).update(
|
||||||
appSettings.copyWith.playerSettings
|
appSettings.copyWith.playerSettings
|
||||||
|
|
@ -246,11 +257,13 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
||||||
description: const Text(
|
description: const Text(
|
||||||
'Show the progress of the current chapter in the player',
|
'Show the progress of the current chapter in the player',
|
||||||
),
|
),
|
||||||
initialValue: playerSettings.expandedPlayerSettings.showChapterProgress,
|
initialValue:
|
||||||
|
playerSettings.expandedPlayerSettings.showChapterProgress,
|
||||||
onToggle: (value) {
|
onToggle: (value) {
|
||||||
ref.read(appSettingsProvider.notifier).update(
|
ref.read(appSettingsProvider.notifier).update(
|
||||||
appSettings.copyWith.playerSettings(
|
appSettings.copyWith.playerSettings(
|
||||||
expandedPlayerSettings: playerSettings.expandedPlayerSettings
|
expandedPlayerSettings: playerSettings
|
||||||
|
.expandedPlayerSettings
|
||||||
.copyWith(showChapterProgress: value),
|
.copyWith(showChapterProgress: value),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -309,7 +322,8 @@ class SpeedPicker extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final speedController = useTextEditingController(text: initialValue.toString());
|
final speedController =
|
||||||
|
useTextEditingController(text: initialValue.toString());
|
||||||
final speed = useState<double?>(initialValue);
|
final speed = useState<double?>(initialValue);
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('Select Speed'),
|
title: const Text('Select Speed'),
|
||||||
|
|
@ -368,7 +382,8 @@ class SpeedOptionsPicker extends HookConsumerWidget {
|
||||||
onDeleted: speed == 1
|
onDeleted: speed == 1
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
speedOptions.value = speedOptions.value.where((element) {
|
speedOptions.value =
|
||||||
|
speedOptions.value.where((element) {
|
||||||
// speed option 1 can't be removed
|
// speed option 1 can't be removed
|
||||||
return element != speed;
|
return element != speed;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,8 @@ class BookOnShelf extends HookConsumerWidget {
|
||||||
onTap: handleTapOnBook,
|
onTap: handleTapOnBook,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
child: Padding(
|
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(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -111,7 +112,9 @@ class BookOnShelf extends HookConsumerWidget {
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
children: [
|
children: [
|
||||||
Hero(
|
Hero(
|
||||||
tag: HeroTagPrefixes.bookCover + item.id + heroTagSuffix,
|
tag: HeroTagPrefixes.bookCover +
|
||||||
|
item.id +
|
||||||
|
heroTagSuffix,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
child: AnimatedSwitcher(
|
child: AnimatedSwitcher(
|
||||||
|
|
@ -125,13 +128,17 @@ class BookOnShelf extends HookConsumerWidget {
|
||||||
var imageWidget = Image.memory(
|
var imageWidget = Image.memory(
|
||||||
image,
|
image,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
cacheWidth:
|
cacheWidth: (height *
|
||||||
(height * 1.2 * MediaQuery.of(context).devicePixelRatio)
|
1.2 *
|
||||||
.round(),
|
MediaQuery.of(context)
|
||||||
|
.devicePixelRatio)
|
||||||
|
.round(),
|
||||||
);
|
);
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onPrimaryContainer,
|
||||||
),
|
),
|
||||||
child: imageWidget,
|
child: imageWidget,
|
||||||
);
|
);
|
||||||
|
|
@ -206,7 +213,8 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final me = ref.watch(meProvider);
|
final me = ref.watch(meProvider);
|
||||||
final player = ref.watch(audiobookPlayerProvider);
|
final player = ref.watch(audiobookPlayerProvider);
|
||||||
final isCurrentBookSetInPlayer = player.book?.libraryItemId == libraryItemId;
|
final isCurrentBookSetInPlayer =
|
||||||
|
player.book?.libraryItemId == libraryItemId;
|
||||||
final isPlayingThisBook = player.playing && isCurrentBookSetInPlayer;
|
final isPlayingThisBook = player.playing && isCurrentBookSetInPlayer;
|
||||||
|
|
||||||
final userProgress = me.valueOrNull?.mediaProgress
|
final userProgress = me.valueOrNull?.mediaProgress
|
||||||
|
|
@ -234,7 +242,8 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
|
||||||
return Theme(
|
return Theme(
|
||||||
// if current book is set in player, get theme from the cover image
|
// if current book is set in player, get theme from the cover image
|
||||||
data: ThemeData(
|
data: ThemeData(
|
||||||
colorScheme: coverColorScheme.valueOrNull ?? Theme.of(context).colorScheme,
|
colorScheme:
|
||||||
|
coverColorScheme.valueOrNull ?? Theme.of(context).colorScheme,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(strokeWidth / 2 + 2),
|
padding: EdgeInsets.all(strokeWidth / 2 + 2),
|
||||||
|
|
@ -249,7 +258,10 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
|
||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
value: userProgress.progress,
|
value: userProgress.progress,
|
||||||
strokeWidth: strokeWidth,
|
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>(
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
Theme.of(context).colorScheme.primary,
|
Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
|
|
@ -267,11 +279,15 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
|
||||||
const Size(size, size),
|
const Size(size, size),
|
||||||
),
|
),
|
||||||
backgroundColor: WidgetStateProperty.all(
|
backgroundColor: WidgetStateProperty.all(
|
||||||
Theme.of(context).colorScheme.onPrimary.withValues(alpha: 0.9),
|
Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onPrimary
|
||||||
|
.withValues(alpha: 0.9),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final book = await ref.watch(libraryItemProvider(libraryItemId).future);
|
final book =
|
||||||
|
await ref.watch(libraryItemProvider(libraryItemId).future);
|
||||||
|
|
||||||
libraryItemPlayButtonOnPressed(
|
libraryItemPlayButtonOnPressed(
|
||||||
ref: ref,
|
ref: ref,
|
||||||
|
|
@ -308,8 +324,10 @@ class BookCoverSkeleton extends StatelessWidget {
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 150,
|
width: 150,
|
||||||
child: Shimmer.fromColors(
|
child: Shimmer.fromColors(
|
||||||
baseColor: Theme.of(context).colorScheme.surface.withValues(alpha: 0.3),
|
baseColor:
|
||||||
highlightColor: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.1),
|
Theme.of(context).colorScheme.surface.withValues(alpha: 0.3),
|
||||||
|
highlightColor:
|
||||||
|
Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.1),
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue