Tab-Reihenfolge, konfigurierbare Meine-Musik-Sektionen, Berechtigungen beim Start, schärferes Sperrbildschirm-Cover
- Tabs: Meine Musik, Suchen, Download, Favoriten (vorher Download vor Suchen) - "Meine Musik": Schnellzugriffe (Favoriten/Wiedergabelisten/Zuletzt) einzeln über die Einstellungen abschaltbar - Audio- und Benachrichtigungs-Berechtigung werden jetzt beim ersten Start gemeinsam angefragt statt erst bei Bedarf; Hinweisbanner + Einstellungen- Button bei dauerhafter Verweigerung (auch für Benachrichtigungen neu) - Cover-Extraktion beim Android-Scan von 512px auf 1024px erhöht, für ein schärferes Cover im Sperrbildschirm - Fix: notifyListeners() in LibraryService nur noch bei echter Wertänderung (verhinderte einen Test-Hang durch den neuen Start-Berechtigungs-Aufruf) 557 Tests grün, flutter analyze ohne Befund. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM2JK5mV7AL1g2Rt6H6h9w
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
54cb523cf4
commit
da012a3dca
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../playlists/playlists_screen.dart';
|
||||
import '../settings/app_settings.dart';
|
||||
import '../settings/settings_screen.dart';
|
||||
import '../shared/cover.dart';
|
||||
import '../shared/sort_store.dart';
|
||||
@@ -57,6 +58,19 @@ class _MyMusicScreenState extends State<MyMusicScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
if (lib.notificationPermissionDenied)
|
||||
MaterialBanner(
|
||||
backgroundColor: Colors.red.shade900,
|
||||
content: const Text(
|
||||
'Benachrichtigungen für die Wiedergabe sind deaktiviert. '
|
||||
'Bitte in den Einstellungen erlauben.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: openMusicPermissionSettings,
|
||||
child: const Text('Einstellungen'),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (lib.scanError != null)
|
||||
MaterialBanner(
|
||||
backgroundColor: Colors.red.shade900,
|
||||
@@ -180,54 +194,61 @@ class _QuickAccessRow extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final db = context.read<MeloDb>();
|
||||
final sektionen = context.watch<AppSettings>().meineMusikSektionen;
|
||||
if (sektionen.isEmpty) return const SizedBox.shrink();
|
||||
return SizedBox(
|
||||
height: 104,
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
children: [
|
||||
StreamBuilder<List<Song>>(
|
||||
stream: db.watchFavorites(),
|
||||
builder: (context, snapshot) {
|
||||
final favorites = snapshot.data ?? const <Song>[];
|
||||
return _QuickCard(
|
||||
icon: Icons.favorite,
|
||||
label: 'Favoriten',
|
||||
subtitle: '${favorites.length} Songs',
|
||||
coverPath: favorites.isEmpty ? null : favorites.first.coverPath,
|
||||
onTap: onFavoritesTap,
|
||||
);
|
||||
},
|
||||
),
|
||||
StreamBuilder<List<Playlist>>(
|
||||
stream: db.watchPlaylists(),
|
||||
builder: (context, snapshot) {
|
||||
final playlists = snapshot.data ?? const <Playlist>[];
|
||||
return _QuickCard(
|
||||
icon: Icons.queue_music,
|
||||
label: 'Wiedergabelisten',
|
||||
subtitle: '${playlists.length} Listen',
|
||||
onTap: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (_) => const PlaylistsScreen()),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
StreamBuilder<List<Song>>(
|
||||
stream: db.watchRecent(limit: 50),
|
||||
builder: (context, snapshot) {
|
||||
final recent = snapshot.data ?? const <Song>[];
|
||||
return _QuickCard(
|
||||
icon: Icons.schedule,
|
||||
label: 'Zuletzt',
|
||||
subtitle: 'Neu hinzugefügt',
|
||||
coverPath: recent.isEmpty ? null : recent.first.coverPath,
|
||||
onTap: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (_) => const RecentlyAddedScreen()),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (sektionen.contains(AppSettings.sektionFavoriten))
|
||||
StreamBuilder<List<Song>>(
|
||||
stream: db.watchFavorites(),
|
||||
builder: (context, snapshot) {
|
||||
final favorites = snapshot.data ?? const <Song>[];
|
||||
return _QuickCard(
|
||||
icon: Icons.favorite,
|
||||
label: 'Favoriten',
|
||||
subtitle: '${favorites.length} Songs',
|
||||
coverPath:
|
||||
favorites.isEmpty ? null : favorites.first.coverPath,
|
||||
onTap: onFavoritesTap,
|
||||
);
|
||||
},
|
||||
),
|
||||
if (sektionen.contains(AppSettings.sektionWiedergabelisten))
|
||||
StreamBuilder<List<Playlist>>(
|
||||
stream: db.watchPlaylists(),
|
||||
builder: (context, snapshot) {
|
||||
final playlists = snapshot.data ?? const <Playlist>[];
|
||||
return _QuickCard(
|
||||
icon: Icons.queue_music,
|
||||
label: 'Wiedergabelisten',
|
||||
subtitle: '${playlists.length} Listen',
|
||||
onTap: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (_) => const PlaylistsScreen()),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (sektionen.contains(AppSettings.sektionZuletzt))
|
||||
StreamBuilder<List<Song>>(
|
||||
stream: db.watchRecent(limit: 50),
|
||||
builder: (context, snapshot) {
|
||||
final recent = snapshot.data ?? const <Song>[];
|
||||
return _QuickCard(
|
||||
icon: Icons.schedule,
|
||||
label: 'Zuletzt',
|
||||
subtitle: 'Neu hinzugefügt',
|
||||
coverPath: recent.isEmpty ? null : recent.first.coverPath,
|
||||
onTap: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => const RecentlyAddedScreen()),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user