From d81041802a8917d4b5ab7caa7ef6d541d3916ace Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Fri, 17 Apr 2020 10:27:21 +0200 Subject: [PATCH] MarkdownView: Use CachedNetworkImage This is the simplest way I could find of showing a placeholder and loading screen while the image was downloading. I'm not sure if I want to cache the images locally. Also, this adds lots of dependencies, which I'm not too comfortable with. --- lib/widgets/note_viewer.dart | 63 +++++++++++++++++++++++++++++++++++- pubspec.lock | 63 ++++++++++++++++++++++++++++++++++++ pubspec.yaml | 1 + 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/lib/widgets/note_viewer.dart b/lib/widgets/note_viewer.dart index 3fb31092..77ce79ae 100644 --- a/lib/widgets/note_viewer.dart +++ b/lib/widgets/note_viewer.dart @@ -1,3 +1,6 @@ +import 'dart:io'; + +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; @@ -67,7 +70,8 @@ class NoteViewer extends StatelessWidget { launch(link); } }, - imageDirectory: note.parent.folderPath + p.separator, + imageBuilder: (url) => kDefaultImageBuilder( + url, note.parent.folderPath + p.separator, null, null), ), ), // _buildFooter(context), @@ -120,3 +124,60 @@ class NoteTitleHeader extends StatelessWidget { ); } } + +// +// Copied from flutter_markdown +// But it uses CachedNetworkImage +// +typedef Widget ImageBuilder( + Uri uri, String imageDirectory, double width, double height); + +final ImageBuilder kDefaultImageBuilder = ( + Uri uri, + String imageDirectory, + double width, + double height, +) { + if (uri.scheme == 'http' || uri.scheme == 'https') { + return CachedNetworkImage( + imageUrl: uri.toString(), + width: width, + height: height, + placeholder: (context, url) => const CircularProgressIndicator(), + errorWidget: (context, url, error) => const Icon(Icons.error), + ); + } else if (uri.scheme == 'data') { + return _handleDataSchemeUri(uri, width, height); + } else if (uri.scheme == "resource") { + return Image.asset(uri.path, width: width, height: height); + } else { + Uri fileUri = imageDirectory != null + ? Uri.parse(imageDirectory + uri.toString()) + : uri; + if (fileUri.scheme == 'http' || fileUri.scheme == 'https') { + return CachedNetworkImage( + imageUrl: fileUri.toString(), + width: width, + height: height, + placeholder: (context, url) => const CircularProgressIndicator(), + errorWidget: (context, url, error) => const Icon(Icons.error), + ); + } else { + return Image.file(File.fromUri(fileUri), width: width, height: height); + } + } +}; + +Widget _handleDataSchemeUri(Uri uri, final double width, final double height) { + final String mimeType = uri.data.mimeType; + if (mimeType.startsWith('image/')) { + return Image.memory( + uri.data.contentAsBytes(), + width: width, + height: height, + ); + } else if (mimeType.startsWith('text/')) { + return Text(uri.data.contentAsString()); + } + return const SizedBox(); +} diff --git a/pubspec.lock b/pubspec.lock index 805a93b8..c91bc6cd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -78,6 +78,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.6" + cached_network_image: + dependency: "direct main" + description: + name: cached_network_image + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0+1" charcode: dependency: transitive description: @@ -85,6 +92,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.2" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" collection: dependency: transitive description: @@ -197,6 +211,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.2" flutter_crashlytics: dependency: "direct main" description: @@ -490,6 +511,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.6.4" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.5" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" pedantic: dependency: transitive description: @@ -574,6 +616,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.6" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.24.0" screenshots: dependency: "direct dev" description: @@ -677,6 +726,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.5" + sqflite: + dependency: transitive + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0+1" stack_trace: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a7f0003b..ba92b9d1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,7 @@ dependencies: sentry: ">=3.0.0 <4.0.0" equatable: ^1.1.0 purchases_flutter: ^1.1.0 + cached_network_image: ^2.1.0+1 dev_dependencies: flutter_launcher_icons: "^0.7.2"