fix: 增加排序

This commit is contained in:
rang 2026-01-09 17:58:36 +08:00
parent eef72c6aa6
commit 03cec3f4b6
13 changed files with 1151 additions and 925 deletions

View file

@ -63,8 +63,8 @@ class LibraryItemsState {
final List<LibraryItem> items; final List<LibraryItem> items;
final int limit; final int limit;
final int page; final int page;
final String? sort; final String sort;
final bool? desc; final bool desc;
final bool isLoading; final bool isLoading;
final bool isRefreshing; final bool isRefreshing;
final bool hasMore; final bool hasMore;
@ -75,8 +75,8 @@ class LibraryItemsState {
this.items = const [], this.items = const [],
this.limit = 18, this.limit = 18,
this.page = 0, this.page = 0,
this.sort, this.sort = 'media.metadata.title',
this.desc, this.desc = false,
this.isLoading = false, this.isLoading = false,
this.isRefreshing = false, this.isRefreshing = false,
this.hasMore = false, this.hasMore = false,
@ -111,6 +111,26 @@ class LibraryItemsState {
} }
factory LibraryItemsState.initial() => const LibraryItemsState(); factory LibraryItemsState.initial() => const LibraryItemsState();
final sortMap = const {
'media.metadata.title': '标题',
'media.metadata.authorName': '作者(姓,名)',
'media.metadata.authorNameLF': '作者(名,姓)',
'media.metadata.publishedYear': '发布年份',
'addedAt': '添加于',
'size': '文件大小',
'media.duration': '持续时间',
'birthtimeMs': '文件创建时间',
'mtimeMs': '文件修改时间',
'progress': '进度更新时间',
'progress.createdAt': '开始日期',
'progress.finishedAt': '完成日期',
'random': '随机',
};
List<String> get sortList => sortMap.keys.toList();
String sortDisplay(String sort) {
return sortMap[sort] ?? 'unknown';
}
} }
@riverpod @riverpod
@ -208,6 +228,11 @@ class LibraryItems extends _$LibraryItems {
} }
return []; return [];
} }
void update(LibraryItemsState record) {
state = record;
refresh();
}
} }
// //

View file

@ -188,7 +188,7 @@ final librariesProvider =
); );
typedef _$Libraries = AutoDisposeAsyncNotifier<List<Library>>; typedef _$Libraries = AutoDisposeAsyncNotifier<List<Library>>;
String _$libraryItemsHash() => r'2927603eca709f7444a5d2ab5595dedc8596de78'; String _$libraryItemsHash() => r'402fb8d5dbbd83e77d0f3637068018a052cb7021';
/// See also [LibraryItems]. /// See also [LibraryItems].
@ProviderFor(LibraryItems) @ProviderFor(LibraryItems)

View file

@ -3,6 +3,10 @@ class HeroTagPrefixes {
/// The hero tag for the book cover /// The hero tag for the book cover
static const String bookCover = 'book_cover_'; static const String bookCover = 'book_cover_';
static String bookCoverWith(String? id) {
return bookCover + (id ?? '');
}
static const String bookCoverSkeleton = 'book_cover_skeleton_'; static const String bookCoverSkeleton = 'book_cover_skeleton_';
static const String authorAvatar = 'author_avatar_'; static const String authorAvatar = 'author_avatar_';
static const String authorAvatarSkeleton = 'author_avatar_skeleton_'; static const String authorAvatarSkeleton = 'author_avatar_skeleton_';
@ -10,4 +14,8 @@ class HeroTagPrefixes {
static const String bookTitle = 'book_title_'; static const String bookTitle = 'book_title_';
static const String narratorName = 'narrator_name_'; static const String narratorName = 'narrator_name_';
static const String libraryItemPlayButton = 'library_item_play_button_'; static const String libraryItemPlayButton = 'library_item_play_button_';
/// (Desktop)
static const String controlsCenter = 'player_controls_desktop_center';
static const String controlsRight = 'player_controls_desktop_right';
} }

View file

@ -2,6 +2,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/constants/hero_tag_conventions.dart';
import 'package:vaani/constants/sizes.dart'; import 'package:vaani/constants/sizes.dart';
import 'package:vaani/features/player/providers/abs_provider.dart'; import 'package:vaani/features/player/providers/abs_provider.dart';
import 'package:vaani/features/player/view/widgets/player_player_pause_button.dart'; import 'package:vaani/features/player/view/widgets/player_player_pause_button.dart';
@ -52,7 +53,10 @@ class PlayerExpanded extends HookConsumerWidget {
child: Align( child: Align(
alignment: Alignment.center, alignment: Alignment.center,
// add a shadow to the image elevation hovering effect // add a shadow to the image elevation hovering effect
child: PlayerExpandedImage(imageSize), child: PlayerExpandedImage(
imageSize,
itemId: currentBook.libraryItemId,
),
), ),
), ),
@ -169,8 +173,9 @@ class PlayerExpanded extends HookConsumerWidget {
class PlayerExpandedImage extends StatelessWidget { class PlayerExpandedImage extends StatelessWidget {
final double imageSize; final double imageSize;
final String? itemId;
const PlayerExpandedImage(this.imageSize, {super.key}); const PlayerExpandedImage(this.imageSize, {super.key, this.itemId});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@ -183,16 +188,11 @@ class PlayerExpandedImage extends StatelessWidget {
), ),
], ],
), ),
child: SizedBox(
height: imageSize,
child: InkWell( child: InkWell(
onTap: () {}, onTap: () {},
child: ClipRRect( child: Hero(
borderRadius: BorderRadius.circular( tag: HeroTagPrefixes.bookCoverWith(itemId),
AppElementSizes.borderRadiusRegular, child: BookCoverWidget(imageSize, itemId: itemId),
),
child: BookCoverWidget(),
),
), ),
), ),
); );

View file

