improved performance and battery usage on older devices

This commit is contained in:
2026-09-25 23:58:08 +02:00
parent ed8e52f475
commit 56a497985b
70 changed files with 1631 additions and 621 deletions
+32 -26
View File
@@ -10,9 +10,33 @@ class PmImageView extends StatelessWidget {
const PmImageView({required this.node, super.key});
/// Full-resolution source, used for the zoomable fullscreen view.
static ImageProvider? sourceProvider(PmImage node) {
final bytes = node.bytes;
if (bytes != null) return MemoryImage(bytes);
if (node.src.startsWith('http')) {
return CachedNetworkImageProvider(node.src);
}
return null;
}
/// Inline images never render wider than the screen, so they are decoded at
/// most at its physical width instead of the (often camera-sized) original.
/// [PmJsonView] precaches through this too, so both hit the same cache key.
static ImageProvider? inlineProvider(BuildContext context, PmImage node) {
final source = sourceProvider(node);
if (source == null) return null;
final width =
(MediaQuery.sizeOf(context).width *
MediaQuery.devicePixelRatioOf(context))
.round();
return ResizeImage(source, width: width);
}
@override
Widget build(BuildContext context) {
final provider = _imageProvider();
final provider = sourceProvider(node);
final inline = inlineProvider(context, node);
return LayoutBuilder(
builder: (context, constraints) {
final available = constraints.maxWidth.isFinite
@@ -22,7 +46,13 @@ class PmImageView extends StatelessWidget {
Widget image = ConstrainedBox(
constraints: BoxConstraints(maxWidth: targetWidth ?? available),
child: _imageWidget(context, provider),
child: inline == null
? _brokenImage(context)
: Image(
image: inline,
errorBuilder: (context, error, stack) =>
_brokenImage(context),
),
);
final href = node.href;
@@ -43,30 +73,6 @@ class PmImageView extends StatelessWidget {
);
}
ImageProvider? _imageProvider() {
if (node.bytes != null) return MemoryImage(node.bytes!);
if (node.src.startsWith('http')) {
return CachedNetworkImageProvider(node.src);
}
return null;
}
Widget _imageWidget(BuildContext context, ImageProvider? provider) {
if (node.bytes != null) {
return Image.memory(
node.bytes!,
errorBuilder: (context, error, stack) => _brokenImage(context),
);
}
if (node.src.startsWith('http')) {
return CachedNetworkImage(
imageUrl: node.src,
errorWidget: (context, url, error) => _brokenImage(context),
);
}
return _brokenImage(context);
}
Widget _brokenImage(BuildContext context) {
final theme = Theme.of(context);
return DecoratedBox(