mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2026-02-17 23:09:36 +00:00
chore: 优化进度条显示
This commit is contained in:
parent
03cec3f4b6
commit
d96995a863
27 changed files with 1229 additions and 1311 deletions
|
|
@ -105,22 +105,11 @@ class PlayerExpanded extends HookConsumerWidget {
|
|||
left: AppElementSizes.paddingRegular,
|
||||
right: AppElementSizes.paddingRegular,
|
||||
),
|
||||
child: const AudiobookChapterProgressBar(),
|
||||
child: const AbsDesktopProgressBar(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
width: imageSize,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: AppElementSizes.paddingRegular,
|
||||
right: AppElementSizes.paddingRegular,
|
||||
),
|
||||
child: const AudiobookProgressBar(),
|
||||
),
|
||||
),
|
||||
|
||||
// the chapter skip buttons, seek 30 seconds back and forward, and play/pause button
|
||||
Expanded(
|
||||
flex: 2,
|
||||
|
|
|
|||
|
|
@ -110,9 +110,9 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
|
|||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: AppElementSizes.paddingRegular,
|
||||
horizontal: AppElementSizes.paddingLarge,
|
||||
),
|
||||
child: const AudiobookChapterProgressBar(
|
||||
child: const AbsDesktopProgressBar(
|
||||
timeLabelLocation: TimeLabelLocation.sides,
|
||||
),
|
||||
),
|
||||
|
|
@ -140,10 +140,10 @@ class PlayerExpandedDesktop extends HookConsumerWidget {
|
|||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Row(),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Hero(
|
||||
tag: HeroTagPrefixes.controlsCenter,
|
||||
child: const PlayerControlsDesktopCenter(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:vaani/constants/hero_tag_conventions.dart';
|
||||
|
|
@ -8,12 +7,12 @@ 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/player_player_pause_button.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/router/router.dart';
|
||||
import 'package:vaani/shared/extensions/chapter.dart';
|
||||
import 'package:vaani/shared/extensions/model_conversions.dart';
|
||||
import 'package:vaani/shared/widgets/shelves/book_shelf.dart';
|
||||
|
||||
|
|
@ -29,16 +28,16 @@ class PlayerMinimized extends HookConsumerWidget {
|
|||
final size = MediaQuery.of(context).size;
|
||||
// 竖屏
|
||||
final isVertical = size.height > size.width;
|
||||
return Container(
|
||||
return SizedBox(
|
||||
height: playerMinHeight,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
// color: Theme.of(context).colorScheme.surface,
|
||||
child: Stack(
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
isVertical
|
||||
? const PlayerMinimizedControls()
|
||||
: const PlayerMinimizedControlsDesktop(),
|
||||
const PlayerMinimizedProgress(),
|
||||
const AbsMinimizedProgress(),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
@ -145,36 +144,14 @@ class PlayerMinimizedControls extends HookConsumerWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class PlayerMinimizedProgress extends HookConsumerWidget {
|
||||
const PlayerMinimizedProgress({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final currentChapter = ref.watch(currentChapterProvider);
|
||||
|
||||
final progress = useStream(
|
||||
ref.read(absPlayerProvider).positionInChapterStream,
|
||||
initialData: Duration.zero,
|
||||
);
|
||||
return SizedBox(
|
||||
height: AppElementSizes.barHeight,
|
||||
child: LinearProgressIndicator(
|
||||
value: (progress.data ?? Duration.zero).inSeconds /
|
||||
(currentChapter?.duration.inSeconds ?? 1),
|
||||
// color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
// backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerMinimizedControlsDesktop extends HookConsumerWidget {
|
||||
const PlayerMinimizedControlsDesktop({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final currentBook = ref.watch(currentBookProvider);
|
||||
final currentChapter = ref.watch(currentChapterProvider);
|
||||
final absPlayer = ref.watch(absPlayerProvider);
|
||||
ref.watch(currentChapterProvider);
|
||||
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click, // 桌面端显示手型光标
|
||||
|
|
@ -210,7 +187,8 @@ class PlayerMinimizedControlsDesktop extends HookConsumerWidget {
|
|||
},
|
||||
child: Hero(
|
||||
tag: HeroTagPrefixes.bookCoverWith(
|
||||
currentBook?.libraryItemId),
|
||||
currentBook?.libraryItemId,
|
||||
),
|
||||
child: BookCoverWidget(
|
||||
playerMinHeight,
|
||||
itemId: currentBook?.libraryItemId,
|
||||
|
|
@ -231,18 +209,14 @@ class PlayerMinimizedControlsDesktop extends HookConsumerWidget {
|
|||
children: [
|
||||
// AutoScrollText(
|
||||
Text(
|
||||
currentChapter?.title ??
|
||||
currentBook?.metadata.title ??
|
||||
'',
|
||||
absPlayer.primaryTitle(),
|
||||
maxLines: 1, overflow: TextOverflow.ellipsis,
|
||||
// velocity:
|
||||
// const Velocity(pixelsPerSecond: Offset(16, 0)),
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
Text(
|
||||
currentBook?.metadata.asBookMetadataExpanded
|
||||
.authorName ??
|
||||
'',
|
||||
absPlayer.secondaryTitle(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
|
|
@ -263,6 +237,7 @@ class PlayerMinimizedControlsDesktop extends HookConsumerWidget {
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Hero(
|
||||
tag: HeroTagPrefixes.controlsCenter,
|
||||
child: const PlayerControlsDesktopCenter(),
|
||||
|
|
|
|||
|
|
@ -1,60 +1,44 @@
|
|||
import 'package:audio_video_progress_bar/audio_video_progress_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:vaani/constants/sizes.dart';
|
||||
import 'package:vaani/features/player/providers/abs_provider.dart';
|
||||
import 'package:vaani/features/settings/app_settings_provider.dart';
|
||||
|
||||
// 章节进度
|
||||
class AudiobookChapterProgressBar extends HookConsumerWidget {
|
||||
/// 进度条展示 根据设置显示章节进度或整本书的进度
|
||||
class AbsDesktopProgressBar extends HookConsumerWidget {
|
||||
final TimeLabelLocation timeLabelLocation;
|
||||
const AudiobookChapterProgressBar({
|
||||
const AbsDesktopProgressBar({
|
||||
super.key,
|
||||
this.timeLabelLocation = TimeLabelLocation.below,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final book = ref.watch(currentBookProvider);
|
||||
final player = ref.watch(absPlayerProvider);
|
||||
final currentChapter = ref.watch(currentChapterProvider);
|
||||
final position = useStream(
|
||||
player.positionInBookStream,
|
||||
initialData: const Duration(seconds: 0),
|
||||
);
|
||||
final buffered = useStream(
|
||||
player.bufferedPositionInBookStream,
|
||||
initialData: const Duration(seconds: 0),
|
||||
);
|
||||
final playerSettings =
|
||||
ref.watch(appSettingsProvider.select((v) => v.playerSettings));
|
||||
final showChapterProgress =
|
||||
playerSettings.expandedPlayerSettings.showChapterProgress;
|
||||
|
||||
// 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 position = ref.watch(progressProvider);
|
||||
final buffered = ref.watch(progressBufferedProvider);
|
||||
|
||||
final currentChapterBuffered = currentChapter == null
|
||||
? null
|
||||
: (player.bufferedPositionInBook - currentChapter.start);
|
||||
|
||||
final progress =
|
||||
currentChapterProgress ?? position.data ?? const Duration(seconds: 0);
|
||||
final total = currentChapter == null
|
||||
? book?.duration ?? const Duration(seconds: 0)
|
||||
: currentChapter.end - currentChapter.start;
|
||||
final total = ref.watch(totalProvider);
|
||||
return ProgressBar(
|
||||
progress: progress,
|
||||
progress: position.requireValue,
|
||||
total: total,
|
||||
// ! TODO add onSeek
|
||||
onSeek: (duration) {
|
||||
player.seekInBook(
|
||||
duration + (currentChapter?.start ?? const Duration(seconds: 0)),
|
||||
duration +
|
||||
(showChapterProgress
|
||||
? (currentChapter?.start ?? Duration.zero)
|
||||
: Duration.zero),
|
||||
);
|
||||
// player.seek(duration);
|
||||
},
|
||||
thumbRadius: 8,
|
||||
buffered:
|
||||
currentChapterBuffered ?? buffered.data ?? const Duration(seconds: 0),
|
||||
buffered: buffered.requireValue,
|
||||
bufferedBarColor: Theme.of(context).colorScheme.secondary,
|
||||
timeLabelType: TimeLabelType.remainingTime,
|
||||
timeLabelLocation: timeLabelLocation,
|
||||
|
|
@ -63,26 +47,19 @@ class AudiobookChapterProgressBar extends HookConsumerWidget {
|
|||
}
|
||||
|
||||
// 书籍进度 简化版
|
||||
class AudiobookProgressBar extends HookConsumerWidget {
|
||||
const AudiobookProgressBar({
|
||||
super.key,
|
||||
});
|
||||
class AbsMinimizedProgress extends HookConsumerWidget {
|
||||
const AbsMinimizedProgress({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final book = ref.watch(currentBookProvider);
|
||||
final player = ref.read(absPlayerProvider);
|
||||
final position = useStream(
|
||||
player.positionInBookStream,
|
||||
initialData: const Duration(seconds: 0),
|
||||
);
|
||||
|
||||
final position = ref.watch(progressProvider);
|
||||
final total = ref.watch(totalProvider);
|
||||
return SizedBox(
|
||||
height: AppElementSizes.barHeightLarge,
|
||||
height: AppElementSizes.barHeight,
|
||||
child: LinearProgressIndicator(
|
||||
value: (position.data ?? const Duration(seconds: 0)).inSeconds /
|
||||
(book?.duration ?? const Duration(seconds: 0)).inSeconds,
|
||||
borderRadius: BorderRadiusGeometry.all(Radius.circular(10)),
|
||||
value: total > Duration.zero
|
||||
? ((position.value ?? Duration.zero).inSeconds / total.inSeconds)
|
||||
: 0,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue