Files
YungR1otz/lib/features/music/presentation/widgets/track_card.dart
Lucas Saburido cabf2025cd first commit
2026-05-13 16:26:45 +01:00

110 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:just_audio/just_audio.dart';
import '../../../../core/theme/app_colors.dart';
import '../../domain/models/track_model.dart';
import '../providers/music_providers.dart';
class TrackCard extends ConsumerWidget {
const TrackCard({
required this.track,
super.key,
});
final TrackModel track;
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final player = ref.watch(audioPlayerProvider);
final currentTrack = ref.watch(currentTrackProvider);
final isPlaying = ref.watch(isPlayingProvider).value ?? false;
final isCurrent = currentTrack?.id == track.id;
return Container(
decoration: BoxDecoration(
color: isCurrent ? AppColors.surfaceLight : Colors.transparent,
border: Border.all(color: isCurrent ? AppColors.neonRed : AppColors.border),
),
margin: const EdgeInsets.only(bottom: 12),
child: InkWell(
onTap: () => _handlePlay(ref, player),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row(
children: [
// Cover / Icon
Container(
width: 56,
height: 56,
color: AppColors.black,
child: Center(
child: Icon(
isCurrent && isPlaying ? Icons.graphic_eq : Icons.music_note,
color: isCurrent ? AppColors.neonRed : AppColors.white,
size: 28,
),
),
),
const SizedBox(width: 16),
// Info
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
track.title.toUpperCase(),
style: theme.textTheme.titleLarge?.copyWith(fontSize: 16, letterSpacing: 1),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
Text(
'${track.username.toUpperCase()} // ${track.genreTag.toUpperCase()}',
style: theme.textTheme.bodySmall?.copyWith(color: AppColors.grey, fontSize: 10),
),
],
),
),
// Plays & Action
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'${track.plays} PLAYS',
style: theme.textTheme.bodySmall?.copyWith(fontSize: 9, fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Icon(
isCurrent && isPlaying ? Icons.pause_circle_filled : Icons.play_circle_filled,
color: AppColors.white,
size: 32,
),
],
),
],
),
),
),
);
}
Future<void> _handlePlay(WidgetRef ref, AudioPlayer player) async {
final currentTrack = ref.read(currentTrackProvider);
if (currentTrack?.id == track.id) {
if (player.playing) {
await player.pause();
} else {
await player.play();
}
} else {
ref.read(currentTrackProvider.notifier).state = track;
await player.setUrl(track.audioUrl);
await player.play();
// Increment play count
ref.read(musicControllerProvider.notifier).incrementPlays(track.id);
}
}
}