fix(favorite): 收藏状态变化时主页实时刷新
之前主页收藏列表只在启动或从文件列表返回时重查, 在播放页/文件列表点红心,主页不会变。 - 新增 FavoriteEvents(songPath 事件) - 文件列表、播放页收藏/取消后 publish - 主页订阅后重新拉取收藏列表
This commit is contained in:
@@ -2,6 +2,7 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import '../services/audio_service.dart';
|
import '../services/audio_service.dart';
|
||||||
|
import '../services/favorite_events.dart';
|
||||||
import '../services/metadata_events.dart';
|
import '../services/metadata_events.dart';
|
||||||
import '../services/webdav_service.dart';
|
import '../services/webdav_service.dart';
|
||||||
import '../widgets/magnetic_scroll_physics.dart';
|
import '../widgets/magnetic_scroll_physics.dart';
|
||||||
@@ -166,6 +167,7 @@ class _HomePageState extends BaseState<HomePage> {
|
|||||||
int _homeTab = 0;
|
int _homeTab = 0;
|
||||||
final PageController _homePageController = PageController();
|
final PageController _homePageController = PageController();
|
||||||
StreamSubscription<MetadataUpdate>? _metaSub;
|
StreamSubscription<MetadataUpdate>? _metaSub;
|
||||||
|
StreamSubscription<String>? _favSub;
|
||||||
List<PlaylistSummary> _playlistSummaries = [];
|
List<PlaylistSummary> _playlistSummaries = [];
|
||||||
|
|
||||||
// ========== 滚动控制 ==========
|
// ========== 滚动控制 ==========
|
||||||
@@ -204,6 +206,7 @@ class _HomePageState extends BaseState<HomePage> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
_scrollController = ScrollController()..addListener(_onScroll);
|
_scrollController = ScrollController()..addListener(_onScroll);
|
||||||
_metaSub = MetadataEvents().stream.listen(_onMetadataUpdate);
|
_metaSub = MetadataEvents().stream.listen(_onMetadataUpdate);
|
||||||
|
_favSub = FavoriteEvents().stream.listen((_) => _onFavoriteChanged());
|
||||||
_initWebDAV();
|
_initWebDAV();
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
@@ -214,6 +217,7 @@ class _HomePageState extends BaseState<HomePage> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_metaSub?.cancel();
|
_metaSub?.cancel();
|
||||||
|
_favSub?.cancel();
|
||||||
_homePageController.dispose();
|
_homePageController.dispose();
|
||||||
_scrollController.dispose();
|
_scrollController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
@@ -245,6 +249,12 @@ class _HomePageState extends BaseState<HomePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 任何位置收藏/取消收藏后,重新拉一次收藏列表
|
||||||
|
Future<void> _onFavoriteChanged() async {
|
||||||
|
await _loadFavoritesFromDb();
|
||||||
|
if (mounted) safeSetState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
/// 元数据补全后,按 path 更新收藏列表里的对应行
|
/// 元数据补全后,按 path 更新收藏列表里的对应行
|
||||||
void _onMetadataUpdate(MetadataUpdate update) {
|
void _onMetadataUpdate(MetadataUpdate update) {
|
||||||
final index = _favorites.indexWhere((item) => item.path == update.path);
|
final index = _favorites.indexWhere((item) => item.path == update.path);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
|
|||||||
import '../base/base_state.dart';
|
import '../base/base_state.dart';
|
||||||
import '../database/song_database.dart';
|
import '../database/song_database.dart';
|
||||||
import '../services/audio_service.dart';
|
import '../services/audio_service.dart';
|
||||||
|
import '../services/favorite_events.dart';
|
||||||
|
|
||||||
class PlayerPage extends StatefulWidget {
|
class PlayerPage extends StatefulWidget {
|
||||||
final VoidCallback? onClose;
|
final VoidCallback? onClose;
|
||||||
@@ -138,6 +139,7 @@ class _PlayerPageState extends BaseState<PlayerPage> {
|
|||||||
Future<void> _toggleFavorite(Song song) async {
|
Future<void> _toggleFavorite(Song song) async {
|
||||||
try {
|
try {
|
||||||
await SongDatabase().toggleFavorite(song.id);
|
await SongDatabase().toggleFavorite(song.id);
|
||||||
|
FavoriteEvents().publish(song.id);
|
||||||
final favorite = await SongDatabase().isFavorite(song.id);
|
final favorite = await SongDatabase().isFavorite(song.id);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
setState(() => _isFavorite = favorite);
|
setState(() => _isFavorite = favorite);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import '../base/base_state.dart';
|
|||||||
import '../controllers/playback_controller.dart';
|
import '../controllers/playback_controller.dart';
|
||||||
import '../database/song_database.dart';
|
import '../database/song_database.dart';
|
||||||
import '../services/audio_service.dart';
|
import '../services/audio_service.dart';
|
||||||
|
import '../services/favorite_events.dart';
|
||||||
import '../services/metadata_events.dart';
|
import '../services/metadata_events.dart';
|
||||||
import '../widgets/song_artwork.dart';
|
import '../widgets/song_artwork.dart';
|
||||||
import '../widgets/add_to_playlist_sheet.dart';
|
import '../widgets/add_to_playlist_sheet.dart';
|
||||||
@@ -92,6 +93,7 @@ class _WebDAVFileListPageState extends BaseState<WebDAVFileListPage> {
|
|||||||
final wasFavorite = _favoritePaths.contains(path);
|
final wasFavorite = _favoritePaths.contains(path);
|
||||||
try {
|
try {
|
||||||
await SongDatabase().toggleFavorite(path);
|
await SongDatabase().toggleFavorite(path);
|
||||||
|
FavoriteEvents().publish(path);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
safeSetState(() {
|
safeSetState(() {
|
||||||
final next = {..._favoritePaths};
|
final next = {..._favoritePaths};
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// lib/services/favorite_events.dart
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
/// 收藏状态变化事件。
|
||||||
|
///
|
||||||
|
/// 文件列表、播放页都能收藏/取消收藏,主页的收藏列表需要跟着变,
|
||||||
|
/// 否则要退出重进才看得到。
|
||||||
|
class FavoriteEvents {
|
||||||
|
static final FavoriteEvents _instance = FavoriteEvents._internal();
|
||||||
|
factory FavoriteEvents() => _instance;
|
||||||
|
FavoriteEvents._internal();
|
||||||
|
|
||||||
|
final StreamController<String> _controller =
|
||||||
|
StreamController<String>.broadcast();
|
||||||
|
|
||||||
|
Stream<String> get stream => _controller.stream;
|
||||||
|
|
||||||
|
void publish(String songPath) {
|
||||||
|
if (songPath.isEmpty) return;
|
||||||
|
_controller.add(songPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user