diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..5472856 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/mingw64/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..b02ad94 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "e:/Flutter/MusicAPP/MTMusic/linux/flutter", + "program": "e:/Flutter/MusicAPP/MTMusic/linux/flutter/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bb879da --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/assets/img/list_collection.png b/assets/img/list_collection.png index 0b6fb02..5f60bba 100644 Binary files a/assets/img/list_collection.png and b/assets/img/list_collection.png differ diff --git a/assets/img/list_collection_un.png b/assets/img/list_collection_un.png new file mode 100644 index 0000000..0b6fb02 Binary files /dev/null and b/assets/img/list_collection_un.png differ diff --git a/assets/img/list_good.png b/assets/img/list_good.png index 99fd85a..5dca998 100644 Binary files a/assets/img/list_good.png and b/assets/img/list_good.png differ diff --git a/assets/img/list_good_act.png b/assets/img/list_good_act.png deleted file mode 100644 index 5dca998..0000000 Binary files a/assets/img/list_good_act.png and /dev/null differ diff --git a/assets/img/list_good_un.png b/assets/img/list_good_un.png new file mode 100644 index 0000000..99fd85a Binary files /dev/null and b/assets/img/list_good_un.png differ diff --git a/lib/api/api_music_likes_list.dart b/lib/api/api_music_likes_list.dart new file mode 100644 index 0000000..1cd6357 --- /dev/null +++ b/lib/api/api_music_likes_list.dart @@ -0,0 +1,32 @@ +import 'package:dio/dio.dart'; +import '../models/getLikeList_bean.dart'; + +const String _LikesListURL = 'http://8.210.250.29:10010/likes/user-like-list'; + +class LikesListApi { + final Dio dio = Dio(); + + /// 获取用户点赞歌曲列表 + Future getUserLikesList({ + required String Authorization, + }) async { + try { + Response response = await dio.get( + _LikesListURL, + options: Options( + headers: { + 'Authorization': Authorization, + 'Content-Type': 'application/json;charset=UTF-8' + } + ), + ); + + print('点赞列表响应数据: ${response.data}'); + return LikeListBean.formMap(response.data); + + } catch (e) { + print('获取点赞列表失败: $e'); + rethrow; + } + } +} \ No newline at end of file diff --git a/lib/models/getLikeList_bean.dart b/lib/models/getLikeList_bean.dart new file mode 100644 index 0000000..3c26c3a --- /dev/null +++ b/lib/models/getLikeList_bean.dart @@ -0,0 +1,51 @@ +class LikeListBean { + int? code; + String? msg; + List? data; + + LikeListBean.formMap(Map map) { + code = map['code']; + msg = map['msg']; + if (map['data'] is! List) return; + + data = (map['data'] as List) + .map((item) => LikeListData._formMap(item)) + .toList(); + } +} + +class LikeListData { + int? id; + String? name; + String? coverPath; + String? musicPath; + String? singerName; + String? uploadUserName; + bool? likes; + bool? collection; + + LikeListData._formMap(Map map) { + id = map['id']; + name = map['name']; + coverPath = map['coverPath']; + musicPath = map['musicPath']; + singerName = map['singerName']; + uploadUserName = map['uploadUserName']; + likes = map['likes']; + collection = map['collection']; + } + + // 转换为Map方法,用于数据存储 + Map toJson() { + return { + 'id': id, + 'name': name, + 'coverPath': coverPath, + 'musicPath': musicPath, + 'singerName': singerName, + 'uploadUserName': uploadUserName, + 'likes': likes, + 'collection': collection, + }; + } +} \ No newline at end of file diff --git a/lib/view/home_view.dart b/lib/view/home_view.dart index 31a1214..a6ffb6c 100644 --- a/lib/view/home_view.dart +++ b/lib/view/home_view.dart @@ -12,6 +12,9 @@ import '../common_widget/Song_widegt.dart'; import '../common_widget/list_cell.dart'; import '../models/getMusicList_bean.dart'; import 'music_view.dart'; +import '../api/api_collection.dart'; +import '../api/api_music_likes.dart'; +import '../models/universal_bean.dart'; class HomeView extends StatefulWidget { const HomeView({super.key}); @@ -112,7 +115,7 @@ class _HomeViewState extends State // 如果请求成功且返回的数据不为空 if (bean.code == 200 && bean.data != null) { - // 创建一个临时列表来存储所有异步请求 + // 创���一个临时列表来存储所有异步请求 List> songDetailsFutures = []; // 循环处理每个搜索结果,通过 id 请求详细信息 @@ -428,16 +431,15 @@ class _HomeViewState extends State builder: (context) => MusicView( songList: selectedSongs, initialSongIndex: index, - onSongStatusChanged: - (index, isCollected, isLiked) { + onSongStatusChanged: (index, isCollected, isLiked) { setState(() { - selectedSongs[index].collection = - isCollected; + selectedSongs[index].collection = isCollected; selectedSongs[index].likes = isLiked; downloadManager.updateSongInfo( - selectedSongs[index].id, - isCollected, - isLiked); + selectedSongs[index].id, + isCollected, + isLiked + ); }); }, ), @@ -500,19 +502,20 @@ class _HomeViewState extends State borderRadius: BorderRadius.vertical(top: Radius.circular(30)), ), builder: (context) => StatefulBuilder( - // 使用StatefulBuilder以便动态修改状态 builder: (context, setState) { - bool likesnot = false; // 初始状态,假设未点赞 + // 获取当前歌曲的点赞和收藏状态 + bool likesnot = selectedSongs[index].likes ?? false; + bool collectionsnot = selectedSongs[index].collection ?? false; return Container( height: 150, padding: const EdgeInsets.only(top: 20), child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + // 加入歌单按钮 Column( children: [ IconButton( @@ -523,6 +526,8 @@ class _HomeViewState extends State const Text("加入歌单"), ], ), + + // 下载按钮 Column( children: [ IconButton( @@ -533,37 +538,122 @@ class _HomeViewState extends State const Text("下载"), ], ), + + // 收藏按钮及功能 Column( children: [ IconButton( - onPressed: () {}, - icon: Image.asset("assets/img/list_collection.png"), - iconSize: 60, + onPressed: () async { + // 1. 立即更新UI状态,提供即时反馈 + setState(() { + collectionsnot = !collectionsnot; + selectedSongs[index].collection = collectionsnot; + }); + + // 2. 调用收藏API + UniversalBean response = await CollectionApiMusic().addCollection( + musicId: selectedSongs[index].id, + Authorization: AppData().currentToken, + ); + + // 3. 处理API响应 + if (response.code != 200) { + // 3.1 如果API调用失败,回滚状态变化 + setState(() { + collectionsnot = !collectionsnot; + selectedSongs[index].collection = collectionsnot; + }); + } else { + // 3.2 API调用成功,更新全局状态管理器 + downloadManager.updateSongInfo( + selectedSongs[index].id, // 当前歌曲ID + collectionsnot, // 新的收藏状态 + selectedSongs[index].likes ?? false // 保持原有的点赞状态 + ); + } + }, + icon: SizedBox( + width: 60, + height: 60, + child: Image.asset( + // 根据收藏状态显示对应图标 + collectionsnot + ? "assets/img/list_collection.png" // 已收藏状态图标 + : "assets/img/list_collection_un.png" // 未收藏状态图标 + ), + ), ), const Text("收藏"), ], ), + + // 点赞按钮及功能 Column( children: [ IconButton( - onPressed: () {}, - icon: Image.asset("assets/img/list_good.png"), - iconSize: 60, + onPressed: () async { + // 1. 立即更新UI状态,提供即时反馈 + setState(() { + likesnot = !likesnot; + selectedSongs[index].likes = likesnot; + }); + + // 2. 调用点赞API + UniversalBean response = await LikesApiMusic().likesMusic( + musicId: selectedSongs[index].id, + Authorization: AppData().currentToken, + ); + + // 3. 处理API响应 + if (response.code != 200) { + // 3.1 如果API调用失败,回滚状态变化 + setState(() { + likesnot = !likesnot; + selectedSongs[index].likes = likesnot; + }); + } else { + // 3.2 API调用成功,更新全局状态管理器 + downloadManager.updateSongInfo( + selectedSongs[index].id, // 当前歌曲ID + selectedSongs[index].collection ?? false, // 保持原有的收藏状态 + likesnot // 新的点赞状态 + ); + } + }, + icon: SizedBox( + width: 60, + height: 60, + child: Image.asset( + // 根据点赞状态显示对应图标 + likesnot + ? "assets/img/list_good.png" // 已点赞状态图标 + : "assets/img/list_good_un.png" // 未点赞状态图标 + ), + ), ), - const Text("点赞") + const Text("点赞"), ], ), + + // 评论按钮 Column( children: [ IconButton( onPressed: () { + // 关闭底部弹出栏 Navigator.pop(context); - // Get.to(() => - // CommentView( - // id:, - // song:, - // singer:, - // )); + // 导航到评论页面 + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CommentView( + id: selectedSongs[index].id, + song: selectedSongs[index].title, + singer: selectedSongs[index].artist, + cover: selectedSongs[index].artistPic, + ), + ), + ); }, icon: Image.asset("assets/img/list_comment.png"), iconSize: 60, diff --git a/lib/view/rank_view.dart b/lib/view/rank_view.dart index 9a8c633..bece2d6 100644 --- a/lib/view/rank_view.dart +++ b/lib/view/rank_view.dart @@ -7,6 +7,12 @@ import '../models/getRank_bean.dart'; import '../view_model/rank_view_model.dart'; import 'music_view.dart'; import '../common_widget/Song_widegt.dart'; +import '../api/api_collection.dart'; +import '../api/api_music_likes.dart'; +import '../api/api_music_list.dart'; +import '../models/universal_bean.dart'; +import 'comment_view.dart'; +import '../models/getMusicList_bean.dart'; class RankView extends StatefulWidget { const RankView({super.key}); @@ -309,77 +315,167 @@ class _RankViewState extends State with AutomaticKeepAliveClientMixin Future _bottomSheet(BuildContext context, int index) { return showModalBottomSheet( - context: context, - backgroundColor: Colors.white, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.vertical(top: Radius.circular(30)) - ), - builder: (context) => Container( - height: 150, - padding: const EdgeInsets.only(top: 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Column( - children: [ - IconButton( - onPressed: (){}, - icon: Image.asset("assets/img/list_add.png"), - iconSize: 60, - ), - const Text("加入歌单") - ], - ), - Column( - children: [ - IconButton( - onPressed: (){}, - icon: Image.asset("assets/img/list_download.png"), - iconSize: 60, - ), - const Text("下载") - ], - ), - Column( - children: [ - IconButton( - onPressed: (){}, - icon: Image.asset("assets/img/list_collection.png"), - iconSize: 60, - ), - const Text("收藏") - ], - ), - Column( - children: [ - IconButton( - onPressed: (){}, - icon: Image.asset("assets/img/list_good.png"), - iconSize: 60, - ), - const Text("点赞") - ], - ), - Column( - children: [ - IconButton( - onPressed: (){ - Navigator.pop(context); - }, - icon: Image.asset("assets/img/list_comment.png"), - iconSize: 60, - ), - const Text("评论") - ], - ), - ], - ), - ], - ), - ) + context: context, + backgroundColor: Colors.white, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(30)), + ), + builder: (context) => StatefulBuilder( + builder: (context, setState) { + // 获取当前歌曲的点赞和收藏状态 + bool likesnot = songs[index].likes ?? false; + bool collectionsnot = songs[index].collection ?? false; + + return Container( + height: 150, + padding: const EdgeInsets.only(top: 20), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + IconButton( + onPressed: (){}, + icon: Image.asset("assets/img/list_add.png"), + iconSize: 60, + ), + const Text("加入歌单") + ], + ), + Column( + children: [ + IconButton( + onPressed: (){}, + icon: Image.asset("assets/img/list_download.png"), + iconSize: 60, + ), + const Text("下载") + ], + ), + Column( + children: [ + IconButton( + onPressed: () async { + // 1. 立即更新UI显示,优化用户体验 + setState(() { + collectionsnot = !collectionsnot; + songs[index].collection = collectionsnot; + }); + + // 2. 调用收藏API + UniversalBean response = await CollectionApiMusic().addCollection( + musicId: songs[index].id, + Authorization: AppData().currentToken, + ); + + // 3. 处理API响应 + if (response.code != 200) { + // 如果API调用失败,恢复原状态 + setState(() { + collectionsnot = !collectionsnot; + songs[index].collection = collectionsnot; + }); + } else { + // 4. API调用成功,更新全局状态 + downloadManager.updateSongInfo( + songs[index].id, // 歌曲ID + collectionsnot, // 新的收藏状态 + songs[index].likes ?? false // 保持原有的点赞状态 + ); + } + }, + icon: SizedBox( + width: 60, + height: 60, + child: Image.asset( + // 根据收藏状态显示不同图标 + collectionsnot + ? "assets/img/list_collection.png" // 已收藏图标 + : "assets/img/list_collection_un.png" // 未收藏图标 + ), + ), + ), + const Text("收藏"), + ], + ), + Column( + children: [ + IconButton( + onPressed: () async { + // 1. 立即更新UI显示,优化用户体验 + setState(() { + likesnot = !likesnot; + songs[index].likes = likesnot; + }); + + // 2. 调用点赞API + UniversalBean response = await LikesApiMusic().likesMusic( + musicId: songs[index].id, + Authorization: AppData().currentToken, + ); + + // 3. 处理API响应 + if (response.code != 200) { + // 如果API调用失败,恢复原状态 + setState(() { + likesnot = !likesnot; + songs[index].likes = likesnot; + }); + } else { + // 4. API调用成功,更新全局状态 + downloadManager.updateSongInfo( + songs[index].id, // 歌曲ID + songs[index].collection ?? false, // 保持原有的收藏状态 + likesnot // 新的点赞状态 + ); + } + }, + icon: SizedBox( + width: 60, + height: 60, + child: Image.asset( + // 根据点赞状态显示不同图标 + likesnot + ? "assets/img/list_good.png" // 已点赞图标 + : "assets/img/list_good_un.png" // 未点赞图标 + ), + ), + ), + const Text("点赞"), + ], + ), + Column( + children: [ + IconButton( + onPressed: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CommentView( + id: songs[index].id, + song: songs[index].title, + singer: songs[index].artist, + cover: songs[index].artistPic, + ), + ), + ); + }, + icon: Image.asset("assets/img/list_comment.png"), + iconSize: 60, + ), + const Text("评论") + ], + ), + ], + ), + ], + ), + ); + }, + ), ); } } \ No newline at end of file diff --git a/lib/view/user/my_likes_view.dart b/lib/view/user/my_likes_view.dart new file mode 100644 index 0000000..d3048ff --- /dev/null +++ b/lib/view/user/my_likes_view.dart @@ -0,0 +1,409 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:music_player_miao/api/api_music_likes_list.dart'; +import 'package:music_player_miao/common_widget/app_data.dart'; +import 'package:music_player_miao/models/getLikeList_bean.dart'; +import 'package:music_player_miao/view_model/home_view_model.dart'; +import '../music_view.dart'; +import '../../common_widget/Song_widegt.dart'; +import '../../common/download_manager.dart'; + +/// 我的点赞页面 +class MyLikesView extends StatefulWidget { + const MyLikesView({Key? key}) : super(key: key); + + @override + State createState() => _MyLikesViewState(); +} + +class _MyLikesViewState extends State { + // 存储已点赞歌曲的列表 + List likedSongs = []; + // 是否处于多选模式 + bool _isSelectMode = false; + // 记录每首歌曲是否被选中的状态 + List _selectedItems = []; + // 获取全局状态管理器实例 + final listVM = Get.put(HomeViewModel()); + final downloadManager = Get.put(DownloadManager()); + + @override + void initState() { + super.initState(); + // 页面初始化时获取点赞歌曲列表 + _fetchLikedSongs(); + } + + /// 从服务器获取用户点赞的歌曲列表 + Future _fetchLikedSongs() async { + try { + // 调用API获取点赞列表 + LikeListBean response = await LikesListApi().getUserLikesList( + Authorization: AppData().currentToken, + ); + + // 如果请求成功且数据不为空,更新状态 + if (response.code == 200 && response.data != null) { + setState(() { + likedSongs = response.data!; + // 初始化选中状态列表,默认全部未选中 + _selectedItems = List.generate(likedSongs.length, (index) => false); + }); + } + } catch (error) { + print('Error fetching liked songs: $error'); + } + } + + @override + Widget build(BuildContext context) { + return Container( + // 设置背景图片 + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage("assets/img/app_bg.png"), + fit: BoxFit.cover, + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + // 自定义应用栏 + appBar: AppBar( + backgroundColor: Colors.transparent, + centerTitle: true, + elevation: 0, + // 根据是否是多选模式显示不同的前导图标 + leading: !_isSelectMode + ? IconButton( // 非多选模式显示返回按钮 + onPressed: () { + Get.back(result: true); + }, + icon: Image.asset( + "assets/img/back.png", + width: 25, + height: 25, + fit: BoxFit.contain, + ), + ) + : TextButton( // 多选模式显示全选按钮 + onPressed: () { + setState(() { + _selectedItems = List.generate(likedSongs.length, (index) => true); + }); + }, + style: TextButton.styleFrom( + foregroundColor: Colors.black, + minimumSize: const Size(50, 40), + padding: const EdgeInsets.symmetric(horizontal: 8), + ), + child: const Text( + '全选', + style: TextStyle(fontSize: 18), + ), + ), + // 根据是否是多选模式显示不同的标题 + title: _isSelectMode + ? Text( + '已选中 ${_selectedItems.where((item) => item).length} 首歌曲', + style: const TextStyle( + color: Colors.black, + ), + ) + : const Text( + '我的点赞', + style: TextStyle(color: Colors.black), + ), + // 多选模式下显示完成按钮 + actions: [ + if (_isSelectMode) + TextButton( + onPressed: () { + setState(() { + _isSelectMode = false; + _selectedItems = List.generate(likedSongs.length, (index) => false); + }); + }, + child: const Text( + "完成", + style: TextStyle(color: Colors.black, fontSize: 18), + )) + ], + ), + // 主体内容 + body: Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(30)), + ), + child: Column( + children: [ + // 顶部操作栏 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // 播放全部按钮组 + Row( + children: [ + IconButton( + onPressed: likedSongs.isEmpty + ? null + : () { + // TODO: 实现播放全部功能 + }, + icon: Image.asset( + "assets/img/button_play.png", + width: 20, + height: 20, + ), + ), + const Text( + '播放全部', + style: TextStyle(fontSize: 16), + ), + const SizedBox(width: 5), + Text( + '(${likedSongs.length})', + style: const TextStyle(fontSize: 16), + ), + ], + ), + // 多选模式切换按钮 + IconButton( + onPressed: likedSongs.isEmpty ? null : () { + setState(() { + _isSelectMode = !_isSelectMode; + if (!_isSelectMode) { + _selectedItems = List.generate(likedSongs.length, (index) => false); + } + }); + }, + icon: Image.asset( + "assets/img/list_op.png", + width: 20, + height: 20, + ), + ), + ], + ), + ), + // 歌曲列表 + Expanded( + child: ListView.builder( + itemCount: likedSongs.length, + padding: EdgeInsets.zero, + itemBuilder: (context, index) { + final song = likedSongs[index]; + return ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 16.0), + // 根据是否是多选模式执行不同的点击操作 + onTap: _isSelectMode + ? () { + setState(() { + _selectedItems[index] = !_selectedItems[index]; + }); + } + : () async { + // 创建Song对象列表用于播放 + List songList = likedSongs.map((song) => Song( + id: song.id ?? 0, + title: song.name ?? '未知歌曲', + artist: song.singerName ?? '未知歌手', + artistPic: song.coverPath ?? '', + pic: song.coverPath ?? '', + musicurl: song.musicPath ?? '', + likes: song.likes, + collection: song.collection, + )).toList(); + + // 导航到音乐播放页面 + final result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MusicView( + songList: songList, + initialSongIndex: index, + // 歌曲状态变化回调 + onSongStatusChanged: (index, isCollected, isLiked) { + setState(() { + songList[index].collection = isCollected; + songList[index].likes = isLiked; + downloadManager.updateSongInfo( + songList[index].id, + isCollected, + isLiked, + ); + }); + }, + ), + ), + ); + + // 从播放页面返回时刷新列表 + if (result != null) { + _fetchLikedSongs(); + } + }, + // 歌曲列表项布局 + title: Row( + children: [ + // 多选模式下显示复选框 + if (_isSelectMode) + Checkbox( + value: _selectedItems[index], + onChanged: (value) { + setState(() { + _selectedItems[index] = value!; + }); + }, + shape: const CircleBorder(), + activeColor: const Color(0xff429482), + ), + // 歌曲封面图 + ClipRRect( + borderRadius: BorderRadius.circular(10), + child: Image.network( + song.coverPath ?? '', + width: 60, + height: 60, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) { + return Image.asset( + "assets/img/artist_pic.png", + width: 60, + height: 60, + ); + }, + ), + ), + const SizedBox(width: 12), + // 歌曲信息 + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + song.name ?? '未知歌曲', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 16, + color: Colors.black, + ), + ), + Text( + song.singerName ?? '未知歌手', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 14, + color: Colors.black54, + ), + ), + ], + ), + ), + ], + ), + ); + }, + ), + ), + ], + ), + ), + // 多选模式下显示底部操作栏 + bottomNavigationBar: _isSelectMode + ? BottomAppBar( + height: 140, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // 底部操作按钮 + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + // "添加到"按钮 + Expanded( + child: InkWell( + onTap: () { + // TODO: 实现添加到功能 + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 25, + height: 25, + child: Image.asset("assets/img/add.png"), + ), + const SizedBox(width: 4), + const Text("添加到"), + ], + ), + ), + ), + // 分隔线 + Container( + height: 50, + width: 2, + color: const Color(0xff429482), + ), + // "删除"按钮 + Expanded( + child: InkWell( + onTap: () { + // TODO: 实现批量删除功能 + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 22, + height: 22, + child: Image.asset("assets/img/delete.png"), + ), + const SizedBox(width: 4), + const Text("删除"), + ], + ), + ), + ), + ], + ), + ), + // 取消按钮 + ElevatedButton( + onPressed: () { + setState(() { + _isSelectMode = false; + _selectedItems = List.generate(likedSongs.length, (index) => false); + }); + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xff429482), + padding: const EdgeInsets.symmetric(vertical: 14), + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + ), + ), + child: const Text( + '取消', + style: TextStyle(color: Colors.black, fontSize: 16), + ), + ), + ], + ), + ), + ) + : null, + ), + ); + } +} \ No newline at end of file diff --git a/lib/view/user/user_view.dart b/lib/view/user/user_view.dart index b7fad99..7cbe628 100644 --- a/lib/view/user/user_view.dart +++ b/lib/view/user/user_view.dart @@ -16,6 +16,9 @@ import '../../api/api_client.dart'; import '../../common/download_manager.dart'; import '../../models/search_bean.dart'; import 'my_work_view.dart'; +import 'my_likes_view.dart'; +import 'package:music_player_miao/api/api_music_likes_list.dart'; // 点赞列表API +import 'package:music_player_miao/models/getLikeList_bean.dart'; // 点赞列表数据模型 class UserView extends StatefulWidget { const UserView({super.key}); @@ -33,6 +36,7 @@ class _UserViewState extends State with AutomaticKeepAliveClientMixin int downloadCount = 0; String avatar = AppData().currentAvatar; String username = AppData().currentUsername; + int likesCount = 0; final downloadManager = Get.put(DownloadManager()); @@ -44,6 +48,7 @@ class _UserViewState extends State with AutomaticKeepAliveClientMixin super.initState(); _fetchSonglistData(); downloadCount = downloadManager.completedNumber(); + _fetchLikesCount(); } Future _fetchSonglistData() async { @@ -62,6 +67,22 @@ class _UserViewState extends State with AutomaticKeepAliveClientMixin } } + Future _fetchLikesCount() async { + try { + LikeListBean response = await LikesListApi().getUserLikesList( + Authorization: AppData().currentToken, + ); + + if (response.code == 200 && response.data != null) { + setState(() { + likesCount = response.data!.length; + }); + } + } catch (error) { + print('Error fetching likes count: $error'); + } + } + @override Widget build(BuildContext context) { super.build(context); @@ -125,10 +146,50 @@ class _UserViewState extends State with AutomaticKeepAliveClientMixin padding: const EdgeInsets.only( left: 15, right: 15, top: 20, bottom: 20), - //我的收藏 + //我的收藏,点赞,下载 child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ + // 我的点赞 + InkWell( + onTap: () async { + final result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const MyLikesView(), + ), + ); + + if (result == true) { + _fetchLikesCount(); + } + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Image.asset("assets/img/artist_pic.png"), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + "我的点赞", + style: TextStyle(fontSize: 20), + ), + Text( + "$likesCount首", + style: const TextStyle(fontSize: 16), + ), + ], + ), + const SizedBox(width: 80), + Image.asset("assets/img/user_next.png") + ], + ), + ), + + const SizedBox(height: 10), + + // 我的收藏 InkWell( onTap: () { Navigator.push( @@ -155,28 +216,22 @@ class _UserViewState extends State with AutomaticKeepAliveClientMixin ), ], ), - const SizedBox( - width: 80, - ), - Image.asset( - "assets/img/user_next.png", - ) + const SizedBox(width: 80), + Image.asset("assets/img/user_next.png") ], ), ), - const SizedBox( - height: 10, - ), + const SizedBox(height: 10), - //我的收藏和本地下载分界 + // 本地下载 InkWell( onTap: () async { final result = await Navigator.push( context, - MaterialPageRoute( + MaterialPageRoute( builder: (context) => MyDownloadView(), - ), + ), ); if (result == true) { @@ -184,7 +239,6 @@ class _UserViewState extends State with AutomaticKeepAliveClientMixin downloadCount = downloadManager.completedNumber(); }); } - }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -203,12 +257,8 @@ class _UserViewState extends State with AutomaticKeepAliveClientMixin ), ], ), - const SizedBox( - width: 80, - ), - Image.asset( - "assets/img/user_next.png", - ) + const SizedBox(width: 80), + Image.asset("assets/img/user_next.png") ], ), ), diff --git a/pubspec.lock b/pubspec.lock index ced97e0..7201580 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: async sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.11.0" audio_session: @@ -14,7 +14,7 @@ packages: description: name: audio_session sha256: "343e83bc7809fbda2591a49e525d6b63213ade10c76f15813be9aed6657b3261" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.1.21" audioplayers: @@ -22,7 +22,7 @@ packages: description: name: audioplayers sha256: c05c6147124cd63e725e861335a8b4d57300b80e6e92cea7c145c739223bbaef - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.2.1" audioplayers_android: @@ -30,7 +30,7 @@ packages: description: name: audioplayers_android sha256: b00e1a0e11365d88576320ec2d8c192bc21f1afb6c0e5995d1c57ae63156acb5 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.0.3" audioplayers_darwin: @@ -38,7 +38,7 @@ packages: description: name: audioplayers_darwin sha256: "3034e99a6df8d101da0f5082dcca0a2a99db62ab1d4ddb3277bed3f6f81afe08" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.0.2" audioplayers_linux: @@ -46,7 +46,7 @@ packages: description: name: audioplayers_linux sha256: "60787e73fefc4d2e0b9c02c69885402177e818e4e27ef087074cf27c02246c9e" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.1.0" audioplayers_platform_interface: @@ -54,7 +54,7 @@ packages: description: name: audioplayers_platform_interface sha256: "365c547f1bb9e77d94dd1687903a668d8f7ac3409e48e6e6a3668a1ac2982adb" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.1.0" audioplayers_web: @@ -62,7 +62,7 @@ packages: description: name: audioplayers_web sha256: "22cd0173e54d92bd9b2c80b1204eb1eb159ece87475ab58c9788a70ec43c2a62" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.1.0" audioplayers_windows: @@ -70,7 +70,7 @@ packages: description: name: audioplayers_windows sha256: "9536812c9103563644ada2ef45ae523806b0745f7a78e89d1b5fb1951de90e1a" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.1.0" boolean_selector: @@ -78,7 +78,7 @@ packages: description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.1" characters: @@ -86,7 +86,7 @@ packages: description: name: characters sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.3.0" clock: @@ -94,7 +94,7 @@ packages: description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.1" collection: @@ -102,7 +102,7 @@ packages: description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.18.0" cross_file: @@ -110,7 +110,7 @@ packages: description: name: cross_file sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.3.4+2" crypto: @@ -118,7 +118,7 @@ packages: description: name: crypto sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.6" cupertino_icons: @@ -126,7 +126,7 @@ packages: description: name: cupertino_icons sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.8" dio: @@ -134,7 +134,7 @@ packages: description: name: dio sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.7.0" dio_web_adapter: @@ -142,7 +142,7 @@ packages: description: name: dio_web_adapter sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.0.0" fake_async: @@ -150,7 +150,7 @@ packages: description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.3.1" ffi: @@ -158,7 +158,7 @@ packages: description: name: ffi sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.3" file: @@ -166,7 +166,7 @@ packages: description: name: file sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "7.0.1" file_picker: @@ -174,7 +174,7 @@ packages: description: name: file_picker sha256: "1bbf65dd997458a08b531042ec3794112a6c39c07c37ff22113d2e7e4f81d4e4" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.2.1" file_selector_linux: @@ -182,7 +182,7 @@ packages: description: name: file_selector_linux sha256: b2b91daf8a68ecfa4a01b778a6f52edef9b14ecd506e771488ea0f2e0784198b - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.9.3+1" file_selector_macos: @@ -190,7 +190,7 @@ packages: description: name: file_selector_macos sha256: "271ab9986df0c135d45c3cdb6bd0faa5db6f4976d3e4b437cf7d0f258d941bfc" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.9.4+2" file_selector_platform_interface: @@ -198,7 +198,7 @@ packages: description: name: file_selector_platform_interface sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.6.2" file_selector_windows: @@ -206,7 +206,7 @@ packages: description: name: file_selector_windows sha256: "8f5d2f6590d51ecd9179ba39c64f722edc15226cc93dcc8698466ad36a4a85a4" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.9.3+3" fixnum: @@ -214,7 +214,7 @@ packages: description: name: fixnum sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.1" flutter: @@ -227,7 +227,7 @@ packages: description: name: flutter_lints sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.0.3" flutter_plugin_android_lifecycle: @@ -235,7 +235,7 @@ packages: description: name: flutter_plugin_android_lifecycle sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.0.23" flutter_swiper_view: @@ -243,7 +243,7 @@ packages: description: name: flutter_swiper_view sha256: "2a165b259e8a4c49d4da5626b967ed42a73dac2d075bd9e266ad8d23b9f01879" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.8" flutter_test: @@ -261,7 +261,7 @@ packages: description: name: get sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.6.6" get_storage: @@ -269,7 +269,7 @@ packages: description: name: get_storage sha256: "39db1fffe779d0c22b3a744376e86febe4ade43bf65e06eab5af707dc84185a2" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.1" http: @@ -277,7 +277,7 @@ packages: description: name: http sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.2" http_parser: @@ -285,7 +285,7 @@ packages: description: name: http_parser sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.0.2" image_picker: @@ -293,7 +293,7 @@ packages: description: name: image_picker sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.2" image_picker_android: @@ -301,7 +301,7 @@ packages: description: name: image_picker_android sha256: "8faba09ba361d4b246dc0a17cb4289b3324c2b9f6db7b3d457ee69106a86bd32" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.8.12+17" image_picker_for_web: @@ -309,7 +309,7 @@ packages: description: name: image_picker_for_web sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.6" image_picker_ios: @@ -317,7 +317,7 @@ packages: description: name: image_picker_ios sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.8.12+1" image_picker_linux: @@ -325,7 +325,7 @@ packages: description: name: image_picker_linux sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1+1" image_picker_macos: @@ -333,7 +333,7 @@ packages: description: name: image_picker_macos sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1+1" image_picker_platform_interface: @@ -341,7 +341,7 @@ packages: description: name: image_picker_platform_interface sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.10.0" image_picker_windows: @@ -349,23 +349,23 @@ packages: description: name: image_picker_windows sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1+1" js: dependency: transitive description: name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" + sha256: cf7243a0c29626284ada2add68a33f5b1102affe3509393e75136e0f6616bd68 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "0.6.7" + version: "0.6.8" just_audio: dependency: "direct main" description: name: just_audio sha256: a49e7120b95600bd357f37a2bb04cd1e88252f7cdea8f3368803779b925b1049 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.9.42" just_audio_platform_interface: @@ -373,7 +373,7 @@ packages: description: name: just_audio_platform_interface sha256: "0243828cce503c8366cc2090cefb2b3c871aa8ed2f520670d76fd47aa1ab2790" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.3.0" just_audio_web: @@ -381,7 +381,7 @@ packages: description: name: just_audio_web sha256: "9a98035b8b24b40749507687520ec5ab404e291d2b0937823ff45d92cb18d448" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.4.13" leak_tracker: @@ -389,7 +389,7 @@ packages: description: name: leak_tracker sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "10.0.5" leak_tracker_flutter_testing: @@ -397,7 +397,7 @@ packages: description: name: leak_tracker_flutter_testing sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.5" leak_tracker_testing: @@ -405,7 +405,7 @@ packages: description: name: leak_tracker_testing sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.1" lints: @@ -413,7 +413,7 @@ packages: description: name: lints sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.1" matcher: @@ -421,7 +421,7 @@ packages: description: name: matcher sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.12.16+1" material_color_utilities: @@ -429,7 +429,7 @@ packages: description: name: material_color_utilities sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.11.1" meta: @@ -437,7 +437,7 @@ packages: description: name: meta sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.15.0" mime: @@ -445,7 +445,7 @@ packages: description: name: mime sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.0.0" nested: @@ -453,7 +453,7 @@ packages: description: name: nested sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.0" path: @@ -461,7 +461,7 @@ packages: description: name: path sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.9.0" path_provider: @@ -469,7 +469,7 @@ packages: description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.5" path_provider_android: @@ -477,7 +477,7 @@ packages: description: name: path_provider_android sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.2.12" path_provider_foundation: @@ -485,7 +485,7 @@ packages: description: name: path_provider_foundation sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.0" path_provider_linux: @@ -493,7 +493,7 @@ packages: description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.2.1" path_provider_platform_interface: @@ -501,7 +501,7 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.2" path_provider_windows: @@ -509,7 +509,7 @@ packages: description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.3.0" permission_handler: @@ -517,7 +517,7 @@ packages: description: name: permission_handler sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "11.3.1" permission_handler_android: @@ -525,7 +525,7 @@ packages: description: name: permission_handler_android sha256: "71bbecfee799e65aff7c744761a57e817e73b738fedf62ab7afd5593da21f9f1" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "12.0.13" permission_handler_apple: @@ -533,23 +533,23 @@ packages: description: name: permission_handler_apple sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "9.4.5" permission_handler_html: dependency: transitive description: name: permission_handler_html - sha256: af26edbbb1f2674af65a8f4b56e1a6f526156bc273d0e65dd8075fab51c78851 - url: "https://pub.dev" + sha256: "6b9cb54b7135073841a35513fba39e598b421702d5f4d92319992fd6eb5532a9" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "0.1.3+2" + version: "0.1.3+4" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface sha256: e9c8eadee926c4532d0305dff94b85bf961f16759c3af791486613152af4b4f9 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.2.3" permission_handler_windows: @@ -557,7 +557,7 @@ packages: description: name: permission_handler_windows sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1" platform: @@ -565,7 +565,7 @@ packages: description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.1.6" plugin_platform_interface: @@ -573,7 +573,7 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.8" provider: @@ -581,7 +581,7 @@ packages: description: name: provider sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.1.2" rxdart: @@ -589,7 +589,7 @@ packages: description: name: rxdart sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.28.0" shared_preferences: @@ -597,7 +597,7 @@ packages: description: name: shared_preferences sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.3.3" shared_preferences_android: @@ -605,7 +605,7 @@ packages: description: name: shared_preferences_android sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.3.3" shared_preferences_foundation: @@ -613,7 +613,7 @@ packages: description: name: shared_preferences_foundation sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.5.3" shared_preferences_linux: @@ -621,7 +621,7 @@ packages: description: name: shared_preferences_linux sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" shared_preferences_platform_interface: @@ -629,7 +629,7 @@ packages: description: name: shared_preferences_platform_interface sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" shared_preferences_web: @@ -637,7 +637,7 @@ packages: description: name: shared_preferences_web sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.2" shared_preferences_windows: @@ -645,7 +645,7 @@ packages: description: name: shared_preferences_windows sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" sky_engine: @@ -658,7 +658,7 @@ packages: description: name: source_span sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.10.0" sprintf: @@ -666,7 +666,7 @@ packages: description: name: sprintf sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "7.0.0" stack_trace: @@ -674,7 +674,7 @@ packages: description: name: stack_trace sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.11.1" stream_channel: @@ -682,7 +682,7 @@ packages: description: name: stream_channel sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.2" string_scanner: @@ -690,7 +690,7 @@ packages: description: name: string_scanner sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.0" synchronized: @@ -698,7 +698,7 @@ packages: description: name: synchronized sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.3.0+3" term_glyph: @@ -706,7 +706,7 @@ packages: description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.1" test_api: @@ -714,7 +714,7 @@ packages: description: name: test_api sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.7.2" typed_data: @@ -722,7 +722,7 @@ packages: description: name: typed_data sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.4.0" uuid: @@ -730,7 +730,7 @@ packages: description: name: uuid sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.5.1" vector_math: @@ -738,7 +738,7 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.4" vm_service: @@ -746,7 +746,7 @@ packages: description: name: vm_service sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "14.2.5" web: @@ -754,7 +754,7 @@ packages: description: name: web sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.0" win32: @@ -762,7 +762,7 @@ packages: description: name: win32 sha256: "84ba388638ed7a8cb3445a320c8273136ab2631cd5f2c57888335504ddab1bc2" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.8.0" xdg_directories: @@ -770,7 +770,7 @@ packages: description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.0" sdks: