mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
Improve comic image loading retry
This commit is contained in:
@@ -3,31 +3,30 @@ part of 'reader.dart';
|
||||
class ComicImage extends StatefulWidget {
|
||||
/// Modified from flutter Image
|
||||
ComicImage({
|
||||
required ImageProvider image,
|
||||
super.key,
|
||||
double scale = 1.0,
|
||||
this.semanticLabel,
|
||||
this.excludeFromSemantics = false,
|
||||
this.width,
|
||||
this.height,
|
||||
this.color,
|
||||
this.opacity,
|
||||
this.colorBlendMode,
|
||||
this.fit,
|
||||
this.alignment = Alignment.center,
|
||||
this.repeat = ImageRepeat.noRepeat,
|
||||
this.centerSlice,
|
||||
this.matchTextDirection = false,
|
||||
this.gaplessPlayback = false,
|
||||
this.filterQuality = FilterQuality.medium,
|
||||
this.isAntiAlias = false,
|
||||
Map<String, String>? headers,
|
||||
int? cacheWidth,
|
||||
int? cacheHeight,
|
||||
}
|
||||
): image = ResizeImage.resizeIfNeeded(cacheWidth, cacheHeight, image),
|
||||
assert(cacheWidth == null || cacheWidth > 0),
|
||||
assert(cacheHeight == null || cacheHeight > 0);
|
||||
required ImageProvider image,
|
||||
super.key,
|
||||
double scale = 1.0,
|
||||
this.semanticLabel,
|
||||
this.excludeFromSemantics = false,
|
||||
this.width,
|
||||
this.height,
|
||||
this.color,
|
||||
this.opacity,
|
||||
this.colorBlendMode,
|
||||
this.fit,
|
||||
this.alignment = Alignment.center,
|
||||
this.repeat = ImageRepeat.noRepeat,
|
||||
this.centerSlice,
|
||||
this.matchTextDirection = false,
|
||||
this.gaplessPlayback = false,
|
||||
this.filterQuality = FilterQuality.medium,
|
||||
this.isAntiAlias = false,
|
||||
Map<String, String>? headers,
|
||||
int? cacheWidth,
|
||||
int? cacheHeight,
|
||||
}) : image = ResizeImage.resizeIfNeeded(cacheWidth, cacheHeight, image),
|
||||
assert(cacheWidth == null || cacheWidth > 0),
|
||||
assert(cacheHeight == null || cacheHeight > 0);
|
||||
|
||||
final ImageProvider image;
|
||||
|
||||
@@ -138,8 +137,8 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
}
|
||||
|
||||
void _updateInvertColors() {
|
||||
_invertColors = MediaQuery.maybeInvertColorsOf(context)
|
||||
?? SemanticsBinding.instance.accessibilityFeatures.invertColors;
|
||||
_invertColors = MediaQuery.maybeInvertColorsOf(context) ??
|
||||
SemanticsBinding.instance.accessibilityFeatures.invertColors;
|
||||
}
|
||||
|
||||
void _resolveImage() {
|
||||
@@ -148,16 +147,19 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
imageProvider: widget.image,
|
||||
);
|
||||
final ImageStream newStream =
|
||||
provider.resolve(createLocalImageConfiguration(
|
||||
provider.resolve(createLocalImageConfiguration(
|
||||
context,
|
||||
size: widget.width != null && widget.height != null ? Size(widget.width!, widget.height!) : null,
|
||||
size: widget.width != null && widget.height != null
|
||||
? Size(widget.width!, widget.height!)
|
||||
: null,
|
||||
));
|
||||
_updateSourceStream(newStream);
|
||||
}
|
||||
|
||||
ImageStreamListener? _imageStreamListener;
|
||||
|
||||
ImageStreamListener _getListener({bool recreateListener = false}) {
|
||||
if(_imageStreamListener == null || recreateListener) {
|
||||
if (_imageStreamListener == null || recreateListener) {
|
||||
_lastException = null;
|
||||
_imageStreamListener = ImageStreamListener(
|
||||
_handleImageFrame,
|
||||
@@ -191,7 +193,8 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
|
||||
void _replaceImage({required ImageInfo? info}) {
|
||||
final ImageInfo? oldImageInfo = _imageInfo;
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) => oldImageInfo?.dispose());
|
||||
SchedulerBinding.instance
|
||||
.addPostFrameCallback((_) => oldImageInfo?.dispose());
|
||||
_imageInfo = info;
|
||||
}
|
||||
|
||||
@@ -208,7 +211,9 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
}
|
||||
|
||||
if (!widget.gaplessPlayback) {
|
||||
setState(() { _replaceImage(info: null); });
|
||||
setState(() {
|
||||
_replaceImage(info: null);
|
||||
});
|
||||
}
|
||||
|
||||
setState(() {
|
||||
@@ -247,7 +252,9 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
return;
|
||||
}
|
||||
|
||||
if (keepStreamAlive && _completerHandle == null && _imageStream?.completer != null) {
|
||||
if (keepStreamAlive &&
|
||||
_completerHandle == null &&
|
||||
_imageStream?.completer != null) {
|
||||
_completerHandle = _imageStream!.completer!.keepAlive();
|
||||
}
|
||||
|
||||
@@ -269,26 +276,41 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text(_lastException.toString(), maxLines: 3,),
|
||||
child: Text(
|
||||
_lastException.toString(),
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4,),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Listener(
|
||||
onPointerDown: (details){
|
||||
onPointerDown: (details) {
|
||||
GlobalState.find<_ReaderGestureDetectorState>().ignoreNextTap();
|
||||
setState(() {
|
||||
_loadingProgress = null;
|
||||
_lastException = null;
|
||||
});
|
||||
_resolveImage();
|
||||
},
|
||||
child: const SizedBox(
|
||||
child: SizedBox(
|
||||
width: 84,
|
||||
height: 36,
|
||||
child: Center(
|
||||
child: Text("Retry", style: TextStyle(color: Colors.blue),),
|
||||
child: Text(
|
||||
"Retry".tl,
|
||||
style: TextStyle(color: Colors.blue),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16,),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -300,34 +322,32 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
var width = widget.width;
|
||||
var height = widget.height;
|
||||
|
||||
if(_imageInfo != null) {
|
||||
if (_imageInfo != null) {
|
||||
// Record the height and the width of the image
|
||||
_cache[widget.image.hashCode] = Size(
|
||||
_imageInfo!.image.width.toDouble(),
|
||||
_imageInfo!.image.height.toDouble()
|
||||
);
|
||||
_cache[widget.image.hashCode] = Size(_imageInfo!.image.width.toDouble(),
|
||||
_imageInfo!.image.height.toDouble());
|
||||
}
|
||||
|
||||
Size? cacheSize = _cache[widget.image.hashCode];
|
||||
if(cacheSize != null){
|
||||
if(width == double.infinity) {
|
||||
if (cacheSize != null) {
|
||||
if (width == double.infinity) {
|
||||
width = constrains.maxWidth;
|
||||
height = width * cacheSize.height / cacheSize.width;
|
||||
} else if(height == double.infinity) {
|
||||
} else if (height == double.infinity) {
|
||||
height = constrains.maxHeight;
|
||||
width = height * cacheSize.width / cacheSize.height;
|
||||
}
|
||||
} else {
|
||||
if(width == double.infinity) {
|
||||
if (width == double.infinity) {
|
||||
width = constrains.maxWidth;
|
||||
height = 300;
|
||||
} else if(height == double.infinity) {
|
||||
} else if (height == double.infinity) {
|
||||
height = constrains.maxHeight;
|
||||
width = 300;
|
||||
}
|
||||
}
|
||||
|
||||
if(_imageInfo != null){
|
||||
if (_imageInfo != null) {
|
||||
// build image
|
||||
Widget result = RawImage(
|
||||
// Do not clone the image, because RawImage is a stateless wrapper.
|
||||
@@ -379,12 +399,13 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
height: 24,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 3,
|
||||
backgroundColor: context.colorScheme.surfaceContainerLow,
|
||||
backgroundColor: context.colorScheme.surfaceContainer,
|
||||
value: (_loadingProgress != null &&
|
||||
_loadingProgress!.expectedTotalBytes!=null &&
|
||||
_loadingProgress!.expectedTotalBytes! != 0)
|
||||
?_loadingProgress!.cumulativeBytesLoaded / _loadingProgress!.expectedTotalBytes!
|
||||
:0,
|
||||
_loadingProgress!.expectedTotalBytes != null &&
|
||||
_loadingProgress!.expectedTotalBytes! != 0)
|
||||
? _loadingProgress!.cumulativeBytesLoaded /
|
||||
_loadingProgress!.expectedTotalBytes!
|
||||
: 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -398,8 +419,10 @@ class _ComicImageState extends State<ComicImage> with WidgetsBindingObserver {
|
||||
super.debugFillProperties(description);
|
||||
description.add(DiagnosticsProperty<ImageStream>('stream', _imageStream));
|
||||
description.add(DiagnosticsProperty<ImageInfo>('pixels', _imageInfo));
|
||||
description.add(DiagnosticsProperty<ImageChunkEvent>('loadingProgress', _loadingProgress));
|
||||
description.add(DiagnosticsProperty<ImageChunkEvent>(
|
||||
'loadingProgress', _loadingProgress));
|
||||
description.add(DiagnosticsProperty<int>('frameNumber', _frameNumber));
|
||||
description.add(DiagnosticsProperty<bool>('wasSynchronouslyLoaded', _wasSynchronouslyLoaded));
|
||||
description.add(DiagnosticsProperty<bool>(
|
||||
'wasSynchronouslyLoaded', _wasSynchronouslyLoaded));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user