feat: add PlayingIndicatorIcon widget for animated playback indication (#80)

This commit is contained in:
Dr.Blank 2025-04-23 16:23:57 +05:30 committed by GitHub
parent 25be7fda03
commit bae99292a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 237 additions and 20 deletions

View file

@ -1,13 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart';
import 'package:vaani/features/player/providers/currently_playing_provider.dart';
import 'package:vaani/features/player/view/player_when_expanded.dart';
import 'package:vaani/main.dart';
import 'package:vaani/shared/extensions/chapter.dart';
import 'package:vaani/shared/extensions/duration_format.dart';
import 'package:vaani/shared/hooks.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart'
show audiobookPlayerProvider;
import 'package:vaani/features/player/providers/currently_playing_provider.dart'
show currentPlayingChapterProvider, currentlyPlayingBookProvider;
import 'package:vaani/features/player/view/player_when_expanded.dart'
show pendingPlayerModals;
import 'package:vaani/features/player/view/widgets/playing_indicator_icon.dart';
import 'package:vaani/main.dart' show appLogger;
import 'package:vaani/shared/extensions/chapter.dart' show ChapterDuration;
import 'package:vaani/shared/extensions/duration_format.dart'
show DurationFormat;
import 'package:vaani/shared/hooks.dart' show useTimer;
class ChapterSelectionButton extends HookConsumerWidget {
const ChapterSelectionButton({
@ -67,6 +72,7 @@ class ChapterSelectionModal extends HookConsumerWidget {
useTimer(scrollToCurrentChapter, 500.ms);
// useInterval(scrollToCurrentChapter, 500.ms);
final theme = Theme.of(context);
return Column(
children: [
ListTile(
@ -81,24 +87,41 @@ class ChapterSelectionModal extends HookConsumerWidget {
child: currentBook?.chapters == null
? const Text('No chapters found')
: Column(
children: [
for (final chapter in currentBook!.chapters)
ListTile(
title: Text(chapter.title),
trailing: Text(
'(${chapter.duration.smartBinaryFormat})',
),
selected: currentChapterIndex == chapter.id,
key: currentChapterIndex == chapter.id
? chapterKey
children: currentBook!.chapters.map(
(chapter) {
final isCurrent = currentChapterIndex == chapter.id;
final isPlayed = currentChapterIndex != null &&
chapter.id < currentChapterIndex;
return ListTile(
autofocus: isCurrent,
iconColor: isPlayed && !isCurrent
? theme.disabledColor
: null,
title: Text(
chapter.title,
style: isPlayed && !isCurrent
? TextStyle(color: theme.disabledColor)
: null,
),
subtitle: Text(
'(${chapter.duration.smartBinaryFormat})',
style: isPlayed && !isCurrent
? TextStyle(color: theme.disabledColor)
: null,
),
trailing: isCurrent
? const PlayingIndicatorIcon()
: const Icon(Icons.play_arrow),
selected: isCurrent,
key: isCurrent ? chapterKey : null,
onTap: () {
Navigator.of(context).pop();
notifier.seek(chapter.start + 90.ms);
notifier.play();
},
),
],
);
},
).toList(),
),
),
),