mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
145 lines
4.0 KiB
Dart
145 lines
4.0 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:venera/foundation/cache_manager.dart';
|
|
import 'package:venera/foundation/comic_source/comic_source.dart';
|
|
import 'package:venera/foundation/consts.dart';
|
|
|
|
import 'app_dio.dart';
|
|
|
|
class ImageDownloader {
|
|
static Stream<ImageDownloadProgress> loadThumbnail(
|
|
String url, String? sourceKey) async* {
|
|
final cacheKey = "$url@$sourceKey";
|
|
final cache = await CacheManager().findCache(cacheKey);
|
|
|
|
if (cache != null) {
|
|
var data = await cache.readAsBytes();
|
|
yield ImageDownloadProgress(
|
|
currentBytes: data.length,
|
|
totalBytes: data.length,
|
|
imageBytes: data,
|
|
);
|
|
}
|
|
|
|
var configs = <String, dynamic>{};
|
|
if (sourceKey != null) {
|
|
var comicSource = ComicSource.find(sourceKey);
|
|
configs = comicSource!.getThumbnailLoadingConfig?.call(url) ?? {};
|
|
}
|
|
configs['headers'] ??= {};
|
|
if(configs['headers']['user-agent'] == null
|
|
&& configs['headers']['User-Agent'] == null) {
|
|
configs['headers']['user-agent'] = webUA;
|
|
}
|
|
|
|
var dio = AppDio(BaseOptions(
|
|
headers: Map<String, dynamic>.from(configs['headers']),
|
|
method: configs['method'] ?? 'GET',
|
|
responseType: ResponseType.stream,
|
|
));
|
|
|
|
var req = await dio.request<ResponseBody>(configs['url'] ?? url,
|
|
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);
|
|
}
|
|
|
|
await CacheManager().writeCache(cacheKey, buffer);
|
|
yield ImageDownloadProgress(
|
|
currentBytes: buffer.length,
|
|
totalBytes: buffer.length,
|
|
imageBytes: Uint8List.fromList(buffer),
|
|
);
|
|
}
|
|
|
|
static Stream<ImageDownloadProgress> loadComicImage(
|
|
String imageKey, String? sourceKey, String cid, String eid) async* {
|
|
final cacheKey = "$imageKey@$sourceKey@$cid@$eid";
|
|
final cache = await CacheManager().findCache(cacheKey);
|
|
|
|
if (cache != null) {
|
|
var data = await cache.readAsBytes();
|
|
yield ImageDownloadProgress(
|
|
currentBytes: data.length,
|
|
totalBytes: data.length,
|
|
imageBytes: data,
|
|
);
|
|
}
|
|
|
|
var configs = <String, dynamic>{};
|
|
if (sourceKey != null) {
|
|
var comicSource = ComicSource.find(sourceKey);
|
|
configs = (await comicSource!.getImageLoadingConfig
|
|
?.call(imageKey, cid, eid)) ?? {};
|
|
}
|
|
configs['headers'] ??= {
|
|
'user-agent': webUA,
|
|
};
|
|
|
|
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);
|
|
}
|
|
|
|
await CacheManager().writeCache(cacheKey, buffer);
|
|
yield ImageDownloadProgress(
|
|
currentBytes: buffer.length,
|
|
totalBytes: buffer.length,
|
|
imageBytes: Uint8List.fromList(buffer),
|
|
);
|
|
}
|
|
}
|
|
|
|
class ImageDownloadProgress {
|
|
final int currentBytes;
|
|
|
|
final int totalBytes;
|
|
|
|
final Uint8List? imageBytes;
|
|
|
|
const ImageDownloadProgress({
|
|
required this.currentBytes,
|
|
required this.totalBytes,
|
|
this.imageBytes,
|
|
});
|
|
}
|