mobile-music/lib/screens/favorites_screen.dart
2026-07-29 16:22:00 -04:00

112 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../state/providers.dart';
import '../theme/tokens.dart';
import 'browser_screen.dart';
/// Favorites — starred songs / albums / artists from `getStarred2`.
class FavoritesScreen extends ConsumerWidget {
const FavoritesScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final starred = ref.watch(starredProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Favorites',
style: TextStyle(fontWeight: FontWeight.w700)),
),
body: SafeArea(
child: starred.when(
loading: () => const Center(
child: SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(strokeWidth: 2),
),
),
error: (e, _) => Center(
child: Text('$e',
style: const TextStyle(color: TimbreColors.dimmed)),
),
data: (s) {
if (s.songs.isEmpty && s.albums.isEmpty && s.artists.isEmpty) {
return const Center(
child: Text('No favorites yet.',
style: TextStyle(color: TimbreColors.dimmed)),
);
}
return ListView(
children: [
if (s.songs.isNotEmpty) ...[
const _SectionLabel('Songs'),
for (var i = 0; i < s.songs.length; i++)
BrowseRow(
title: s.songs[i].title ?? 'Untitled',
trailing: s.songs[i].artist,
onTap: () => ref
.read(playbackProvider.notifier)
.playSongs(s.songs, startIndex: i),
onPlayNext: () => ref
.read(playbackProvider.notifier)
.playNext(s.songs[i]),
onAddToQueue: () => ref
.read(playbackProvider.notifier)
.addToQueue(s.songs[i]),
),
],
if (s.albums.isNotEmpty) ...[
const _SectionLabel('Albums'),
for (final a in s.albums)
BrowseRow(
title: a.name ?? 'Unknown album',
trailing: a.artist,
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => AlbumScreen(id: a.id),
),
),
),
],
if (s.artists.isNotEmpty) ...[
const _SectionLabel('Artists'),
for (final a in s.artists)
BrowseRow(
title: a.name ?? 'Unknown artist',
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ArtistScreen(id: a.id),
),
),
),
],
],
);
},
),
),
);
}
}
class _SectionLabel extends StatelessWidget {
const _SectionLabel(this.text);
final String text;
@override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.fromLTRB(
TimbreSpacing.lg,
TimbreSpacing.lg,
TimbreSpacing.lg,
TimbreSpacing.sm,
),
child: Text(
text,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontWeight: FontWeight.w700,
),
),
);
}