import 'dart:async'; import 'package:clean/base/base_controller.dart'; import 'package:clean/module/calendar/selected_preview/calendar_selected_preview_view.dart'; import 'package:flutter/Material.dart'; import 'package:flutter_card_swiper/flutter_card_swiper.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import '../../../data/consts/constants.dart'; import '../../../data/consts/event_report_id.dart'; import '../../../data/repositories/user_repository.dart'; import '../../../dialog/photo_delete_finish_dialog.dart'; import '../../../dialog/photo_deleting_dialog.dart'; import '../../../dialog/photo_preview_tip_dialog.dart'; import '../../../dialog/play_video_dialog.dart'; import '../../../handler/event_handler.dart'; import '../../../utils/file_size_calculator_util.dart'; import '../../../utils/toast_util.dart'; import '../../image_picker/image_picker_util.dart'; import '../../people_photo/photo_group.dart'; import '../../store/store_view.dart'; class CalendarPreviewController extends BaseController with GetSingleTickerProviderStateMixin { final Rx photoGroup = PhotoGroup(isSelected: false, images: []).obs; late String? currentImageId; final CardSwiperController cardSwiperController = CardSwiperController(); final RxBool isSwiperEnd = false.obs; RxInt groupIndex = 0.obs; late AnimationController animationController; RxBool animationIsComplete = false.obs; void playVideo(AssetEntity asset) async { playVideoDialog(asset); } @override void onInit() { super.onInit(); _getArgs(); // 获取传递的参数 animationController = AnimationController( vsync: this, duration: const Duration(seconds: 3), ); WidgetsBinding.instance.addPostFrameCallback((_) { if (currentImageId != null) { for (int i = 0; i < photoGroup.value.images.length; i++) { if (photoGroup.value.images[i].id == currentImageId) { debugPrint( 'photoGroups[i].id ${photoGroup.value.images[i].id},i $i'); groupIndex.value = i; cardSwiperController.moveTo(i); break; } } } }); animationController.addStatusListener((status) { if (status == AnimationStatus.forward) { // 延迟一秒 Future.delayed(Duration(seconds: 1), () { animationIsComplete.value = true; EventHandler.report(EventId.event_04008); }); } if (status == AnimationStatus.completed) { Future.delayed(Duration(seconds: 1), () { CalendarSelectedPreviewPage.start(photoGroup.value); }); } }); } // 获取参数 void _getArgs() { photoGroup.value = parameters?['photoGroup']; currentImageId = parameters?['currentImageId']; } void clickUnselect() { debugPrint("clickUnselect"); cardSwiperController.swipe(CardSwiperDirection.right); } FutureOr onSwipe( int previousIndex, int? currentIndex, CardSwiperDirection direction, ) { debugPrint( 'onSwipe The card $previousIndex was swiped to the ${direction.name}. Now the card $currentIndex is on top', ); if (currentIndex != null) { groupIndex.value = currentIndex; } // 如果direction是left, if (direction == CardSwiperDirection.left) { // 先看看图片id是不是在selectedPhotosIds里面,如果在,不处理,如果不在,添加到selectedPhotosIds里面 if (!photoGroup.value.selectedPhotosIds .contains(photoGroup.value.images[previousIndex].id)) { debugPrint( 'add photoGroups[groupIndex.value].id ${photoGroup.value.images[previousIndex].id}'); photoGroup.value.selectedPhotosIds .add(photoGroup.value.images[previousIndex].id); } } else if (direction == CardSwiperDirection.right) { // 先看看图片id是不是在selectedPhotosIds里面,如果在,在selectedPhotosIds移除,不处理,如果不在,不处理 if (photoGroup.value.selectedPhotosIds .contains(photoGroup.value.images[previousIndex].id)) { debugPrint( 'remove photoGroups[groupIndex.value].id ${photoGroup.value.images[previousIndex].id}'); photoGroup.value.selectedPhotosIds .remove(photoGroup.value.images[previousIndex].id); } } updateSelectedFilesSize(); return true; } bool onSwiperUndo( int? previousIndex, int currentIndex, CardSwiperDirection direction, ) { debugPrint( 'onSwiperUndo The card $currentIndex was swiped back to the ${direction.name}. Now the card $previousIndex is on top'); groupIndex.value = currentIndex; // 撤销之前左滑的操作 if (direction == CardSwiperDirection.left) { debugPrint( 'photoGroups[groupIndex.value].id ${photoGroup.value.images[groupIndex.value].id}'); if (photoGroup.value.selectedPhotosIds .contains(photoGroup.value.images[groupIndex.value].id)) { photoGroup.value.selectedPhotosIds .remove(photoGroup.value.images[groupIndex.value].id); } } updateSelectedFilesSize(); return true; } onSwiperEnd() { isSwiperEnd.value = true; debugPrint('onSwiperEnd'); // 延迟500ms Future.delayed(Duration(milliseconds: 200), () { animationController.forward(from: 0); }); PhotoManager.clearFileCache(); // PhotoSelectedPreviewPage.start(photosType, selectedPhotosIds); } void recoverSelectPhoto() { debugPrint('PhotoPreviewController recoverSelectPhoto'); cardSwiperController.undo(); } void clickSelect() { cardSwiperController.swipe(CardSwiperDirection.left); } @override void onReady() { super.onReady(); EventHandler.report(EventId.event_04002); print('PhotoPreviewController onReady'); if (isFirstOpenPhotoPreview()) { photoPreviewTipDialog(clickCallback: () { setFirstOpenPhotoPreview(false); EventHandler.report(EventId.event_04001); }); } } void clickBack() { EventHandler.report(EventId.event_04003); Get.back(); } clickDelete() async { EventHandler.report(EventId.event_04004); debugPrint('CalendarPreviewController clickDelete'); if (userRepository.isVip()) { if (photoGroup.value.selectedPhotosIds.isNotEmpty) { photoDeletingDialog(); // 获取要删除的资产 final assetsToDelete = photoGroup.value.images .where( (asset) => photoGroup.value.selectedPhotosIds.contains(asset.id), ) .toList(); // 调用方法会返回被删除的资源,如果全部失败会返回空列表。 final List result = await PhotoManager.editor.deleteWithIds( assetsToDelete.map((e) => e.id).toList(), ); // 比较result和selectedPhotosIds,如果result和selectedPhotosIds相等,说明删除成功,走下面的逻辑 // 如果不相等,说明有删除失败的,走else逻辑 if (result.length == photoGroup.value.selectedPhotosIds.length) { ImagePickerUtil.updatePhotoData(photoGroup.value.selectedPhotosIds); cleanSelections(); ToastUtil.show('Delete success'); Future.delayed(Duration(seconds: 2), () { SmartDialog.dismiss(tag: 'photoDeletingDialog'); photoDeleteFinishDialog(); }); } else { SmartDialog.dismiss(tag: 'photoDeletingDialog'); // 删除失败 ToastUtil.show("Delete failed"); } } } else { StorePage.start(); } } void clickJumpSelected() { debugPrint('PhotoPreviewController clickJumpSelected'); EventHandler.report(EventId.event_04005); CalendarSelectedPreviewPage.start(photoGroup.value); } //删除成功清除选中的图片 void cleanSelections() async { photoGroup.value.images.removeWhere( (element) => photoGroup.value.selectedPhotosIds.contains(element.id)); photoGroup.value.selectedPhotosIds.clear(); photoGroup.refresh(); if (photoGroup.value.images.isEmpty) { return; } isSwiperEnd.value = false; if (photoGroup.value.images.isNotEmpty) { WidgetsBinding.instance.addPostFrameCallback((_) { groupIndex.value = 0; cardSwiperController.moveTo(0); }); } updateSelectedFilesSize(); } // 将selectedFilesSize转成String类型,然后单位转换,如果超过1MB,则转成MB,超过1GB,则转成GB,否则KB String get selectedFilesSizeString { final double sizeInKB = photoGroup.value.selectedTotalSize.value; if (sizeInKB >= 1024 * 1024) { // 先检查最大单位(GB) return "${(sizeInKB / (1024 * 1024)).toStringAsFixed(2)}GB"; } else if (sizeInKB >= 1024) { // 然后检查MB return "${(sizeInKB / 1024).toStringAsFixed(2)}MB"; } else { // 最后是KB return "${sizeInKB.toStringAsFixed(2)}KB"; } } Future updateSelectedFilesSize() async { // 如果没有选中的文件,直接返回 if (photoGroup.value.selectedCount == 0) { photoGroup.value.selectedTotalSize.value = 0; return; } FileSizeCalculatorUtil.calculateTotalSize( assetIds: photoGroup.value.selectedPhotosIds, updateValue: (double totalSize) { photoGroup.value.selectedTotalSize.value = totalSize; }, ); PhotoManager.clearFileCache(); } void restoreSelections() { if (photoGroup.value.images.isEmpty) { clickBack(); return; } isSwiperEnd.value = false; if (photoGroup.value.images.isNotEmpty) { WidgetsBinding.instance.addPostFrameCallback((_) { groupIndex.value = 0; cardSwiperController.moveTo(0); }); } updateSelectedFilesSize(); } @override void onClose() { debugPrint('CalendarPreviewController onClose'); animationController.dispose(); super.onClose(); isSwiperEnd.value = false; // 清理操作,释放资源 cardSwiperController.dispose(); // 清理缓存 PhotoManager.clearFileCache(); } }