Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 45 additions & 30 deletions lib/pages/download_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -791,10 +791,10 @@ class _DownloadPageState extends State<DownloadPage> {
}
}
if (!mounted || widget.runtime != runtime) return;
final count = groups.values.fold<int>(
0,
(sum, tasks) => sum + tasks.length,
);
final selected = groups.values.expand((tasks) => tasks).toList();
final count = selected.length;
final hiddenSelected =
count - _matchingDownloads(selected, _downloadFilter).length;
final confirmed = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
Expand All @@ -803,6 +803,7 @@ class _DownloadPageState extends State<DownloadPage> {
content: Text(
'共 ${groups.length} 个路径,预计释放 ${_bytes(estimatedBytes)}'
'${unknownSizes > 0 ? "(另有 $unknownSizes 个路径大小未知或文件已缺失)" : ""}。\n\n'
'${hiddenSelected > 0 ? "其中 $hiddenSelected 条已选声音不在当前搜索结果中,也将删除其音频。\n\n" : ""}'
'正在使用这些文件的播放会停止。任务和扣时记录保留;缺失文件不会记为主动删除。',
),
actions: [
Expand Down Expand Up @@ -1145,30 +1146,41 @@ class _DownloadPageState extends State<DownloadPage> {
}
}

Widget _downloadedLibrary(List<DownloadTask> completed) {
final compact = MediaQuery.sizeOf(context).width < 320;
final query = _downloadFilter;
List<DownloadTask> _matchingDownloads(
List<DownloadTask> tasks,
String query,
) {
if (query.isEmpty) return tasks;
final tokens = query
.split(RegExp(r'\s+'))
.where((value) => value.isNotEmpty);
final matches = query.isEmpty
? const <DownloadTask>[]
: completed.where((task) {
final track = task.track;
final text = [
_downloadAlbumTitle(task),
track.album,
track.title,
for (final ordinal in {
track.officialPosition,
track.orderNo,
track.episode,
}.whereType<int>())
'$ordinal 第${ordinal}集',
].join(' ').toLowerCase();
return tokens.every(text.contains);
}).toList();
final visible = query.isEmpty ? completed : matches;
return tasks.where((task) {
final track = task.track;
final text = [
_downloadAlbumTitle(task),
track.album,
track.title,
for (final ordinal in {
track.officialPosition,
track.orderNo,
track.episode,
}.whereType<int>())
'$ordinal 第${ordinal}集',
].join(' ').toLowerCase();
return tokens.every(text.contains);
}).toList();
}

Widget _downloadedLibrary(List<DownloadTask> completed) {
final compact = MediaQuery.sizeOf(context).width < 320;
final query = _downloadFilter;
final visible = _matchingDownloads(completed, query);
final hiddenSelected = query.isEmpty || _selectedDownloads.isEmpty
? 0
: _selectedDownloads.length -
visible
.where((task) => _selectedDownloads.contains(task.id))
.length;
return LayoutBuilder(
builder: (context, constraints) => Column(
children: [
Expand Down Expand Up @@ -1248,7 +1260,10 @@ class _DownloadPageState extends State<DownloadPage> {
label: const Text('多选音频'),
)
else ...[
Text('已选 ${_selectedDownloads.length} 条'),
Text(
'已选 ${_selectedDownloads.length} 条'
'${hiddenSelected > 0 ? "(含 $hiddenSelected 条未显示)" : ""}',
),
TextButton(
onPressed: _deletingAudio || visible.isEmpty
? null
Expand Down Expand Up @@ -1293,7 +1308,7 @@ class _DownloadPageState extends State<DownloadPage> {
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
child: Text(
'本地下载记录:匹配 ${matches.length} / 共 ${completed.length} 条',
'本地下载记录:匹配 ${visible.length} / 共 ${completed.length} 条',
),
),
if (query.isNotEmpty && _error != null)
Expand All @@ -1313,14 +1328,14 @@ class _DownloadPageState extends State<DownloadPage> {
Expanded(
child: query.isEmpty
? _albumList(completed, downloaded: true)
: matches.isEmpty
: visible.isEmpty
? const Center(child: Text('未找到匹配的本地下载记录'))
: Scrollbar(
child: ListView.builder(
key: ValueKey('downloadSearch:$query'),
itemCount: matches.length,
itemCount: visible.length,
itemBuilder: (context, index) => _downloadedTrack(
matches[index],
visible[index],
compact,
searchResult: true,
),
Expand Down