import 'package:background_downloader/background_downloader.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:tone_snap/components/base_easyloading.dart'; import 'package:tone_snap/components/dialog/remind_dialog.dart'; import 'package:tone_snap/components/my_marquee_text.dart'; import 'package:tone_snap/components/network_image_widget.dart'; import 'package:tone_snap/data/models/music_model.dart'; import 'package:tone_snap/data/storage/offline_box.dart'; import 'package:tone_snap/generated/assets.dart'; import 'package:tone_snap/global/download_manager.dart'; import 'package:tone_snap/modules/sideb/controllers/music_player_controller.dart'; import 'package:tone_snap/modules/sideb/more_bottom_sheet/more_bottom_sheet_view.dart'; import 'package:tone_snap/modules/sideb/offline/offline_controller.dart'; import 'package:tone_snap/modules/sideb/personal_music_library/personal_music_library_controller.dart'; import 'package:tone_snap/res/themes/app_colors.dart'; import 'package:tone_snap/utils/obj_util.dart'; class MusicItem extends StatelessWidget { MusicItem({ super.key, required this.musicModel, required this.onTapItem, this.showDownload = true, this.showMore = true, this.playlistModelId, }); final musicPlayerController = MusicPlayerController.to; final Rx musicModel; final Function() onTapItem; final bool showDownload; final bool showMore; final String? playlistModelId; @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: InkWell( onTap: onTapItem, child: Padding( padding: EdgeInsets.symmetric(vertical: 8.h), child: Row( children: [ SizedBox(width: 18.w), _buildCover(), SizedBox(width: 12.w), _buildContent(), SizedBox(width: 8.w), if (showDownload) ...[ _buildDownload(), SizedBox(width: 4.w), ], if (showMore) ...[ _buildMore(), SizedBox(width: 4.w), ], SizedBox(width: 10.w), ], ), ), ), ); } Widget _buildCover() { return Obx(() { return NetworkImageWidget( url: musicModel.value.coverUrl, width: 60.w, height: 60.w, radius: 8.r, ); }); } Widget _buildContent() { return Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Obx(() { bool isCurrentPlayModel = ObjUtil.isNotEmpty(musicModel.value.videoId) && musicPlayerController.getMusicModel()?.value.videoId == musicModel.value.videoId; return Visibility( visible: isCurrentPlayModel, replacement: Text( ObjUtil.getStr(musicModel.value.title), maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: Colors.white, fontSize: 14.sp, ), ), child: MyMarqueeText( text: ObjUtil.getStr(musicModel.value.title), textStyle: TextStyle( color: seedColor, fontSize: 14.sp, ), ), ); }), SizedBox(height: 4.h), Obx(() { bool isCurrentPlayModel = ObjUtil.isNotEmpty(musicModel.value.videoId) && musicPlayerController.getMusicModel()?.value.videoId == musicModel.value.videoId; return Visibility( visible: isCurrentPlayModel, replacement: Text( ObjUtil.getStr(musicModel.value.subtitle), maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: const Color(0x99FFFFFF), fontSize: 12.sp, ), ), child: MyMarqueeText( text: ObjUtil.getStr(musicModel.value.subtitle), textStyle: TextStyle( color: seedColor, fontSize: 12.sp, ), ), ); }), ], ), ); } Widget _buildDownload() { return ClipOval( child: Material( color: Colors.transparent, child: InkWell( onTap: onTapDownload, child: Padding( padding: const EdgeInsets.all(4).w, child: SizedBox( width: 24.w, height: 24.w, child: Obx(() { if (OfflineBox().checkDownloaded(musicModel.value.videoId) || musicModel.value.taskStatus == TaskStatus.complete) { return Image.asset(Assets.sideBDownloaded); } else { if (musicModel.value.taskStatus == TaskStatus.enqueued) { return CircularProgressIndicator( color: seedColor, strokeWidth: 2.w, ); } else if (musicModel.value.taskStatus == TaskStatus.running) { return CircularProgressIndicator( value: musicModel.value.progress, backgroundColor: seedColor.withOpacity(0.2), valueColor: const AlwaysStoppedAnimation(seedColor), strokeWidth: 2.w, ); } else { return Image.asset(Assets.sideBNotDownload2); } } }), ), ), ), ), ); } Widget _buildMore() { return ClipOval( child: Material( color: Colors.transparent, child: InkWell( onTap: onTapMore, child: Padding( padding: const EdgeInsets.all(4).w, child: Image.asset( Assets.sideBMore, width: 24.w, height: 24.w, ), ), ), ), ); } void onTapDownload() { if (OfflineBox().checkDownloaded(musicModel.value.videoId) || musicModel.value.taskStatus == TaskStatus.complete) { Get.dialog( RemindDialog( content: 'Confirm to remove this song?', confirmOnTap: () async { await OfflineBox().delete(musicModel.value.videoId!); musicModel.update((fn) => fn?.taskStatus = null); BaseEasyLoading.toast('Removed'); if (Get.isRegistered()) { PersonalMusicLibraryController.to.refreshOffline(); } if (Get.isRegistered()) { OfflineController.to.getOfflineList(); } }, ), ); } else { if (musicModel.value.taskStatus == TaskStatus.enqueued || musicModel.value.taskStatus == TaskStatus.running) { DownloadManager().cancelDownload(musicModel); } else { DownloadManager().downloadMusic(musicModel); } } } void onTapMore() { Get.bottomSheet( MoreBottomSheetView( musicModel: musicModel, playlistModelId: playlistModelId, ), ); } }