add onLoadFailed to imageLoadingConfig

This commit is contained in:
nyne
2024-11-11 15:01:31 +08:00
parent d875681c4b
commit 7cf55fcb8e

View File

@@ -1,5 +1,6 @@
import 'dart:typed_data';
import 'package:flutter_qjs/flutter_qjs.dart';
import 'package:venera/foundation/cache_manager.dart';
import 'package:venera/foundation/comic_source/comic_source.dart';
import 'package:venera/foundation/consts.dart';
@@ -83,61 +84,92 @@ class ImageDownloader {
);
}
Future<Map<String, dynamic>?> Function()? onLoadFailed;
var configs = <String, dynamic>{};
if (sourceKey != null) {
var comicSource = ComicSource.find(sourceKey);
configs = (await comicSource!.getImageLoadingConfig
?.call(imageKey, cid, eid)) ?? {};
?.call(imageKey, cid, eid)) ??
{};
}
configs['headers'] ??= {
'user-agent': webUA,
};
var retryLimit = 5;
while (true) {
try {
configs['headers'] ??= {
'user-agent': webUA,
};
var dio = AppDio(BaseOptions(
headers: configs['headers'],
method: configs['method'] ?? 'GET',
responseType: ResponseType.stream,
));
if (configs['onLoadFailed'] is JSInvokable) {
onLoadFailed = () async {
dynamic result = configs['onLoadFailed']();
if (result is Future) {
result = await result;
}
if (result is! Map<String, dynamic>) return null;
return result;
};
}
var req = await dio.request<ResponseBody>(configs['url'] ?? imageKey,
data: configs['data']);
var stream = req.data?.stream ?? (throw "Error: Empty response body.");
int? expectedBytes = req.data!.contentLength;
if (expectedBytes == -1) {
expectedBytes = null;
}
var buffer = <int>[];
await for (var data in stream) {
buffer.addAll(data);
if (expectedBytes != null) {
var dio = AppDio(BaseOptions(
headers: configs['headers'],
method: configs['method'] ?? 'GET',
responseType: ResponseType.stream,
));
var req = await dio.request<ResponseBody>(configs['url'] ?? imageKey,
data: configs['data']);
var stream = req.data?.stream ?? (throw "Error: Empty response body.");
int? expectedBytes = req.data!.contentLength;
if (expectedBytes == -1) {
expectedBytes = null;
}
var buffer = <int>[];
await for (var data in stream) {
buffer.addAll(data);
if (expectedBytes != null) {
yield ImageDownloadProgress(
currentBytes: buffer.length,
totalBytes: expectedBytes,
);
}
}
if (configs['onResponse'] != null) {
buffer = configs['onResponse'](buffer);
}
var data = Uint8List.fromList(buffer);
buffer.clear();
if (configs['modifyImage'] != null) {
var newData = await modifyImageWithScript(
data,
configs['modifyImage'],
);
data = newData;
}
await CacheManager().writeCache(cacheKey, data);
yield ImageDownloadProgress(
currentBytes: buffer.length,
totalBytes: expectedBytes,
currentBytes: data.length,
totalBytes: data.length,
imageBytes: data,
);
return;
} catch (e) {
if(retryLimit < 0 || onLoadFailed == null) {
rethrow;
}
var newConfig = await onLoadFailed();
onLoadFailed = null;
if(newConfig == null) {
rethrow;
}
configs = newConfig;
retryLimit--;
}
}
if (configs['onResponse'] != null) {
buffer = configs['onResponse'](buffer);
}
var data = Uint8List.fromList(buffer);
buffer.clear();
if (configs['modifyImage'] != null) {
var newData = await modifyImageWithScript(
data,
configs['modifyImage'],
);
data = newData;
}
await CacheManager().writeCache(cacheKey, data);
yield ImageDownloadProgress(
currentBytes: data.length,
totalBytes: data.length,
imageBytes: data,
);
}
}