download & view local comics

This commit is contained in:
nyne
2024-10-14 11:10:24 +08:00
parent 5a3537657a
commit c0a0dc59e1
20 changed files with 1467 additions and 158 deletions

139
lib/network/images.dart Normal file
View File

@@ -0,0 +1,139 @@
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'] ??= {
'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'] ?? 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 = 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,
});
}