|
|
@@ -9,6 +9,7 @@ import 'package:wechat_assets_picker/wechat_assets_picker.dart';
|
|
|
import '../../data/repositories/user_repository.dart';
|
|
|
import '../../dialog/photo_delete_finish_dialog.dart';
|
|
|
import '../../dialog/photo_deleting_dialog.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';
|
|
|
@@ -18,8 +19,6 @@ class CalendarMonthController extends BaseController {
|
|
|
late final Rx<PhotoGroup> photoGroup =
|
|
|
PhotoGroup(isSelected: false, images: []).obs;
|
|
|
|
|
|
-
|
|
|
-
|
|
|
// 是否是选择模式
|
|
|
RxBool isSelectMode = false.obs;
|
|
|
|
|
|
@@ -44,7 +43,6 @@ class CalendarMonthController extends BaseController {
|
|
|
final newValue = !photoGroup.value.isSelected.value;
|
|
|
photoGroup.value.toggleSelectAll(newValue);
|
|
|
|
|
|
-
|
|
|
// 更新选中状态
|
|
|
for (var image in imagesList) {
|
|
|
updateSelectedPhotosIds(image.id, newValue);
|
|
|
@@ -55,59 +53,54 @@ class CalendarMonthController extends BaseController {
|
|
|
clickDelete() async {
|
|
|
debugPrint('CalendarMonthController 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<String> result = await PhotoManager.editor.deleteWithIds(
|
|
|
- assetsToDelete.map((e) => e.id).toList(),
|
|
|
- );
|
|
|
-
|
|
|
-
|
|
|
- // 比较result和selectedPhotosIds,如果result和selectedPhotosIds相等,说明删除成功,走下面的逻辑
|
|
|
- // 如果不相等,说明有删除失败的,走else逻辑
|
|
|
- if (result.length == photoGroup.value.selectedPhotosIds.length) {
|
|
|
-
|
|
|
- debugPrint("CalendarMonthController delete ${photoGroup.value.selectedPhotosIds}");
|
|
|
- ImagePickerUtil.updatePhotoData(
|
|
|
- photoGroup.value.selectedPhotosIds);
|
|
|
- cleanSelections();
|
|
|
- ToastUtil.show('Delete success');
|
|
|
- Future.delayed(Duration(seconds: 2), () {
|
|
|
+ if (photoGroup.value.selectedPhotosIds.isNotEmpty) {
|
|
|
+ photoDeletingDialog();
|
|
|
+ // 获取要删除的资产
|
|
|
+ final assetsToDelete = photoGroup.value.images
|
|
|
+ .where(
|
|
|
+ (asset) => photoGroup.value.selectedPhotosIds.contains(asset.id),
|
|
|
+ )
|
|
|
+ .toList();
|
|
|
+
|
|
|
+ // 调用方法会返回被删除的资源,如果全部失败会返回空列表。
|
|
|
+ final List<String> result = await PhotoManager.editor.deleteWithIds(
|
|
|
+ assetsToDelete.map((e) => e.id).toList(),
|
|
|
+ );
|
|
|
+
|
|
|
+ // 比较result和selectedPhotosIds,如果result和selectedPhotosIds相等,说明删除成功,走下面的逻辑
|
|
|
+ // 如果不相等,说明有删除失败的,走else逻辑
|
|
|
+ if (result.length == photoGroup.value.selectedPhotosIds.length) {
|
|
|
+ debugPrint(
|
|
|
+ "CalendarMonthController delete ${photoGroup.value.selectedPhotosIds}");
|
|
|
+ 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');
|
|
|
- photoDeleteFinishDialog();
|
|
|
- });
|
|
|
- } else {
|
|
|
- SmartDialog.dismiss(tag: 'photoDeletingDialog');
|
|
|
- // 删除失败
|
|
|
- ToastUtil.show("Delete failed");
|
|
|
+ // 删除失败
|
|
|
+ ToastUtil.show("Delete failed");
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
} else {
|
|
|
StorePage.start();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
//删除成功清除选中的图片
|
|
|
void cleanSelections() async {
|
|
|
- photoGroup.value.images
|
|
|
- .removeWhere((element) => photoGroup.value.selectedPhotosIds.contains(element.id));
|
|
|
-
|
|
|
+ photoGroup.value.images.removeWhere(
|
|
|
+ (element) => photoGroup.value.selectedPhotosIds.contains(element.id));
|
|
|
|
|
|
photoGroup.value.selectedPhotosIds.clear();
|
|
|
|
|
|
-
|
|
|
if (photoGroup.value.images.isEmpty) {
|
|
|
return;
|
|
|
}
|
|
|
updateSelectedFilesSize();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
Future<void> updateSelectedFilesSize() async {
|
|
|
@@ -118,36 +111,48 @@ class CalendarMonthController extends BaseController {
|
|
|
}
|
|
|
|
|
|
double totalSize = 0;
|
|
|
- final selectedImages = photoGroup.value.images;
|
|
|
-
|
|
|
- // 获取选中图片的大小(异步并行执行)
|
|
|
- final futures = photoGroup.value.selectedPhotosIds.map((assetId) async {
|
|
|
- if (ImagePickerUtil.fileSizeCache.containsKey(assetId)) {
|
|
|
- totalSize += ImagePickerUtil.fileSizeCache[assetId]!;
|
|
|
- } else {
|
|
|
- final image = selectedImages.firstWhere((image) => image.id == assetId);
|
|
|
- final file = await image.file;
|
|
|
- if (file != null) {
|
|
|
- final size = (await file.length()) / 1024; // 转换为KB
|
|
|
- totalSize += size;
|
|
|
- ImagePickerUtil.fileSizeCache[assetId] = size;
|
|
|
- file.delete();
|
|
|
- }
|
|
|
+ final uncasedIds = photoGroup.value.selectedPhotosIds
|
|
|
+ .where((id) => !FileSizeCalculatorUtil.fileSizeCache.containsKey(id))
|
|
|
+ .toSet();
|
|
|
+
|
|
|
+ // **1️⃣ 先处理缓存中的文件**
|
|
|
+
|
|
|
+ totalSize = photoGroup.value.selectedPhotosIds
|
|
|
+ .fold(0, (prev, id) => prev + (FileSizeCalculatorUtil.fileSizeCache[id] ?? 0));
|
|
|
+
|
|
|
+ // **2️⃣ 分批处理未缓存的文件**
|
|
|
+ const batchSize = 50;
|
|
|
+ for (int i = 0; i < uncasedIds.length; i += batchSize) {
|
|
|
+ if (photoGroup.value.selectedPhotosIds.isEmpty) {
|
|
|
+ photoGroup.value.selectedTotalSize.value = 0;
|
|
|
+ return;
|
|
|
}
|
|
|
- }).toList();
|
|
|
|
|
|
- // 等待所有异步操作完成
|
|
|
- await Future.wait(futures);
|
|
|
+ final batch = uncasedIds.skip(i).take(batchSize);
|
|
|
+ final sizes = await Future.wait(batch.map(FileSizeCalculatorUtil.getFileSize));
|
|
|
+
|
|
|
+ totalSize += sizes.fold(0, (sum, size) => sum + size);
|
|
|
|
|
|
- // 更新选中文件的总大小
|
|
|
- photoGroup.value.selectedTotalSize.value = totalSize;
|
|
|
+ // **再检查一次是否被清空,避免无意义计算**
|
|
|
+ if (photoGroup.value.selectedPhotosIds.isEmpty) {
|
|
|
+ photoGroup.value.selectedTotalSize.value = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- // 打印调试信息
|
|
|
- print("selectedFilesSize: ${photoGroup.value.selectedTotalSize.value}");
|
|
|
+ // **减少 UI 更新频率**
|
|
|
+ if (i % (batchSize * 2) == 0 || i + batchSize >= uncasedIds.length) {
|
|
|
+ photoGroup.value.selectedTotalSize.value = totalSize;
|
|
|
+ }
|
|
|
|
|
|
+ await Future.delayed(Duration.zero);
|
|
|
+ }
|
|
|
|
|
|
+ photoGroup.value.selectedTotalSize.value = totalSize; // 确保最终更新总大小
|
|
|
+ PhotoManager.clearFileCache();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
void updateSelectedPhotosIds(String photoId, bool isSelected) {
|
|
|
if (isSelected) {
|
|
|
if (!photoGroup.value.selectedPhotosIds.contains(photoId)) {
|
|
|
@@ -157,8 +162,10 @@ class CalendarMonthController extends BaseController {
|
|
|
photoGroup.value.selectedPhotosIds.remove(photoId);
|
|
|
}
|
|
|
photoGroup.value.isSelected.value =
|
|
|
- photoGroup.value.selectedPhotosIds.length == photoGroup.value.images.length;
|
|
|
+ photoGroup.value.selectedPhotosIds.length ==
|
|
|
+ photoGroup.value.images.length;
|
|
|
}
|
|
|
+
|
|
|
clickImage(int imageIndex) {
|
|
|
print("CalendarMonthController clickImage");
|
|
|
|
|
|
@@ -177,19 +184,19 @@ class CalendarMonthController extends BaseController {
|
|
|
updateSelectedPhotosIds(photoId, isNowSelected);
|
|
|
|
|
|
updateSelectedFilesSize();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-
|
|
|
String get selectedFilesSizeString {
|
|
|
-
|
|
|
final double sizeInKB = photoGroup.value.selectedTotalSize.value;
|
|
|
|
|
|
- if (sizeInKB >= 1024 * 1024) { // 先检查最大单位(GB)
|
|
|
+ if (sizeInKB >= 1024 * 1024) {
|
|
|
+ // 先检查最大单位(GB)
|
|
|
return "${(sizeInKB / (1024 * 1024)).toStringAsFixed(2)}GB";
|
|
|
- } else if (sizeInKB >= 1024) { // 然后检查MB
|
|
|
+ } else if (sizeInKB >= 1024) {
|
|
|
+ // 然后检查MB
|
|
|
return "${(sizeInKB / 1024).toStringAsFixed(2)}MB";
|
|
|
- } else { // 最后是KB
|
|
|
+ } else {
|
|
|
+ // 最后是KB
|
|
|
return "${sizeInKB.toStringAsFixed(2)}KB";
|
|
|
}
|
|
|
}
|