From 94f137657255a61d337a7149d8acee62463ab5cf Mon Sep 17 00:00:00 2001 From: rang <378694192@qq.com> Date: Sat, 25 Oct 2025 17:44:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=92=AD=E6=94=BE=E7=95=8C=E9=9D=A2=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=B8=80=E4=B8=AA=E6=80=BB=E8=BF=9B=E5=BA=A6=E6=9D=A1?= =?UTF-8?q?,mini=E6=92=AD=E6=94=BE=E5=99=A8=E6=94=B9=E4=B8=BA=E5=8D=95?= =?UTF-8?q?=E7=AB=A0=E8=8A=82=E8=BF=9B=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../player/view/audiobook_player.dart | 55 ++++++++++++------- .../player/view/player_when_expanded.dart | 27 ++++++--- .../player/view/player_when_minimized.dart | 18 +++--- 3 files changed, 62 insertions(+), 38 deletions(-) diff --git a/lib/features/player/view/audiobook_player.dart b/lib/features/player/view/audiobook_player.dart index fe5efa1..a092f23 100644 --- a/lib/features/player/view/audiobook_player.dart +++ b/lib/features/player/view/audiobook_player.dart @@ -31,8 +31,7 @@ class AudiobookPlayer extends HookConsumerWidget { if (currentBook == null) { return const SizedBox.shrink(); } - final itemBeingPlayed = - ref.watch(libraryItemProvider(currentBook.libraryItemId)); + final itemBeingPlayed = ref.watch(libraryItemProvider(currentBook.libraryItemId)); final player = ref.watch(audiobookPlayerProvider); final imageOfItemBeingPlayed = itemBeingPlayed.valueOrNull != null ? ref.watch( @@ -65,8 +64,7 @@ class AudiobookPlayer extends HookConsumerWidget { themeOfLibraryItemProvider( itemBeingPlayed.valueOrNull?.id, brightness: Theme.of(context).brightness, - highContrast: appSettings.themeSettings.highContrast || - MediaQuery.of(context).highContrast, + highContrast: appSettings.themeSettings.highContrast || MediaQuery.of(context).highContrast, ), ); @@ -88,8 +86,7 @@ class AudiobookPlayer extends HookConsumerWidget { onDragDown: (percentage) async { // preferred volume // set volume to 0 when dragging down - await player - .setVolume(preferredVolume * (1 - percentage.clamp(0, .75))); + await player.setVolume(preferredVolume * (1 - percentage.clamp(0, .75))); }, minHeight: playerMinHeight, // subtract the height of notches and other system UI @@ -109,10 +106,8 @@ class AudiobookPlayer extends HookConsumerWidget { // at what point should the player switch from miniplayer to expanded player // also at this point the image should be at its max size and in the center of the player final miniplayerPercentageDeclaration = - (maxImgSize - playerMinHeight) / - (playerMaxHeight - playerMinHeight); - final bool isFormMiniplayer = - percentage < miniplayerPercentageDeclaration; + (maxImgSize - playerMinHeight) / (playerMaxHeight - playerMinHeight); + final bool isFormMiniplayer = percentage < miniplayerPercentageDeclaration; if (!isFormMiniplayer) { // this calculation needs a refactor @@ -212,17 +207,14 @@ class AudiobookChapterProgressBar extends HookConsumerWidget { // now find the chapter that corresponds to the current time // and calculate the progress of the current chapter - final currentChapterProgress = currentChapter == null - ? null - : (player.positionInBook - currentChapter.start); + final currentChapterProgress = + currentChapter == null ? null : (player.positionInBook - currentChapter.start); - final currentChapterBuffered = currentChapter == null - ? null - : (player.bufferedPositionInBook - currentChapter.start); + final currentChapterBuffered = + currentChapter == null ? null : (player.bufferedPositionInBook - currentChapter.start); return ProgressBar( - progress: - currentChapterProgress ?? position.data ?? const Duration(seconds: 0), + progress: currentChapterProgress ?? position.data ?? const Duration(seconds: 0), total: currentChapter == null ? player.book?.duration ?? const Duration(seconds: 0) : currentChapter.end - currentChapter.start, @@ -234,8 +226,31 @@ class AudiobookChapterProgressBar extends HookConsumerWidget { player.seek(duration); }, thumbRadius: 8, - buffered: - currentChapterBuffered ?? buffered.data ?? const Duration(seconds: 0), + buffered: currentChapterBuffered ?? buffered.data ?? const Duration(seconds: 0), + bufferedBarColor: Theme.of(context).colorScheme.secondary, + timeLabelType: TimeLabelType.remainingTime, + timeLabelLocation: TimeLabelLocation.below, + ); + } +} + +class AudiobookProgressBar extends HookConsumerWidget { + const AudiobookProgressBar({ + super.key, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final player = ref.watch(audiobookPlayerProvider); + final position = useStream( + player.slowPositionStreamInBook, + initialData: const Duration(seconds: 0), + ); + + return ProgressBar( + progress: position.data ?? const Duration(seconds: 0), + total: player.book?.duration ?? const Duration(seconds: 0), + thumbRadius: 8, bufferedBarColor: Theme.of(context).colorScheme.secondary, timeLabelType: TimeLabelType.remainingTime, timeLabelLocation: TimeLabelLocation.below, diff --git a/lib/features/player/view/player_when_expanded.dart b/lib/features/player/view/player_when_expanded.dart index a69d71f..a27d260 100644 --- a/lib/features/player/view/player_when_expanded.dart +++ b/lib/features/player/view/player_when_expanded.dart @@ -105,10 +105,7 @@ class PlayerWhenExpanded extends HookConsumerWidget { decoration: BoxDecoration( boxShadow: [ BoxShadow( - color: Theme.of(context) - .colorScheme - .primary - .withValues(alpha: 0.1), + color: Theme.of(context).colorScheme.primary.withValues(alpha: 0.1), blurRadius: 32 * earlyPercentage, spreadRadius: 8 * earlyPercentage, // offset: Offset(0, 16 * earlyPercentage), @@ -174,10 +171,7 @@ class PlayerWhenExpanded extends HookConsumerWidget { currentBookMetadata?.authorName ?? '', ].join(' - '), style: Theme.of(context).textTheme.titleMedium?.copyWith( - color: Theme.of(context) - .colorScheme - .onSurface - .withValues(alpha: 0.7), + color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7), ), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -205,6 +199,23 @@ class PlayerWhenExpanded extends HookConsumerWidget { ), ), + Expanded( + child: Opacity( + opacity: earlyPercentage, + child: SizedBox( + width: imageSize, + child: Padding( + padding: EdgeInsets.only( + // top: AppElementSizes.paddingRegular * earlyPercentage, + left: AppElementSizes.paddingRegular * earlyPercentage, + right: AppElementSizes.paddingRegular * earlyPercentage, + ), + child: const AudiobookProgressBar(), + ), + ), + ), + ), + // the chapter skip buttons, seek 30 seconds back and forward, and play/pause button Expanded( flex: 2, diff --git a/lib/features/player/view/player_when_minimized.dart b/lib/features/player/view/player_when_minimized.dart index 59548ad..55ba414 100644 --- a/lib/features/player/view/player_when_minimized.dart +++ b/lib/features/player/view/player_when_minimized.dart @@ -34,8 +34,9 @@ class PlayerWhenMinimized extends HookConsumerWidget { final currentChapter = ref.watch(currentPlayingChapterProvider); final vanishingPercentage = 1 - percentageMiniplayer; - final progress = - useStream(player.slowPositionStreamInBook, initialData: Duration.zero); + // final progress = + // useStream(player.slowPositionStreamInBook, initialData: Duration.zero); + final progress = useStream(player.positionStream, initialData: Duration.zero); final bookMetaExpanded = ref.watch(currentBookMetadataProvider); @@ -57,8 +58,7 @@ class PlayerWhenMinimized extends HookConsumerWidget { context.pushNamed( Routes.libraryItem.name, pathParameters: { - Routes.libraryItem.pathParamName!: - player.book!.libraryItemId, + Routes.libraryItem.pathParamName!: player.book!.libraryItemId, }, ); }, @@ -92,10 +92,7 @@ class PlayerWhenMinimized extends HookConsumerWidget { maxLines: 1, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Theme.of(context) - .colorScheme - .onSurface - .withValues(alpha: 0.7), + color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7), ), ), ], @@ -139,8 +136,9 @@ class PlayerWhenMinimized extends HookConsumerWidget { SizedBox( height: barHeight, child: LinearProgressIndicator( - value: (progress.data ?? Duration.zero).inSeconds / - player.book!.duration.inSeconds, + // value: (progress.data ?? Duration.zero).inSeconds / + // player.book!.duration.inSeconds, + value: (progress.data ?? Duration.zero).inSeconds / player.duration!.inSeconds, color: Theme.of(context).colorScheme.onPrimaryContainer, backgroundColor: Theme.of(context).colorScheme.primaryContainer, ),