254 lines
9.8 KiB
Dart
254 lines
9.8 KiB
Dart
// lib/pages/home_page.dart
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import '../services/audio_service.dart';
|
|
import '../widgets/mini_player_bar.dart';
|
|
|
|
class HomePage extends StatelessWidget {
|
|
const HomePage({super.key});
|
|
|
|
// 收藏数据(从你的 ASCII 图提取)
|
|
final List<Map<String, String>> _favorites = const [
|
|
{'title': '暧昧', 'artist': '王菲', 'format': 'flac', 'tag': 'openlist'},
|
|
{'title': '清平调(独唱版)', 'artist': '王菲', 'format': 'flac', 'tag': 'openlist'},
|
|
{
|
|
'title': 'Rain in the Park',
|
|
'artist': 'Marika Takeuchi',
|
|
'format': 'flac',
|
|
'tag': 'openlist'
|
|
},
|
|
];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final audioService = context.watch<AudioService>();
|
|
final showMiniBar = audioService.currentSong != null;
|
|
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFF0E1211),
|
|
// ---------- 主体:可滚动内容 ----------
|
|
body: Column(
|
|
children: [
|
|
Expanded(
|
|
child: SingleChildScrollView(
|
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const SizedBox(height: 48),
|
|
// ---------- 顶部标题栏 ----------
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
const Text(
|
|
'清听',
|
|
style: TextStyle(
|
|
fontSize: 28,
|
|
fontWeight: FontWeight.w600,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
IconButton(
|
|
icon: const Icon(Icons.menu, color: Colors.white54),
|
|
onPressed: () {
|
|
// 后续:菜单入口
|
|
},
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 28),
|
|
|
|
// ---------- 【媒体库】区域 ----------
|
|
const Text(
|
|
'媒体库',
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.w500,
|
|
color: Color(0xFFB8D4D0),
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
|
|
// ---- WebDAV 连接状态卡片 ----
|
|
Container(
|
|
padding: const EdgeInsets.all(16),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF1A2A2A),
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(
|
|
color: const Color(0xFF2A4A4A), width: 0.5),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.cloud_outlined,
|
|
color: Color(0xFFB8D4D0), size: 24),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text(
|
|
'WebDAV',
|
|
style: TextStyle(
|
|
fontSize: 16, fontWeight: FontWeight.w500),
|
|
),
|
|
Text(
|
|
'username@nas', // 后续替换为真实用户名
|
|
style: TextStyle(
|
|
fontSize: 13, color: Colors.grey[400]),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 12, vertical: 4),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF4CAF50).withOpacity(0.15),
|
|
borderRadius: BorderRadius.circular(20),
|
|
),
|
|
child: const Text(
|
|
'已连接',
|
|
style: TextStyle(
|
|
fontSize: 12, color: Color(0xFF4CAF50)),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 20),
|
|
|
|
// ---- 三个功能入口(横向三列) ----
|
|
Row(
|
|
children: [
|
|
_buildEntryCard(Icons.music_note, '本地音乐'),
|
|
const SizedBox(width: 12),
|
|
_buildEntryCard(Icons.history, '最近播放'),
|
|
const SizedBox(width: 12),
|
|
_buildEntryCard(Icons.playlist_play, '歌单列表'),
|
|
],
|
|
),
|
|
const SizedBox(height: 32),
|
|
|
|
// ---------- 【我的收藏】区域 ----------
|
|
Row(
|
|
children: [
|
|
const Icon(Icons.favorite,
|
|
color: Color(0xFFB8D4D0), size: 20),
|
|
const SizedBox(width: 8),
|
|
const Text(
|
|
'我的收藏',
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.w500,
|
|
color: Color(0xFFB8D4D0),
|
|
),
|
|
),
|
|
const Spacer(),
|
|
TextButton(
|
|
onPressed: () {},
|
|
child: const Text(
|
|
'查看全部',
|
|
style: TextStyle(fontSize: 13, color: Colors.grey),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 8),
|
|
|
|
// ---- 收藏列表 ----
|
|
ListView.separated(
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemCount: _favorites.length,
|
|
separatorBuilder: (_, __) => const Divider(
|
|
color: Colors.white10,
|
|
height: 1,
|
|
),
|
|
itemBuilder: (context, index) {
|
|
final song = _favorites[index];
|
|
return ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
leading: Container(
|
|
width: 40,
|
|
height: 40,
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF2A3332),
|
|
borderRadius: BorderRadius.circular(6),
|
|
),
|
|
child: const Icon(Icons.music_note,
|
|
color: Colors.white38, size: 20),
|
|
),
|
|
title: Text(
|
|
'${song['title']} - ${song['artist']}.${song['format']}',
|
|
style: const TextStyle(
|
|
fontSize: 15, fontWeight: FontWeight.w400),
|
|
),
|
|
subtitle: Text(
|
|
song['tag']!,
|
|
style:
|
|
TextStyle(fontSize: 12, color: Colors.grey[500]),
|
|
),
|
|
trailing: Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 10, vertical: 4),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF2A4A4A).withOpacity(0.4),
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: Text(
|
|
song['tag']!,
|
|
style: const TextStyle(
|
|
fontSize: 11, color: Color(0xFF7C9A9E)),
|
|
),
|
|
),
|
|
onTap: () {
|
|
// 后续:播放该歌曲
|
|
},
|
|
);
|
|
},
|
|
),
|
|
const SizedBox(height: 80), // 底部留空,避免被播放栏遮挡
|
|
],
|
|
),
|
|
),
|
|
),
|
|
// ---------- 底部全局播放控制栏(固定) ----------
|
|
if (showMiniBar) const MiniPlayerBar(),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 功能入口卡片(横向三列共用)
|
|
Widget _buildEntryCard(IconData icon, String label) {
|
|
return Expanded(
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 14),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF1A1F1E),
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(color: Colors.grey[800]!, width: 0.5),
|
|
),
|
|
child: InkWell(
|
|
borderRadius: BorderRadius.circular(12),
|
|
onTap: () {
|
|
// 后续跳转
|
|
},
|
|
child: Column(
|
|
children: [
|
|
Icon(icon, size: 28, color: const Color(0xFFB8D4D0)),
|
|
const SizedBox(height: 6),
|
|
Text(
|
|
label,
|
|
style:
|
|
const TextStyle(fontSize: 13, fontWeight: FontWeight.w400),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|