feat(metadata): 元数据补全后主动推送界面刷新

之前标签补全后,收藏/文件列表要退出重进才显示新信息。
- 新增 MetadataEvents 事件总线(MetadataUpdate: path + songs 行)
- MetadataService 写库成功后 publish
- 首页收藏列表订阅:按 path 替换对应 SongItem(标题/艺术家/封面)
- WebDAV 文件列表订阅:按 path 更新 _metaByPath

效果:歌曲播完标签抓取完成后,列表里的那一行自动变成标签信息,
不需要返回重进。
This commit is contained in:
2026-11-01 12:18:21 +08:00
parent 632713d133
commit 6ca31c37ba
4 changed files with 73 additions and 0 deletions
+11
View File
@@ -1,3 +1,4 @@
import 'dart:async';
// lib/pages/webdav_file_list_page.dart
import 'package:flutter/material.dart';
import '../services/webdav_service.dart';
@@ -6,6 +7,7 @@ import '../base/base_state.dart';
import '../controllers/playback_controller.dart';
import '../database/song_database.dart';
import '../services/audio_service.dart';
import '../services/metadata_events.dart';
import '../widgets/song_artwork.dart';
import '../widgets/add_to_playlist_sheet.dart';
@@ -27,6 +29,7 @@ class _WebDAVFileListPageState extends BaseState<WebDAVFileListPage> {
/// path -> 元数据行(songs 表),用于把文件名替换成标签里的标题/艺术家
Map<String, Map<String, dynamic>> _metaByPath = {};
String? _lastSyncedSongPath;
StreamSubscription<MetadataUpdate>? _metaSub;
/// 已收藏的歌曲路径
Set<String> _favoritePaths = {};
@@ -54,6 +57,14 @@ class _WebDAVFileListPageState extends BaseState<WebDAVFileListPage> {
super.dispose();
}
/// 元数据补全后,按 path 更新列表行的标题/艺术家/封面
void _onMetadataUpdate(MetadataUpdate update) {
if (!_items.any((item) => item.path == update.path)) return;
if (!mounted) return;
safeSetState(() {
_metaByPath = {..._metaByPath, update.path: update.row};
});
}
/// 播放中的歌一旦补全了元数据,立刻刷新列表里对应的那一行
void _onPlaybackChanged() {
final path = AudioService().currentSong?.id;