@ -5,19 +5,15 @@ 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:shelfsdk/audiobookshelf_api.dart'; import 'package:shelfsdk/audiobookshelf_api.dart';
import 'package:vaani/constants/hero_tag_conventions.dart';
import 'package:vaani/constants/sizes.dart'; import 'package:vaani/constants/sizes.dart';
import 'package:vaani/features/item_viewer/view/library_item_hero_section.dart'; import 'package:vaani/features/item_viewer/view/library_item_hero_section.dart';
import 'package:vaani/features/player/providers/abs_provider.dart'; import 'package:vaani/features/player/providers/abs_provider.dart';
import 'package:vaani/features/player/view/player_expanded.dart' import 'package:vaani/features/player/view/player_expanded.dart'
show PlayerExpandedImage; show PlayerExpandedImage;
import 'package:vaani/features/player/view/widgets/audiobook_player_seek_button.dart'; import 'package:vaani/features/player/view/player_minimized.dart';
import 'package:vaani/features/player/view/widgets/audiobook_player_seek_chapter_button.dart';
import 'package:vaani/features/player/view/widgets/chapter_selection_button.dart'; import 'package:vaani/features/player/view/widgets/chapter_selection_button.dart';
import 'package:vaani/features/player/view/widgets/player_player_pause_button.dart';
import 'package:vaani/features/player/view/widgets/player_progress_bar.dart'; import 'package:vaani/features/player/view/widgets/player_progress_bar.dart';
import 'package:vaani/features/player/view/widgets/player_speed_adjust_button.dart';
import 'package:vaani/features/skip_start_end/view/skip_start_end_button.dart';
import 'package:vaani/features/sleep_timer/view/sleep_timer_button.dart';
import 'package:vaani/globals.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/shared/extensions/model_conversions.dart'; import 'package:vaani/shared/extensions/model_conversions.dart';
@ -30,9 +26,8 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
// final textTheme = Theme.of(context).textTheme; final currentBook = ref.watch(currentBookProvider);
final book = ref.watch(currentBookProvider); if (currentBook == null) {
if (book == null) {
return SizedBox.shrink(); return SizedBox.shrink();
} }
@ -45,7 +40,7 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
final availWidth = MediaQuery.of(context).size.width; final availWidth = MediaQuery.of(context).size.width;
// the image width when the player is expanded // the image width when the player is expanded
final imageSize = min(playerMaxHeight * 0.5, availWidth * 0.9); final imageSize = min(playerMaxHeight * 0.5, availWidth * 0.9);
final itemBookMetadata = book.metadata.asBookMetadataExpanded; final itemBookMetadata = currentBook.metadata.asBookMetadataExpanded;
return Stack( return Stack(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
children: [ children: [
@ -65,7 +60,10 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
Align( Align(
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
// add a shadow to the image elevation hovering effect // add a shadow to the image elevation hovering effect
child: PlayerExpandedImage(imageSize), child: PlayerExpandedImage(
imageSize,
itemId: currentBook.libraryItemId,
),
), ),
_buildBookDetails(imageSize, itemBookMetadata), _buildBookDetails(imageSize, itemBookMetadata),
], ],
@ -118,7 +116,9 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
timeLabelLocation: TimeLabelLocation.sides, timeLabelLocation: TimeLabelLocation.sides,
), ),
), ),
MouseRegion( SizedBox(
height: playerMinHeight,
child: MouseRegion(
cursor: SystemMouseCursors.click, // cursor: SystemMouseCursors.click, //
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
@ -128,6 +128,7 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
child: _buildBottom(), child: _buildBottom(),
), ),
), ),
),
], ],
), ),
], ],
@ -143,27 +144,16 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
child: Row(), child: Row(),
), ),
Expanded( Expanded(
child: Row( child: Hero(
mainAxisAlignment: MainAxisAlignment.center, tag: HeroTagPrefixes.controlsCenter,
children: [ child: const PlayerControlsDesktopCenter(),
const AudiobookPlayerSeekChapterButton(isForward: false),
const AudiobookPlayerSeekButton(isForward: false),
// play/pause button
const AudiobookPlayerPlayPauseButton(),
const AudiobookPlayerSeekButton(isForward: true),
const AudiobookPlayerSeekChapterButton(isForward: true),
],
), ),
), ),
Expanded( Expanded(
flex: 1, flex: 1,
child: Row( child: Hero(
mainAxisAlignment: MainAxisAlignment.end, tag: HeroTagPrefixes.controlsRight,
children: [ child: const PlayerControlsDesktopRight(),
const PlayerSpeedAdjustButton(),
const SleepTimerButton(),
SkipChapterStartEndButton(),
],
), ),
), ),
], ],
@ -171,7 +161,9 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
} }
Widget _buildBookDetails( Widget _buildBookDetails(
double width, BookMetadataExpanded? itemBookMetadata) { double width,
BookMetadataExpanded? itemBookMetadata,
) {
return Container( return Container(
padding: EdgeInsets.all(AppElementSizes.paddingLarge), padding: EdgeInsets.all(AppElementSizes.paddingLarge),
width: width, width: width,

View file

@ -2,10 +2,15 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.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/constants/hero_tag_conventions.dart';
import 'package:vaani/constants/sizes.dart'; import 'package:vaani/constants/sizes.dart';
import 'package:vaani/features/player/providers/abs_provider.dart'; import 'package:vaani/features/player/providers/abs_provider.dart';
import 'package:vaani/features/player/view/widgets/audiobook_player_seek_button.dart';
import 'package:vaani/features/player/view/widgets/audiobook_player_seek_chapter_button.dart'; import 'package:vaani/features/player/view/widgets/audiobook_player_seek_chapter_button.dart';
import 'package:vaani/features/player/view/widgets/player_player_pause_button.dart'; import 'package:vaani/features/player/view/widgets/player_player_pause_button.dart';
import 'package:vaani/features/player/view/widgets/player_speed_adjust_button.dart';
import 'package:vaani/features/skip_start_end/view/skip_start_end_button.dart';
import 'package:vaani/features/sleep_timer/view/sleep_timer_button.dart';
import 'package:vaani/globals.dart'; import 'package:vaani/globals.dart';
import 'package:vaani/router/router.dart'; import 'package:vaani/router/router.dart';
import 'package:vaani/shared/extensions/chapter.dart'; import 'package:vaani/shared/extensions/chapter.dart';
@ -75,11 +80,12 @@ class PlayerMinimizedControls extends HookConsumerWidget {
); );
} }
}, },
child: ConstrainedBox( child: Hero(
constraints: BoxConstraints( tag: HeroTagPrefixes.bookCoverWith(currentBook?.libraryItemId),
maxWidth: playerMinHeight, child: BookCoverWidget(
playerMinHeight,
itemId: currentBook?.libraryItemId,
), ),
child: BookCoverWidget(),
), ),
), ),
), ),
@ -181,6 +187,9 @@ class PlayerMinimizedControlsDesktop extends HookConsumerWidget {
context.pop(); context.pop();
} }
}, },
child: Row(
children: [
Expanded(
child: Row( child: Row(
children: [ children: [
// image // image
@ -199,11 +208,13 @@ class PlayerMinimizedControlsDesktop extends HookConsumerWidget {
); );
} }
}, },
child: ConstrainedBox( child: Hero(
constraints: BoxConstraints( tag: HeroTagPrefixes.bookCoverWith(
maxWidth: playerMinHeight, currentBook?.libraryItemId),
child: BookCoverWidget(
playerMinHeight,
itemId: currentBook?.libraryItemId,
), ),
child: BookCoverWidget(),
), ),
), ),
), ),
@ -220,18 +231,24 @@ class PlayerMinimizedControlsDesktop extends HookConsumerWidget {
children: [ children: [
// AutoScrollText( // AutoScrollText(
Text( Text(
'${currentBook?.metadata.title ?? ''} - ${currentChapter?.title ?? ''}', currentChapter?.title ??
currentBook?.metadata.title ??
'',
maxLines: 1, overflow: TextOverflow.ellipsis, maxLines: 1, overflow: TextOverflow.ellipsis,
// velocity: // velocity:
// const Velocity(pixelsPerSecond: Offset(16, 0)), // const Velocity(pixelsPerSecond: Offset(16, 0)),
style: Theme.of(context).textTheme.bodyLarge, style: Theme.of(context).textTheme.bodyLarge,
), ),
Text( Text(
currentBook?.metadata.asBookMetadataExpanded.authorName ?? currentBook?.metadata.asBookMetadataExpanded
.authorName ??
'', '',
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) color: Theme.of(context)
.colorScheme .colorScheme
.onSurface .onSurface
@ -242,20 +259,60 @@ class PlayerMinimizedControlsDesktop extends HookConsumerWidget {
), ),
), ),
), ),
SizedBox(
width: 180,
child: Row(
children: [
const AudiobookPlayerSeekChapterButton(isForward: false),
// play/pause button
const AudiobookPlayerPlayPauseButton(),
const AudiobookPlayerSeekChapterButton(isForward: true),
], ],
), ),
), ),
Expanded(
child: Hero(
tag: HeroTagPrefixes.controlsCenter,
child: const PlayerControlsDesktopCenter(),
),
),
Expanded(
flex: 1,
child: Hero(
tag: HeroTagPrefixes.controlsRight,
child: const PlayerControlsDesktopRight(),
),
),
], ],
), ),
), ),
); );
} }
} }
class PlayerControlsDesktopCenter extends StatelessWidget {
const PlayerControlsDesktopCenter({super.key});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const AudiobookPlayerSeekChapterButton(isForward: false),
const AudiobookPlayerSeekButton(isForward: false),
// play/pause button
const AudiobookPlayerPlayPauseButton(),
const AudiobookPlayerSeekButton(isForward: true),
const AudiobookPlayerSeekChapterButton(isForward: true),
],
);
}
}
class PlayerControlsDesktopRight extends StatelessWidget {
const PlayerControlsDesktopRight({super.key});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const PlayerSpeedAdjustButton(),
const SleepTimerButton(),
const SkipChapterStartEndButton(),
],
);
}
}

