mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 07:29:14 +01:00
v2
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
import '../cache/image_cache.dart';
|
||||
import '../models/support.dart';
|
||||
import '../services/audio_service.dart';
|
||||
import '../state/audio.dart';
|
||||
import '../state/theme.dart';
|
||||
import 'app_router.dart';
|
||||
import 'images.dart';
|
||||
import 'pages/now_playing_page.dart';
|
||||
|
||||
class NowPlayingBar extends HookConsumerWidget {
|
||||
const NowPlayingBar({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final colors = ref.watch(mediaItemThemeProvider).valueOrNull;
|
||||
final noItem = ref.watch(mediaItemProvider).valueOrNull == null;
|
||||
|
||||
final widget = GestureDetector(
|
||||
onTap: () {
|
||||
context.navigateTo(const NowPlayingRoute());
|
||||
},
|
||||
child: Material(
|
||||
elevation: 3,
|
||||
color: colors?.darkBackground,
|
||||
// surfaceTintColor: theme?.colorScheme.background,
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 70,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: const [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: _ArtImage(),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 4),
|
||||
child: _TrackInfo(),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 16, top: 2),
|
||||
child: PlayPauseButton(size: 48),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const _ProgressBar(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (noItem) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
if (colors != null) {
|
||||
return Theme(data: colors.theme, child: widget);
|
||||
} else {
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _ArtImage extends HookConsumerWidget {
|
||||
const _ArtImage();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final imageCache = ref.watch(imageCacheProvider);
|
||||
final uri =
|
||||
ref.watch(mediaItemProvider.select((e) => e.valueOrNull?.artUri));
|
||||
final cacheKey = ref.watch(mediaItemDataProvider.select(
|
||||
(value) => value?.artCache?.thumbnailArtCacheKey,
|
||||
));
|
||||
|
||||
UriCacheInfo? cache;
|
||||
if (uri != null && cacheKey != null) {
|
||||
cache = UriCacheInfo(
|
||||
uri: uri,
|
||||
cacheKey: cacheKey,
|
||||
cacheManager: imageCache,
|
||||
);
|
||||
}
|
||||
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 150),
|
||||
child: CardClip(
|
||||
key: ValueKey(cacheKey ?? 'default'),
|
||||
child: cache == null
|
||||
? const PlaceholderImage()
|
||||
: UriCacheInfoImage(
|
||||
cache: cache,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TrackInfo extends HookConsumerWidget {
|
||||
const _TrackInfo();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final item = ref.watch(mediaItemProvider);
|
||||
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
...item.when(
|
||||
data: (data) => [
|
||||
// Text(
|
||||
// data?.title ?? 'Nothing!!!',
|
||||
// maxLines: 1,
|
||||
// softWrap: false,
|
||||
// overflow: TextOverflow.fade,
|
||||
// style: Theme.of(context).textTheme.labelLarge,
|
||||
// ),
|
||||
ScrollableText(
|
||||
data?.title ?? 'Nothing!!!',
|
||||
style: Theme.of(context).textTheme.labelLarge,
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
data?.artist ?? 'Nothing!!!',
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
),
|
||||
],
|
||||
error: (_, __) => const [Text('Error!')],
|
||||
loading: () => const [Text('loading.....')],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PlayPauseButton extends HookConsumerWidget {
|
||||
final double size;
|
||||
|
||||
const PlayPauseButton({
|
||||
super.key,
|
||||
required this.size,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final playing = ref.watch(playingProvider);
|
||||
final state = ref.watch(processingStateProvider);
|
||||
|
||||
Widget icon;
|
||||
if (state == AudioProcessingState.loading ||
|
||||
state == AudioProcessingState.buffering) {
|
||||
icon = Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
const Icon(Icons.circle),
|
||||
SizedBox(
|
||||
height: size / 3,
|
||||
width: size / 3,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: size / 16,
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (playing) {
|
||||
icon = const Icon(Icons.pause_circle_rounded);
|
||||
} else {
|
||||
icon = const Icon(Icons.play_circle_rounded);
|
||||
}
|
||||
|
||||
return IconButton(
|
||||
iconSize: size,
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: () {
|
||||
if (playing) {
|
||||
ref.read(audioControlProvider).pause();
|
||||
} else {
|
||||
ref.read(audioControlProvider).play();
|
||||
}
|
||||
},
|
||||
icon: icon,
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ProgressBar extends HookConsumerWidget {
|
||||
const _ProgressBar();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final colors = ref.watch(mediaItemThemeProvider).valueOrNull;
|
||||
final position = ref.watch(positionProvider);
|
||||
final duration = ref.watch(durationProvider);
|
||||
|
||||
return Container(
|
||||
height: 4,
|
||||
color: colors?.darkerBackground,
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: position,
|
||||
child: Container(color: colors?.onDarkerBackground),
|
||||
),
|
||||
Flexible(flex: duration - position, child: Container()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user