From 9fb348247416b458aecec99ab0191593b5ff006e Mon Sep 17 00:00:00 2001 From: nyne Date: Sat, 30 Nov 2024 21:05:35 +0800 Subject: [PATCH] fix #73 --- lib/components/comic.dart | 2 +- lib/components/components.dart | 1 + .../image_provider/local_comic_image.dart | 63 +++++++++++++++++++ lib/pages/home_page.dart | 5 +- 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 lib/foundation/image_provider/local_comic_image.dart diff --git a/lib/components/comic.dart b/lib/components/comic.dart index 28d53a7..6420308 100644 --- a/lib/components/comic.dart +++ b/lib/components/comic.dart @@ -163,7 +163,7 @@ class ComicTile extends StatelessWidget { Widget buildImage(BuildContext context) { ImageProvider image; if (comic is LocalComic) { - image = FileImage((comic as LocalComic).coverFile); + image = LocalComicImageProvider(comic as LocalComic); } else if (comic.sourceKey == 'local') { var localComic = LocalManager().find(comic.id, ComicType.local); if (localComic == null) { diff --git a/lib/components/components.dart b/lib/components/components.dart index b4b2dd8..ea377c1 100644 --- a/lib/components/components.dart +++ b/lib/components/components.dart @@ -19,6 +19,7 @@ import 'package:venera/foundation/consts.dart'; import 'package:venera/foundation/favorites.dart'; import 'package:venera/foundation/history.dart'; import 'package:venera/foundation/image_provider/cached_image.dart'; +import 'package:venera/foundation/image_provider/local_comic_image.dart'; import 'package:venera/foundation/local.dart'; import 'package:venera/foundation/res.dart'; import 'package:venera/network/cloudflare.dart'; diff --git a/lib/foundation/image_provider/local_comic_image.dart b/lib/foundation/image_provider/local_comic_image.dart new file mode 100644 index 0000000..cfb1c22 --- /dev/null +++ b/lib/foundation/image_provider/local_comic_image.dart @@ -0,0 +1,63 @@ +import 'dart:async' show Future, StreamController; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:venera/foundation/local.dart'; +import 'package:venera/network/images.dart'; +import 'package:venera/utils/io.dart'; +import 'base_image_provider.dart'; +import 'local_comic_image.dart' as image_provider; + +class LocalComicImageProvider + extends BaseImageProvider { + /// Image provider for normal image. + /// + /// [url] is the url of the image. Local file path is also supported. + const LocalComicImageProvider(this.comic); + + final LocalComic comic; + + @override + Future load(StreamController chunkEvents) async { + File? file = comic.coverFile; + if(! await file.exists()) { + file = null; + var dir = Directory(comic.directory); + if (! await dir.exists()) { + throw "Error: Comic not found."; + } + Directory? firstDir; + await for (var entity in dir.list()) { + if(entity is File) { + if(["jpg", "jpeg", "png", "webp", "gif", "jpe", "jpeg"].contains(entity.extension)) { + file = entity; + break; + } + } else if(entity is Directory) { + firstDir ??= entity; + } + } + if(file == null && firstDir != null) { + await for (var entity in firstDir.list()) { + if(entity is File) { + if(["jpg", "jpeg", "png", "webp", "gif", "jpe", "jpeg"].contains(entity.extension)) { + file = entity; + break; + } + } + } + } + } + if(file == null) { + throw "Error: Cover not found."; + } + return file.readAsBytes(); + } + + @override + Future obtainKey(ImageConfiguration configuration) { + return SynchronousFuture(this); + } + + @override + String get key => "local${comic.id}${comic.comicType.value}"; +} diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 018076b..32ca613 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -7,6 +7,7 @@ import 'package:venera/foundation/consts.dart'; import 'package:venera/foundation/favorites.dart'; import 'package:venera/foundation/history.dart'; import 'package:venera/foundation/image_provider/cached_image.dart'; +import 'package:venera/foundation/image_provider/local_comic_image.dart'; import 'package:venera/foundation/local.dart'; import 'package:venera/pages/accounts_page.dart'; import 'package:venera/pages/comic_page.dart'; @@ -418,8 +419,8 @@ class _LocalState extends State<_Local> { ), clipBehavior: Clip.antiAlias, child: AnimatedImage( - image: FileImage( - local[index].coverFile, + image: LocalComicImageProvider( + local[index], ), width: 96, height: 128,