import 'dart:typed_data'; import 'dart:ui' as ui show Codec; import 'package:aves/services/image_file_service.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; class UriImage extends ImageProvider { const UriImage({ @required this.uri, @required this.mimeType, this.scale = 1.0, }) : assert(uri != null), assert(scale != null); final String uri, mimeType; final double scale; @override Future obtainKey(ImageConfiguration configuration) { return SynchronousFuture(this); } @override ImageStreamCompleter load(UriImage key, DecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(key, decode), scale: key.scale, informationCollector: () sync* { yield ErrorDescription('uri=$uri, mimeType=$mimeType'); }, ); } Future _loadAsync(UriImage key, DecoderCallback decode) async { assert(key == this); final bytes = await ImageFileService.getImage(uri, mimeType); return await decode(bytes ?? Uint8List(0)); } @override bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; return other is UriImage && other.uri == uri && other.mimeType == mimeType && other.scale == scale; } @override int get hashCode => hashValues(uri, scale); @override String toString() => '${objectRuntimeType(this, 'UriImage')}(uri=$uri, mimeType=$mimeType, scale=$scale)'; }