* opt: downloadImg use cache

* opt: uin8 cast

* non null ext
This commit is contained in:
My-Responsitories
2025-10-14 19:36:43 +08:00
committed by GitHub
parent 43beb518f4
commit c3fa976b26
6 changed files with 84 additions and 59 deletions

View File

@@ -80,7 +80,7 @@ class NetworkImgLayer extends StatelessWidget {
if (height == null || forceUseCacheWidth || width <= height!) { if (height == null || forceUseCacheWidth || width <= height!) {
memCacheWidth = width.cacheSize(context); memCacheWidth = width.cacheSize(context);
} else { } else {
memCacheHeight = height.cacheSize(context); memCacheHeight = height?.cacheSize(context);
} }
return CachedNetworkImage( return CachedNetworkImage(
imageUrl: ImageUtils.thumbnailUrl(src, quality), imageUrl: ImageUtils.thumbnailUrl(src, quality),

View File

@@ -39,7 +39,7 @@ class _GroupPanelState extends State<GroupPanel> {
void _query() { void _query() {
MemberHttp.followUpTags().then((res) { MemberHttp.followUpTags().then((res) {
if (mounted) { if (mounted) {
loadingState = res..dataOrNull.removeFirstWhere((e) => e.tagid == 0); loadingState = res..dataOrNull?.removeFirstWhere((e) => e.tagid == 0);
showDefaultBtn.value = tags.isEmpty; showDefaultBtn.value = tags.isEmpty;
setState(() {}); setState(() {});
} }

View File

@@ -68,7 +68,7 @@ class MpvConvertWebp {
_observeProperty('time-pos'); _observeProperty('time-pos');
} }
final level = (kDebugMode ? 'info' : 'error').toNativeUtf8(); final level = (kDebugMode ? 'info' : 'error').toNativeUtf8();
_mpv.mpv_request_log_messages(_ctx, level.cast()); _mpv.mpv_request_log_messages(_ctx, level);
calloc.free(level); calloc.free(level);
} }
@@ -124,7 +124,7 @@ class MpvConvertWebp {
arr[i] = pointers[i]; arr[i] = pointers[i];
} }
_mpv.mpv_command(_ctx, arr.cast()); _mpv.mpv_command(_ctx, arr);
calloc.free(arr); calloc.free(arr);
pointers.forEach(calloc.free); pointers.forEach(calloc.free);
@@ -135,7 +135,7 @@ class MpvConvertWebp {
_mpv.mpv_observe_property( _mpv.mpv_observe_property(
_ctx, _ctx,
property.hashCode, property.hashCode,
name.cast(), name,
generated.mpv_format.MPV_FORMAT_DOUBLE, generated.mpv_format.MPV_FORMAT_DOUBLE,
); );

View File

@@ -57,7 +57,7 @@ abstract class CacheManage {
value = value / 1024; value = value / 1024;
} }
String size = value.toStringAsFixed(2); String size = value.toStringAsFixed(2);
return size + unitArr.getOrElse(index, orElse: () => ''); return size + (unitArr.getOrNull(index) ?? '');
} }
// 清除 Library/Caches 目录及文件缓存 // 清除 Library/Caches 目录及文件缓存

View File

@@ -14,12 +14,12 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart' hide ContextExtensionss; import 'package:get/get.dart' hide ContextExtensionss;
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
extension ImageExtension on num? { extension ImageExtension on num {
int? cacheSize(BuildContext context) { int? cacheSize(BuildContext context) {
if (this == null || this == 0) { if (this == 0) {
return null; return null;
} }
return (this! * MediaQuery.devicePixelRatioOf(context)).round(); return (this * MediaQuery.devicePixelRatioOf(context)).round();
} }
} }
@@ -57,13 +57,43 @@ extension IterableExt<T> on Iterable<T>? {
bool get isNullOrEmpty => this == null || this!.isEmpty; bool get isNullOrEmpty => this == null || this!.isEmpty;
} }
extension NonNullIterableExt<T> on Iterable<T> {
T? reduceOrNull(T Function(T value, T element) combine) {
Iterator<T> iterator = this.iterator;
if (!iterator.moveNext()) {
return null;
}
T value = iterator.current;
while (iterator.moveNext()) {
value = combine(value, iterator.current);
}
return value;
}
}
extension MapExt<K, V> on Map<K, V> { extension MapExt<K, V> on Map<K, V> {
Map<RK, RV> fromCast<RK, RV>() { Map<RK, RV> fromCast<RK, RV>() {
return Map<RK, RV>.from(this); return Map<RK, RV>.from(this);
} }
} }
extension NonNullListExt<T> on List<T> { extension ListExt<T> on List<T> {
T? getOrNull(int index) {
if (index < 0 || index >= length) {
return null;
}
return this[index];
}
bool removeFirstWhere(bool Function(T) test) {
final index = indexWhere(test);
if (index != -1) {
removeAt(index);
return true;
}
return false;
}
List<R> fromCast<R>() { List<R> fromCast<R>() {
return List<R>.from(this); return List<R>.from(this);
} }
@@ -72,34 +102,7 @@ extension NonNullListExt<T> on List<T> {
bool Function(T) test, bool Function(T) test,
T Function(T, T) combine, T Function(T, T) combine,
) { ) {
final filters = where(test).toList(); return where(test).reduceOrNull(combine) ?? reduce(combine);
return filters.isNotEmpty ? filters.reduce(combine) : reduce(combine);
}
}
extension ListExt<T> on List<T>? {
T? getOrNull(int index) {
if (isNullOrEmpty) {
return null;
}
if (index < 0 || index >= this!.length) {
return null;
}
return this![index];
}
T getOrElse(int index, {required T Function() orElse}) {
return getOrNull(index) ?? orElse();
}
bool removeFirstWhere(bool Function(T) test) {
if (this == null) return false;
final index = this!.indexWhere(test);
if (index != -1) {
this!.removeAt(index);
return true;
}
return false;
} }
} }

View File

@@ -11,6 +11,7 @@ import 'package:PiliPlus/utils/utils.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:intl/intl.dart' show DateFormat; import 'package:intl/intl.dart' show DateFormat;
import 'package:live_photo_maker/live_photo_maker.dart'; import 'package:live_photo_maker/live_photo_maker.dart';
@@ -164,8 +165,9 @@ abstract class ImageUtils {
static Future<bool> downloadImg( static Future<bool> downloadImg(
BuildContext context, BuildContext context,
List<String> imgList, List<String> imgList, [
) async { CacheManager? manager,
]) async {
if (Utils.isMobile && !await checkPermissionDependOnSdkInt(context)) { if (Utils.isMobile && !await checkPermissionDependOnSdkInt(context)) {
return false; return false;
} }
@@ -179,11 +181,15 @@ abstract class ImageUtils {
); );
} }
try { try {
final isAndroid = Platform.isAndroid;
final tempPath = await Utils.temporaryDirectory;
final futures = imgList.map((url) async { final futures = imgList.map((url) async {
final name = Utils.getFileName(url); final name = Utils.getFileName(url);
final filePath = '$tempPath/$name';
final file = (await (manager ?? DefaultCacheManager()).getFileFromCache(
url.http2https,
))?.file;
if (file == null) {
final String filePath = '${await Utils.temporaryDirectory}/$name';
final response = await Request().downloadFile( final response = await Request().downloadFile(
url.http2https, url.http2https,
@@ -191,7 +197,7 @@ abstract class ImageUtils {
cancelToken: cancelToken, cancelToken: cancelToken,
); );
if (isAndroid) { if (Utils.isMobile) {
if (response.statusCode == 200) { if (response.statusCode == 200) {
await SaverGallery.saveFile( await SaverGallery.saveFile(
filePath: filePath, filePath: filePath,
@@ -205,15 +211,29 @@ abstract class ImageUtils {
filePath: filePath, filePath: filePath,
name: name, name: name,
statusCode: response.statusCode, statusCode: response.statusCode,
del: true,
); );
} else {
if (Utils.isMobile) {
await SaverGallery.saveFile(
filePath: file.path,
fileName: name,
androidRelativePath: "Pictures/${Constants.appName}",
skipIfExists: false,
);
}
return (filePath: file.path, name: name, statusCode: 200, del: false);
}
}); });
final result = await Future.wait(futures, eagerError: true); final result = await Future.wait(futures, eagerError: true);
if (!isAndroid) { if (!Utils.isMobile) {
for (var res in result) { for (var res in result) {
if (res.statusCode == 200) { if (res.statusCode == 200) {
await saveFileImg( await saveFileImg(
filePath: res.filePath, filePath: res.filePath,
fileName: res.name, fileName: res.name,
del: res.del,
); );
} }
} }
@@ -305,6 +325,7 @@ abstract class ImageUtils {
required String fileName, required String fileName,
FileType type = FileType.image, FileType type = FileType.image,
bool needToast = false, bool needToast = false,
bool del = true,
}) async { }) async {
final file = File(filePath); final file = File(filePath);
if (!file.existsSync()) { if (!file.existsSync()) {
@@ -318,7 +339,8 @@ abstract class ImageUtils {
fileName: fileName, fileName: fileName,
androidRelativePath: "Pictures/${Constants.appName}", androidRelativePath: "Pictures/${Constants.appName}",
skipIfExists: false, skipIfExists: false,
).whenComplete(file.tryDel); );
if (del) file.tryDel();
} else { } else {
final savePath = await FilePicker.platform.saveFile( final savePath = await FilePicker.platform.saveFile(
type: type, type: type,
@@ -329,7 +351,7 @@ abstract class ImageUtils {
return; return;
} }
await file.copy(savePath); await file.copy(savePath);
file.tryDel(); if (del) file.tryDel();
result = SaveResult(true, null); result = SaveResult(true, null);
} }
if (needToast) { if (needToast) {