ToneSnap_FSX_Flutter/lib/modules/sideb/widgets/music_item.dart
2024-08-01 13:38:25 +08:00

230 lines
7.3 KiB
Dart

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> 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<Color>(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>()) {
PersonalMusicLibraryController.to.refreshOffline();
}
if (Get.isRegistered<OfflineController>()) {
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,
),
);
}
}