View file

@ -25,7 +25,7 @@ class SleepTimerButton extends HookConsumerWidget {
// if the sleep timer is active, show the remaining time in a pill shaped container // if the sleep timer is active, show the remaining time in a pill shaped container
return Tooltip( return Tooltip(
message: 'Sleep Timer', message: 'Sleep Timer',
child: InkWell( child: GestureDetector(
onTap: () async { onTap: () async {
appLogger.fine('Sleep Timer button pressed'); appLogger.fine('Sleep Timer button pressed');
pendingPlayerModals++; pendingPlayerModals++;

View file

@ -54,8 +54,10 @@ class MessageLookup extends MessageLookupByLibrary {
"accountDeleteServer": MessageLookupByLibrary.simpleMessage( "accountDeleteServer": MessageLookupByLibrary.simpleMessage(
"Delete Server", "Delete Server",
), ),
"accountInvalidURL": MessageLookupByLibrary.simpleMessage("Invalid URL"), "accountInvalidURL":
"accountManage": MessageLookupByLibrary.simpleMessage("Manage Accounts"), MessageLookupByLibrary.simpleMessage("Invalid URL"),
"accountManage":
MessageLookupByLibrary.simpleMessage("Manage Accounts"),
"accountRegisteredServers": MessageLookupByLibrary.simpleMessage( "accountRegisteredServers": MessageLookupByLibrary.simpleMessage(
"Registered Servers", "Registered Servers",
), ),
@ -94,7 +96,8 @@ class MessageLookup extends MessageLookupByLibrary {
"autoTurnOnTimerAlways": MessageLookupByLibrary.simpleMessage( "autoTurnOnTimerAlways": MessageLookupByLibrary.simpleMessage(
"Always Auto Turn On Timer", "Always Auto Turn On Timer",
), ),
"autoTurnOnTimerAlwaysDescription": MessageLookupByLibrary.simpleMessage( "autoTurnOnTimerAlwaysDescription":
MessageLookupByLibrary.simpleMessage(
"Always turn on the sleep timer, no matter what", "Always turn on the sleep timer, no matter what",
), ),
"autoTurnOnTimerDescription": MessageLookupByLibrary.simpleMessage( "autoTurnOnTimerDescription": MessageLookupByLibrary.simpleMessage(
@ -122,9 +125,11 @@ class MessageLookup extends MessageLookupByLibrary {
"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":
MessageLookupByLibrary.simpleMessage("Abridged"),
"bookMetadataLength": MessageLookupByLibrary.simpleMessage("Length"), "bookMetadataLength": MessageLookupByLibrary.simpleMessage("Length"),
"bookMetadataPublished": MessageLookupByLibrary.simpleMessage("Published"), "bookMetadataPublished":
MessageLookupByLibrary.simpleMessage("Published"),
"bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage( "bookMetadataUnabridged": MessageLookupByLibrary.simpleMessage(
"Unabridged", "Unabridged",
), ),
@ -168,10 +173,12 @@ class MessageLookup extends MessageLookupByLibrary {
"erDragText": MessageLookupByLibrary.simpleMessage("Pull to refresh"), "erDragText": MessageLookupByLibrary.simpleMessage("Pull to refresh"),
"erDragTextUp": MessageLookupByLibrary.simpleMessage("Pull to refresh"), "erDragTextUp": MessageLookupByLibrary.simpleMessage("Pull to refresh"),
"erFailedText": MessageLookupByLibrary.simpleMessage("Failed"), "erFailedText": MessageLookupByLibrary.simpleMessage("Failed"),
"erMessageText": MessageLookupByLibrary.simpleMessage("Last updated at %T"), "erMessageText":
MessageLookupByLibrary.simpleMessage("Last updated at %T"),
"erNoMoreText": MessageLookupByLibrary.simpleMessage("No more"), "erNoMoreText": MessageLookupByLibrary.simpleMessage("No more"),
"erProcessedText": MessageLookupByLibrary.simpleMessage("Succeeded"), "erProcessedText": MessageLookupByLibrary.simpleMessage("Succeeded"),
"erProcessingText": MessageLookupByLibrary.simpleMessage("Refreshing..."), "erProcessingText":
MessageLookupByLibrary.simpleMessage("Refreshing..."),
"erReadyText": MessageLookupByLibrary.simpleMessage("Refreshing..."), "erReadyText": MessageLookupByLibrary.simpleMessage("Refreshing..."),
"explore": MessageLookupByLibrary.simpleMessage("explore"), "explore": MessageLookupByLibrary.simpleMessage("explore"),
"exploreHint": MessageLookupByLibrary.simpleMessage( "exploreHint": MessageLookupByLibrary.simpleMessage(
@ -193,11 +200,13 @@ class MessageLookup extends MessageLookupByLibrary {
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage( "homeBookContinueSeries": MessageLookupByLibrary.simpleMessage(
"Continue Series", "Continue Series",
), ),
"homeBookContinueSeriesDescription": MessageLookupByLibrary.simpleMessage( "homeBookContinueSeriesDescription":
MessageLookupByLibrary.simpleMessage(
"Show play button for books in continue series shelf", "Show play button for books in continue series shelf",
), ),
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("Discover"), "homeBookDiscover": MessageLookupByLibrary.simpleMessage("Discover"),
"homeBookListenAgain": MessageLookupByLibrary.simpleMessage("Listen Again"), "homeBookListenAgain":
MessageLookupByLibrary.simpleMessage("Listen Again"),
"homeBookListenAgainDescription": MessageLookupByLibrary.simpleMessage( "homeBookListenAgainDescription": MessageLookupByLibrary.simpleMessage(
"Show play button for all books in listen again shelf", "Show play button for all books in listen again shelf",
), ),
@ -207,7 +216,8 @@ class MessageLookup extends MessageLookupByLibrary {
"homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage( "homeBookRecentlyAdded": MessageLookupByLibrary.simpleMessage(
"Recently Added", "Recently Added",
), ),
"homeBookRecommended": MessageLookupByLibrary.simpleMessage("Recommended"), "homeBookRecommended":
MessageLookupByLibrary.simpleMessage("Recommended"),
"homeContinueListening": MessageLookupByLibrary.simpleMessage( "homeContinueListening": MessageLookupByLibrary.simpleMessage(
"Continue Listening", "Continue Listening",
), ),
@ -280,7 +290,8 @@ class MessageLookup extends MessageLookupByLibrary {
"nmpSettingsMediaControls": MessageLookupByLibrary.simpleMessage( "nmpSettingsMediaControls": MessageLookupByLibrary.simpleMessage(
"Media Controls", "Media Controls",
), ),
"nmpSettingsMediaControlsDescription": MessageLookupByLibrary.simpleMessage( "nmpSettingsMediaControlsDescription":
MessageLookupByLibrary.simpleMessage(
"Select the media controls to display", "Select the media controls to display",
), ),
"nmpSettingsSelectOne": MessageLookupByLibrary.simpleMessage( "nmpSettingsSelectOne": MessageLookupByLibrary.simpleMessage(
@ -299,27 +310,32 @@ class MessageLookup extends MessageLookupByLibrary {
"nmpSettingsSubTitleDescription": MessageLookupByLibrary.simpleMessage( "nmpSettingsSubTitleDescription": MessageLookupByLibrary.simpleMessage(
"The subtitle of the notification\n", "The subtitle of the notification\n",
), ),
"nmpSettingsTitle": MessageLookupByLibrary.simpleMessage("Primary Title"), "nmpSettingsTitle":
MessageLookupByLibrary.simpleMessage("Primary Title"),
"nmpSettingsTitleDescription": MessageLookupByLibrary.simpleMessage( "nmpSettingsTitleDescription": MessageLookupByLibrary.simpleMessage(
"The title of the notification\n", "The title of the notification\n",
), ),
"no": MessageLookupByLibrary.simpleMessage("No"), "no": MessageLookupByLibrary.simpleMessage("No"),
"notImplemented": MessageLookupByLibrary.simpleMessage("Not implemented"), "notImplemented":
MessageLookupByLibrary.simpleMessage("Not implemented"),
"notificationMediaPlayer": MessageLookupByLibrary.simpleMessage( "notificationMediaPlayer": MessageLookupByLibrary.simpleMessage(
"Notification Media Player", "Notification Media Player",
), ),
"notificationMediaPlayerDescription": MessageLookupByLibrary.simpleMessage( "notificationMediaPlayerDescription":
MessageLookupByLibrary.simpleMessage(
"Customize the media player in notifications", "Customize the media player in notifications",
), ),
"ok": MessageLookupByLibrary.simpleMessage("OK"), "ok": MessageLookupByLibrary.simpleMessage("OK"),
"pause": MessageLookupByLibrary.simpleMessage("Pause"), "pause": MessageLookupByLibrary.simpleMessage("Pause"),
"play": MessageLookupByLibrary.simpleMessage("Play"), "play": MessageLookupByLibrary.simpleMessage("Play"),
"playerSettings": MessageLookupByLibrary.simpleMessage("Player Settings"), "playerSettings":
MessageLookupByLibrary.simpleMessage("Player Settings"),
"playerSettingsCompleteTime": MessageLookupByLibrary.simpleMessage( "playerSettingsCompleteTime": MessageLookupByLibrary.simpleMessage(
"Mark Complete When Time Left", "Mark Complete When Time Left",
), ),
"playerSettingsCompleteTimeDescriptionHead": "playerSettingsCompleteTimeDescriptionHead":
MessageLookupByLibrary.simpleMessage("Mark complete when less than "), MessageLookupByLibrary.simpleMessage(
"Mark complete when less than "),
"playerSettingsCompleteTimeDescriptionTail": "playerSettingsCompleteTimeDescriptionTail":
MessageLookupByLibrary.simpleMessage(" left in the book"), MessageLookupByLibrary.simpleMessage(" left in the book"),
"playerSettingsDescription": MessageLookupByLibrary.simpleMessage( "playerSettingsDescription": MessageLookupByLibrary.simpleMessage(
@ -334,7 +350,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage(
"Show the progress of the current chapter in the player", "Show the progress of the current chapter in the player",
), ),
"playerSettingsDisplayTotalProgress": MessageLookupByLibrary.simpleMessage( "playerSettingsDisplayTotalProgress":
MessageLookupByLibrary.simpleMessage(
"Show Total Progress", "Show Total Progress",
), ),
"playerSettingsDisplayTotalProgressDescription": "playerSettingsDisplayTotalProgressDescription":
@ -363,7 +380,8 @@ class MessageLookup extends MessageLookupByLibrary {
), ),
"playerSettingsPlaybackReportingMinimumDescriptionTail": "playerSettingsPlaybackReportingMinimumDescriptionTail":
MessageLookupByLibrary.simpleMessage("of the book"), MessageLookupByLibrary.simpleMessage("of the book"),
"playerSettingsRememberForEveryBook": MessageLookupByLibrary.simpleMessage( "playerSettingsRememberForEveryBook":
MessageLookupByLibrary.simpleMessage(
"Remember Player Settings for Every Book", "Remember Player Settings for Every Book",
), ),
"playerSettingsRememberForEveryBookDescription": "playerSettingsRememberForEveryBookDescription":
@ -377,14 +395,17 @@ class MessageLookup extends MessageLookupByLibrary {
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage( "playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
"Speed Options", "Speed Options",
), ),
"playerSettingsSpeedOptionsSelect": MessageLookupByLibrary.simpleMessage( "playerSettingsSpeedOptionsSelect":
MessageLookupByLibrary.simpleMessage(
"Select Speed Options", "Select Speed Options",
), ),
"playerSettingsSpeedOptionsSelectAdd": MessageLookupByLibrary.simpleMessage( "playerSettingsSpeedOptionsSelectAdd":
MessageLookupByLibrary.simpleMessage(
"Add Speed Option", "Add Speed Option",
), ),
"playerSettingsSpeedOptionsSelectAddHelper": "playerSettingsSpeedOptionsSelectAddHelper":
MessageLookupByLibrary.simpleMessage("Enter a new speed option to add"), MessageLookupByLibrary.simpleMessage(
"Enter a new speed option to add"),
"playerSettingsSpeedSelect": MessageLookupByLibrary.simpleMessage( "playerSettingsSpeedSelect": MessageLookupByLibrary.simpleMessage(
"Select Speed", "Select Speed",
), ),
@ -432,7 +453,8 @@ class MessageLookup extends MessageLookupByLibrary {
"shakeActivationThreshold": MessageLookupByLibrary.simpleMessage( "shakeActivationThreshold": MessageLookupByLibrary.simpleMessage(
"Shake Activation Threshold", "Shake Activation Threshold",
), ),
"shakeActivationThresholdDescription": MessageLookupByLibrary.simpleMessage( "shakeActivationThresholdDescription":
MessageLookupByLibrary.simpleMessage(
"The higher the threshold, the harder you need to shake", "The higher the threshold, the harder you need to shake",
), ),
"shakeDetector": MessageLookupByLibrary.simpleMessage("Shake Detector"), "shakeDetector": MessageLookupByLibrary.simpleMessage("Shake Detector"),
@ -470,7 +492,8 @@ class MessageLookup extends MessageLookupByLibrary {
"themeModeHighContrast": MessageLookupByLibrary.simpleMessage( "themeModeHighContrast": MessageLookupByLibrary.simpleMessage(
"High Contrast Mode", "High Contrast Mode",
), ),
"themeModeHighContrastDescription": MessageLookupByLibrary.simpleMessage( "themeModeHighContrastDescription":
MessageLookupByLibrary.simpleMessage(
"Increase the contrast between the background and the text", "Increase the contrast between the background and the text",
), ),
"themeModeLight": MessageLookupByLibrary.simpleMessage("Light"), "themeModeLight": MessageLookupByLibrary.simpleMessage("Light"),
@ -485,7 +508,8 @@ class MessageLookup extends MessageLookupByLibrary {
"themeSettingsColorsBook": MessageLookupByLibrary.simpleMessage( "themeSettingsColorsBook": MessageLookupByLibrary.simpleMessage(
"Adaptive Theme on Item Page", "Adaptive Theme on Item Page",
), ),
"themeSettingsColorsBookDescription": MessageLookupByLibrary.simpleMessage( "themeSettingsColorsBookDescription":
MessageLookupByLibrary.simpleMessage(
"Get fancy with the colors on the item page at the cost of some performance", "Get fancy with the colors on the item page at the cost of some performance",
), ),
"themeSettingsColorsCurrent": MessageLookupByLibrary.simpleMessage( "themeSettingsColorsCurrent": MessageLookupByLibrary.simpleMessage(

View file

@ -50,7 +50,8 @@ class MessageLookup extends MessageLookupByLibrary {
"accountDeleteServer": MessageLookupByLibrary.simpleMessage("删除服务器"), "accountDeleteServer": MessageLookupByLibrary.simpleMessage("删除服务器"),
"accountInvalidURL": MessageLookupByLibrary.simpleMessage("无效网址"), "accountInvalidURL": MessageLookupByLibrary.simpleMessage("无效网址"),
"accountManage": MessageLookupByLibrary.simpleMessage("帐户管理"), "accountManage": MessageLookupByLibrary.simpleMessage("帐户管理"),
"accountRegisteredServers": MessageLookupByLibrary.simpleMessage("已注册服务器"), "accountRegisteredServers":
MessageLookupByLibrary.simpleMessage("已注册服务器"),
"accountRemoveServerAndUsers": MessageLookupByLibrary.simpleMessage( "accountRemoveServerAndUsers": MessageLookupByLibrary.simpleMessage(
"删除服务器和用户", "删除服务器和用户",
), ),
@ -60,7 +61,8 @@ class MessageLookup extends MessageLookupByLibrary {
"accountRemoveServerAndUsersTail": MessageLookupByLibrary.simpleMessage( "accountRemoveServerAndUsersTail": MessageLookupByLibrary.simpleMessage(
" 以及该应用程序中所有用户的登录信息。", " 以及该应用程序中所有用户的登录信息。",
), ),
"accountRemoveUserLogin": MessageLookupByLibrary.simpleMessage("删除用户登录"), "accountRemoveUserLogin":
MessageLookupByLibrary.simpleMessage("删除用户登录"),
"accountRemoveUserLoginHead": MessageLookupByLibrary.simpleMessage( "accountRemoveUserLoginHead": MessageLookupByLibrary.simpleMessage(
"这将删除用户 ", "这将删除用户 ",
), ),
@ -72,11 +74,15 @@ class MessageLookup extends MessageLookupByLibrary {
"accountUsersCount": m1, "accountUsersCount": m1,
"appSettings": MessageLookupByLibrary.simpleMessage("应用设置"), "appSettings": MessageLookupByLibrary.simpleMessage("应用设置"),
"appearance": MessageLookupByLibrary.simpleMessage("外观"), "appearance": MessageLookupByLibrary.simpleMessage("外观"),
"autoSleepTimerSettings": MessageLookupByLibrary.simpleMessage("自动睡眠定时器设置"), "autoSleepTimerSettings":
"autoTurnOnSleepTimer": MessageLookupByLibrary.simpleMessage("自动开启睡眠定时器"), MessageLookupByLibrary.simpleMessage("自动睡眠定时器设置"),
"autoTurnOnSleepTimer":
MessageLookupByLibrary.simpleMessage("自动开启睡眠定时器"),
"autoTurnOnTimer": MessageLookupByLibrary.simpleMessage("自动开启定时器"), "autoTurnOnTimer": MessageLookupByLibrary.simpleMessage("自动开启定时器"),
"autoTurnOnTimerAlways": MessageLookupByLibrary.simpleMessage("始终自动开启定时器"), "autoTurnOnTimerAlways":
"autoTurnOnTimerAlwaysDescription": MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage("始终自动开启定时器"),
"autoTurnOnTimerAlwaysDescription":
MessageLookupByLibrary.simpleMessage(
"总是打开睡眠定时器", "总是打开睡眠定时器",
), ),
"autoTurnOnTimerDescription": MessageLookupByLibrary.simpleMessage( "autoTurnOnTimerDescription": MessageLookupByLibrary.simpleMessage(
@ -118,7 +124,8 @@ class MessageLookup extends MessageLookupByLibrary {
"copyToClipboardDescription": MessageLookupByLibrary.simpleMessage( "copyToClipboardDescription": MessageLookupByLibrary.simpleMessage(
"将应用程序设置复制到剪贴板", "将应用程序设置复制到剪贴板",
), ),
"copyToClipboardToast": MessageLookupByLibrary.simpleMessage("设置已复制到剪贴板"), "copyToClipboardToast":
MessageLookupByLibrary.simpleMessage("设置已复制到剪贴板"),
"delete": MessageLookupByLibrary.simpleMessage("删除"), "delete": MessageLookupByLibrary.simpleMessage("删除"),
"deleteDialog": m2, "deleteDialog": m2,
"deleted": m3, "deleted": m3,
@ -141,11 +148,13 @@ class MessageLookup extends MessageLookupByLibrary {
"general": MessageLookupByLibrary.simpleMessage("通用"), "general": MessageLookupByLibrary.simpleMessage("通用"),
"help": MessageLookupByLibrary.simpleMessage("Help"), "help": MessageLookupByLibrary.simpleMessage("Help"),
"home": MessageLookupByLibrary.simpleMessage("首页"), "home": MessageLookupByLibrary.simpleMessage("首页"),
"homeBookContinueListening": MessageLookupByLibrary.simpleMessage("继续收听"), "homeBookContinueListening":
MessageLookupByLibrary.simpleMessage("继续收听"),
"homeBookContinueListeningDescription": "homeBookContinueListeningDescription":
MessageLookupByLibrary.simpleMessage("继续收听书架上显示播放按钮"), MessageLookupByLibrary.simpleMessage("继续收听书架上显示播放按钮"),
"homeBookContinueSeries": MessageLookupByLibrary.simpleMessage("继续系列"), "homeBookContinueSeries": MessageLookupByLibrary.simpleMessage("继续系列"),
"homeBookContinueSeriesDescription": MessageLookupByLibrary.simpleMessage( "homeBookContinueSeriesDescription":
MessageLookupByLibrary.simpleMessage(
"继续系列书架上显示播放按钮", "继续系列书架上显示播放按钮",
), ),
"homeBookDiscover": MessageLookupByLibrary.simpleMessage("发现"), "homeBookDiscover": MessageLookupByLibrary.simpleMessage("发现"),
@ -167,7 +176,8 @@ class MessageLookup extends MessageLookupByLibrary {
), ),
"homePageSettingsOtherShelvesDescription": "homePageSettingsOtherShelvesDescription":
MessageLookupByLibrary.simpleMessage("显示所有剩余书架上所有书籍的播放按钮"), MessageLookupByLibrary.simpleMessage("显示所有剩余书架上所有书籍的播放按钮"),
"homePageSettingsQuickPlay": MessageLookupByLibrary.simpleMessage("继续播放"), "homePageSettingsQuickPlay":
MessageLookupByLibrary.simpleMessage("继续播放"),
"homeStartListening": MessageLookupByLibrary.simpleMessage("开始收听"), "homeStartListening": MessageLookupByLibrary.simpleMessage("开始收听"),
"language": MessageLookupByLibrary.simpleMessage("语言"), "language": MessageLookupByLibrary.simpleMessage("语言"),
"languageDescription": MessageLookupByLibrary.simpleMessage("语言切换"), "languageDescription": MessageLookupByLibrary.simpleMessage("语言切换"),
@ -184,7 +194,8 @@ class MessageLookup extends MessageLookupByLibrary {
"loginOpenID": MessageLookupByLibrary.simpleMessage("OpenID"), "loginOpenID": MessageLookupByLibrary.simpleMessage("OpenID"),
"loginPassword": MessageLookupByLibrary.simpleMessage("密码"), "loginPassword": MessageLookupByLibrary.simpleMessage("密码"),
"loginServerClick": MessageLookupByLibrary.simpleMessage("单击此处"), "loginServerClick": MessageLookupByLibrary.simpleMessage("单击此处"),
"loginServerConnected": MessageLookupByLibrary.simpleMessage("服务器已连接,请登录"), "loginServerConnected":
MessageLookupByLibrary.simpleMessage("服务器已连接,请登录"),
"loginServerNo": MessageLookupByLibrary.simpleMessage("没有服务器? "), "loginServerNo": MessageLookupByLibrary.simpleMessage("没有服务器? "),
"loginServerNoConnected": MessageLookupByLibrary.simpleMessage( "loginServerNoConnected": MessageLookupByLibrary.simpleMessage(
"请输入您的AudiobookShelf服务器的URL", "请输入您的AudiobookShelf服务器的URL",
@ -197,8 +208,10 @@ class MessageLookup extends MessageLookupByLibrary {
"logs": MessageLookupByLibrary.simpleMessage("日志"), "logs": MessageLookupByLibrary.simpleMessage("日志"),
"nmpSettingsBackward": MessageLookupByLibrary.simpleMessage("快退间隔"), "nmpSettingsBackward": MessageLookupByLibrary.simpleMessage("快退间隔"),
"nmpSettingsForward": MessageLookupByLibrary.simpleMessage("快进间隔"), "nmpSettingsForward": MessageLookupByLibrary.simpleMessage("快进间隔"),
"nmpSettingsMediaControls": MessageLookupByLibrary.simpleMessage("媒体控制"), "nmpSettingsMediaControls":
"nmpSettingsMediaControlsDescription": MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage("媒体控制"),
"nmpSettingsMediaControlsDescription":
MessageLookupByLibrary.simpleMessage(
"选择要显示的媒体控件", "选择要显示的媒体控件",
), ),
"nmpSettingsSelectOne": MessageLookupByLibrary.simpleMessage( "nmpSettingsSelectOne": MessageLookupByLibrary.simpleMessage(
@ -219,8 +232,10 @@ class MessageLookup extends MessageLookupByLibrary {
), ),
"no": MessageLookupByLibrary.simpleMessage(""), "no": MessageLookupByLibrary.simpleMessage(""),
"notImplemented": MessageLookupByLibrary.simpleMessage("未实现"), "notImplemented": MessageLookupByLibrary.simpleMessage("未实现"),
"notificationMediaPlayer": MessageLookupByLibrary.simpleMessage("通知媒体播放器"), "notificationMediaPlayer":
"notificationMediaPlayerDescription": MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage("通知媒体播放器"),
"notificationMediaPlayerDescription":
MessageLookupByLibrary.simpleMessage(
"在通知中自定义媒体播放器", "在通知中自定义媒体播放器",
), ),
"ok": MessageLookupByLibrary.simpleMessage("确定"), "ok": MessageLookupByLibrary.simpleMessage("确定"),
@ -242,7 +257,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("显示章节进度"), MessageLookupByLibrary.simpleMessage("显示章节进度"),
"playerSettingsDisplayChapterProgressDescription": "playerSettingsDisplayChapterProgressDescription":
MessageLookupByLibrary.simpleMessage("在播放器中显示当前章节的进度"), MessageLookupByLibrary.simpleMessage("在播放器中显示当前章节的进度"),
"playerSettingsDisplayTotalProgress": MessageLookupByLibrary.simpleMessage( "playerSettingsDisplayTotalProgress":
MessageLookupByLibrary.simpleMessage(
"显示总进度", "显示总进度",
), ),
"playerSettingsDisplayTotalProgressDescription": "playerSettingsDisplayTotalProgressDescription":
@ -265,7 +281,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("不要报告本书前 "), MessageLookupByLibrary.simpleMessage("不要报告本书前 "),
"playerSettingsPlaybackReportingMinimumDescriptionTail": "playerSettingsPlaybackReportingMinimumDescriptionTail":
MessageLookupByLibrary.simpleMessage(" 的播放"), MessageLookupByLibrary.simpleMessage(" 的播放"),
"playerSettingsRememberForEveryBook": MessageLookupByLibrary.simpleMessage( "playerSettingsRememberForEveryBook":
MessageLookupByLibrary.simpleMessage(
"记住每本书的播放器设置", "记住每本书的播放器设置",
), ),
"playerSettingsRememberForEveryBookDescription": "playerSettingsRememberForEveryBookDescription":
@ -277,15 +294,18 @@ class MessageLookup extends MessageLookupByLibrary {
"playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage( "playerSettingsSpeedOptions": MessageLookupByLibrary.simpleMessage(
"播放速度选项", "播放速度选项",
), ),
"playerSettingsSpeedOptionsSelect": MessageLookupByLibrary.simpleMessage( "playerSettingsSpeedOptionsSelect":
MessageLookupByLibrary.simpleMessage(
"播放速度选项", "播放速度选项",
), ),
"playerSettingsSpeedOptionsSelectAdd": MessageLookupByLibrary.simpleMessage( "playerSettingsSpeedOptionsSelectAdd":
MessageLookupByLibrary.simpleMessage(
"添加一个速度选项", "添加一个速度选项",
), ),
"playerSettingsSpeedOptionsSelectAddHelper": "playerSettingsSpeedOptionsSelectAddHelper":
MessageLookupByLibrary.simpleMessage("输入一个新的速度选项"), MessageLookupByLibrary.simpleMessage("输入一个新的速度选项"),
"playerSettingsSpeedSelect": MessageLookupByLibrary.simpleMessage("选择播放速度"), "playerSettingsSpeedSelect":
MessageLookupByLibrary.simpleMessage("选择播放速度"),
"playerSettingsSpeedSelectHelper": MessageLookupByLibrary.simpleMessage( "playerSettingsSpeedSelectHelper": MessageLookupByLibrary.simpleMessage(
"输入默认的播放速度", "输入默认的播放速度",
), ),
@ -306,8 +326,10 @@ class MessageLookup extends MessageLookupByLibrary {
"restoreBackupHint": MessageLookupByLibrary.simpleMessage("将备份粘贴到此处"), "restoreBackupHint": MessageLookupByLibrary.simpleMessage("将备份粘贴到此处"),
"restoreBackupInvalid": MessageLookupByLibrary.simpleMessage("无效备份"), "restoreBackupInvalid": MessageLookupByLibrary.simpleMessage("无效备份"),
"restoreBackupSuccess": MessageLookupByLibrary.simpleMessage("设置已恢复"), "restoreBackupSuccess": MessageLookupByLibrary.simpleMessage("设置已恢复"),
"restoreBackupValidator": MessageLookupByLibrary.simpleMessage("请将备份粘贴到此处"), "restoreBackupValidator":
"restoreDescription": MessageLookupByLibrary.simpleMessage("从备份中还原应用程序设置"), MessageLookupByLibrary.simpleMessage("请将备份粘贴到此处"),
"restoreDescription":
MessageLookupByLibrary.simpleMessage("从备份中还原应用程序设置"),
"resume": MessageLookupByLibrary.simpleMessage("继续"), "resume": MessageLookupByLibrary.simpleMessage("继续"),
"retry": MessageLookupByLibrary.simpleMessage("重试"), "retry": MessageLookupByLibrary.simpleMessage("重试"),
"settings": MessageLookupByLibrary.simpleMessage("设置"), "settings": MessageLookupByLibrary.simpleMessage("设置"),
@ -315,8 +337,10 @@ class MessageLookup extends MessageLookupByLibrary {
"shakeActionDescription": MessageLookupByLibrary.simpleMessage( "shakeActionDescription": MessageLookupByLibrary.simpleMessage(
"检测到抖动时要执行的操作", "检测到抖动时要执行的操作",
), ),
"shakeActivationThreshold": MessageLookupByLibrary.simpleMessage("抖动激活阈值"), "shakeActivationThreshold":
"shakeActivationThresholdDescription": MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage("抖动激活阈值"),
"shakeActivationThresholdDescription":
MessageLookupByLibrary.simpleMessage(
"门槛越高,你就越难摇晃", "门槛越高,你就越难摇晃",
), ),
"shakeDetector": MessageLookupByLibrary.simpleMessage("抖动检测器"), "shakeDetector": MessageLookupByLibrary.simpleMessage("抖动检测器"),
@ -327,7 +351,8 @@ class MessageLookup extends MessageLookupByLibrary {
"shakeDetectorEnableDescription": MessageLookupByLibrary.simpleMessage( "shakeDetectorEnableDescription": MessageLookupByLibrary.simpleMessage(
"启用抖动检测以执行各种操作", "启用抖动检测以执行各种操作",
), ),
"shakeDetectorSettings": MessageLookupByLibrary.simpleMessage("抖动检测器设置"), "shakeDetectorSettings":
MessageLookupByLibrary.simpleMessage("抖动检测器设置"),
"shakeFeedback": MessageLookupByLibrary.simpleMessage("抖动反馈"), "shakeFeedback": MessageLookupByLibrary.simpleMessage("抖动反馈"),
"shakeFeedbackDescription": MessageLookupByLibrary.simpleMessage( "shakeFeedbackDescription": MessageLookupByLibrary.simpleMessage(
"检测到抖动时给出的反馈", "检测到抖动时给出的反馈",
@ -342,18 +367,21 @@ class MessageLookup extends MessageLookupByLibrary {
"themeMode": MessageLookupByLibrary.simpleMessage("主题模式"), "themeMode": MessageLookupByLibrary.simpleMessage("主题模式"),
"themeModeDark": MessageLookupByLibrary.simpleMessage("深色"), "themeModeDark": MessageLookupByLibrary.simpleMessage("深色"),
"themeModeHighContrast": MessageLookupByLibrary.simpleMessage("高对比度模式"), "themeModeHighContrast": MessageLookupByLibrary.simpleMessage("高对比度模式"),
"themeModeHighContrastDescription": MessageLookupByLibrary.simpleMessage( "themeModeHighContrastDescription":
MessageLookupByLibrary.simpleMessage(
"增加背景和文本之间的对比度", "增加背景和文本之间的对比度",
), ),
"themeModeLight": MessageLookupByLibrary.simpleMessage("浅色"), "themeModeLight": MessageLookupByLibrary.simpleMessage("浅色"),
"themeModeSystem": MessageLookupByLibrary.simpleMessage("跟随系统"), "themeModeSystem": MessageLookupByLibrary.simpleMessage("跟随系统"),
"themeSettings": MessageLookupByLibrary.simpleMessage("主题设置"), "themeSettings": MessageLookupByLibrary.simpleMessage("主题设置"),
"themeSettingsColors": MessageLookupByLibrary.simpleMessage("主题色"), "themeSettingsColors": MessageLookupByLibrary.simpleMessage("主题色"),
"themeSettingsColorsAndroid": MessageLookupByLibrary.simpleMessage("主题色"), "themeSettingsColorsAndroid":
MessageLookupByLibrary.simpleMessage("主题色"),
"themeSettingsColorsBook": MessageLookupByLibrary.simpleMessage( "themeSettingsColorsBook": MessageLookupByLibrary.simpleMessage(
"书籍详情页自适应主题", "书籍详情页自适应主题",
), ),
"themeSettingsColorsBookDescription": MessageLookupByLibrary.simpleMessage( "themeSettingsColorsBookDescription":
MessageLookupByLibrary.simpleMessage(
"以牺牲一些性能为代价,对书籍详情页的颜色进行美化", "以牺牲一些性能为代价,对书籍详情页的颜色进行美化",
), ),
"themeSettingsColorsCurrent": MessageLookupByLibrary.simpleMessage( "themeSettingsColorsCurrent": MessageLookupByLibrary.simpleMessage(
@ -364,7 +392,8 @@ class MessageLookup extends MessageLookupByLibrary {
"themeSettingsColorsDescription": MessageLookupByLibrary.simpleMessage( "themeSettingsColorsDescription": MessageLookupByLibrary.simpleMessage(
"使用应用程序的系统主题色", "使用应用程序的系统主题色",
), ),
"themeSettingsDescription": MessageLookupByLibrary.simpleMessage("自定义应用主题"), "themeSettingsDescription":
MessageLookupByLibrary.simpleMessage("自定义应用主题"),
"timeSecond": m7, "timeSecond": m7,
"unknown": MessageLookupByLibrary.simpleMessage("未知"), "unknown": MessageLookupByLibrary.simpleMessage("未知"),
"webVersion": MessageLookupByLibrary.simpleMessage("Web版本"), "webVersion": MessageLookupByLibrary.simpleMessage("Web版本"),

View file

@ -1,5 +1,6 @@
import 'dart:math'; import 'dart:math';
import 'package:dropdown_search/dropdown_search.dart';
import 'package:easy_refresh/easy_refresh.dart'; import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
@ -10,6 +11,7 @@ import 'package:shelfsdk/audiobookshelf_api.dart';
import 'package:vaani/api/api_provider.dart'; import 'package:vaani/api/api_provider.dart';
import 'package:vaani/api/image_provider.dart'; import 'package:vaani/api/image_provider.dart';
import 'package:vaani/api/library_provider.dart'; import 'package:vaani/api/library_provider.dart';
import 'package:vaani/constants/sizes.dart';
import 'package:vaani/features/you/view/widgets/library_switch_chip.dart'; import 'package:vaani/features/you/view/widgets/library_switch_chip.dart';
import 'package:vaani/generated/l10n.dart'; import 'package:vaani/generated/l10n.dart';
import 'package:vaani/router/models/library_item_extras.dart'; import 'package:vaani/router/models/library_item_extras.dart';
@ -18,11 +20,11 @@ import 'package:vaani/shared/extensions/model_conversions.dart';
import 'package:vaani/shared/extensions/style.dart'; import 'package:vaani/shared/extensions/style.dart';
import 'package:vaani/shared/icons/abs_icons.dart'; import 'package:vaani/shared/icons/abs_icons.dart';
import 'package:vaani/shared/utils/components.dart'; import 'package:vaani/shared/utils/components.dart';
import 'package:vaani/shared/widgets/custom_dropdown.dart';
import 'package:vaani/shared/widgets/skeletons.dart'; import 'package:vaani/shared/widgets/skeletons.dart';
// TODO: implement the library page
class LibraryPage extends HookConsumerWidget { class LibraryPage extends HookConsumerWidget {
LibraryPage({this.libraryId, super.key}); const LibraryPage({this.libraryId, super.key});
final String? libraryId; final String? libraryId;
@override @override
@ -72,6 +74,14 @@ class LibraryPage extends HookConsumerWidget {
}, },
), ),
actions: [ actions: [
// IconButton(
// icon: Icon(Icons.filter_list),
// tooltip: '筛选', // Helpful tooltip for users
// onPressed: () {
// debugPrint('筛选');
// },
// ),
const LibraryItemsSort(),
IconButton( IconButton(
icon: Icon(Icons.next_plan), icon: Icon(Icons.next_plan),
tooltip: '加载下一页', // Helpful tooltip for users tooltip: '加载下一页', // Helpful tooltip for users
@ -235,3 +245,64 @@ class BookCoverWidget extends HookConsumerWidget {
); );
} }
} }
class LibraryItemsSort extends HookConsumerWidget {
const LibraryItemsSort({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// return IconButton(
// icon: Icon(Icons.sort),
// tooltip: '排序', // Helpful tooltip for users
// onPressed: () {
// debugPrint('排序');
// },
// );
final state = ref.watch(libraryItemsProvider);
String selected = state.sort;
return DropdownSearch<String>(
selectedItem: selected,
mode: Mode.custom,
items: (filter, loadProps) => state.sortList,
dropdownBuilder: (ctx, selectedItem) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(state.sortDisplay(selectedItem ?? '')),
state.desc
? const Icon(Icons.keyboard_arrow_down)
: const Icon(Icons.keyboard_arrow_up),
],
);
},
popupProps: PopupProps.menu(
menuProps: MenuProps(
borderRadius: const BorderRadius.all(
Radius.circular(AppElementSizes.borderRadiusRegular),
),
popUpAnimationStyle: AnimationStyle(duration: Duration.zero),
),
constraints: BoxConstraints(
minWidth: 180, maxHeight: MediaQuery.of(context).size.height * 0.5),
itemBuilder: (context, item, isDisabled, isSelected) => ListTile(
title: Text(state.sortDisplay(item)),
trailing: selected == item
? state.desc
? const Icon(Icons.keyboard_arrow_down)
: const Icon(Icons.keyboard_arrow_up)
: null,
),
fit: FlexFit.loose,
),
onChanged: (value) {
debugPrint(value);
ref.read(libraryItemsProvider.notifier).update(
state.copyWith(
sort: value,
desc: state.sort == value ? !state.desc : state.desc,
),
);
},
);
}
}

View file

@ -9,6 +9,7 @@ import 'package:vaani/api/api_provider.dart';
import 'package:vaani/api/image_provider.dart'; import 'package:vaani/api/image_provider.dart';
import 'package:vaani/api/library_item_provider.dart' show libraryItemProvider; import 'package:vaani/api/library_item_provider.dart' show libraryItemProvider;
import 'package:vaani/constants/hero_tag_conventions.dart'; import 'package:vaani/constants/hero_tag_conventions.dart';
import 'package:vaani/constants/sizes.dart';
import 'package:vaani/features/item_viewer/view/library_item_actions.dart'; import 'package:vaani/features/item_viewer/view/library_item_actions.dart';
import 'package:vaani/features/player/providers/abs_provider.dart'; import 'package:vaani/features/player/providers/abs_provider.dart';
import 'package:vaani/features/settings/app_settings_provider.dart'; import 'package:vaani/features/settings/app_settings_provider.dart';
@ -315,28 +316,38 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
} }
class BookCoverWidget extends HookConsumerWidget { class BookCoverWidget extends HookConsumerWidget {
const BookCoverWidget({ final double width;
final String? itemId;
const BookCoverWidget(
this.width, {
super.key, super.key,
this.itemId,
}); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final currentBook = ref.watch(currentBookProvider); if (itemId == null) {
if (currentBook == null) { return SizedBox(width: width, child: const BookCoverSkeleton());
return const BookCoverSkeleton();
} }
final itemBeingPlayed = final itemBeingPlayed = ref.watch(libraryItemProvider(itemId!));
ref.watch(libraryItemProvider(currentBook.libraryItemId));
final imageOfItemBeingPlayed = itemBeingPlayed.valueOrNull != null final imageOfItemBeingPlayed = itemBeingPlayed.valueOrNull != null
? ref.watch( ? ref.watch(
coverImageProvider(itemBeingPlayed.valueOrNull!.id), coverImageProvider(itemBeingPlayed.valueOrNull!.id),
) )
: null; : null;
return imageOfItemBeingPlayed?.valueOrNull != null return SizedBox(
width: width,
child: ClipRRect(
borderRadius: BorderRadius.circular(
AppElementSizes.borderRadiusRegular,
),
child: imageOfItemBeingPlayed?.valueOrNull != null
? Image.memory( ? Image.memory(
imageOfItemBeingPlayed!.valueOrNull!, imageOfItemBeingPlayed!.valueOrNull!,
fit: BoxFit.cover, fit: BoxFit.cover,
) )
: const BookCoverSkeleton(); : const BookCoverSkeleton(),
),
);
} }
} }

View file

@ -140,17 +140,26 @@ FutureOr<(ColorScheme light, ColorScheme dark)?> systemTheme(
colorScheme: lightColorScheme.harmonized(), colorScheme: lightColorScheme.harmonized(),
fontFamily: fontFamilyPlatform, fontFamily: fontFamilyPlatform,
textTheme: textTheme, textTheme: textTheme,
// iconTheme: IconThemeData(size: 24),
); );
final appThemeDark = ThemeData( final appThemeDark = ThemeData(
useMaterial3: true, useMaterial3: true,
colorScheme: darkColorScheme.harmonized(), colorScheme: darkColorScheme.harmonized(),
fontFamily: fontFamilyPlatform, fontFamily: fontFamilyPlatform,
textTheme: textTheme, textTheme: textTheme,
// iconTheme: IconThemeData(size: 24),
brightness: Brightness.dark, brightness: Brightness.dark,
// TODO bottom sheet theme is not working // TODO bottom sheet theme is not working
bottomSheetTheme: BottomSheetThemeData( bottomSheetTheme: BottomSheetThemeData(
backgroundColor: darkColorScheme.surface, backgroundColor: darkColorScheme.surface,
), ),
); );
return (appThemeLight, appThemeDark); return (
appThemeLight.copyWith(
// iconTheme: appThemeLight.iconTheme.copyWith(size: 24),
),
appThemeDark.copyWith(
// iconTheme: appThemeLight.iconTheme.copyWith(size: 24),
)
);
} }

View file

@ -176,7 +176,7 @@ class _SystemThemeProviderElement
bool get highContrast => (origin as SystemThemeProvider).highContrast; bool get highContrast => (origin as SystemThemeProvider).highContrast;
} }
String _$currentThemeHash() => r'0e62a7f1b62c6ad73a3769909607407d41eb0338'; String _$currentThemeHash() => r'90abeb0e647e2a0e0c5c6edf4223003500dce431';
/// See also [currentTheme]. /// See also [currentTheme].
@ProviderFor(currentTheme) @ProviderFor(currentTheme)