Download and render encrypted files

This commit is contained in:
Vishnu Mohandas 2020-08-13 06:22:05 +05:30
parent 35aeae2cc7
commit 228ea5990d
3 changed files with 71 additions and 16 deletions

View file

@ -1,14 +1,19 @@
import 'dart:io' as io;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:logging/logging.dart';
import 'package:photos/core/cache/image_cache.dart';
import 'package:photos/core/cache/thumbnail_cache.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/models/file.dart';
import 'package:photos/ui/loading_widget.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photos/core/constants.dart';
import 'package:photos/utils/crypto_util.dart';
class ZoomableImage extends StatefulWidget {
final File photo;
@ -31,6 +36,7 @@ class ZoomableImage extends StatefulWidget {
class _ZoomableImageState extends State<ZoomableImage>
with SingleTickerProviderStateMixin {
final Logger _logger = Logger("ZoomableImage");
File _photo;
ImageProvider _imageProvider;
bool _loadedSmallThumbnail = false;
bool _loadingLargeThumbnail = false;
@ -51,7 +57,8 @@ class _ZoomableImageState extends State<ZoomableImage>
@override
Widget build(BuildContext context) {
if (widget.photo.localID == null) {
_photo = widget.photo;
if (_photo.localID == null) {
_loadNetworkImage();
} else {
_loadLocalImage(context);
@ -64,7 +71,7 @@ class _ZoomableImageState extends State<ZoomableImage>
minScale: PhotoViewComputedScale.contained,
gaplessPlayback: true,
heroAttributes: PhotoViewHeroAttributes(
tag: widget.tagPrefix + widget.photo.tag(),
tag: widget.tagPrefix + _photo.tag(),
),
backgroundDecoration: widget.backgroundDecoration,
);
@ -74,39 +81,86 @@ class _ZoomableImageState extends State<ZoomableImage>
}
void _loadNetworkImage() {
if (!_photo.isEncrypted) {
_loadUnencryptedImage();
} else {
_loadEncryptedImage();
}
}
void _loadUnencryptedImage() {
if (!_loadedSmallThumbnail && !_loadedFinalImage) {
_imageProvider =
CachedNetworkImageProvider(widget.photo.getThumbnailUrl());
_imageProvider = CachedNetworkImageProvider(_photo.getThumbnailUrl());
_loadedSmallThumbnail = true;
}
if (!_loadedFinalImage) {
if (BytesLruCache.get(widget.photo) != null) {
if (BytesLruCache.get(_photo) != null) {
_onFinalImageLoaded(
Image.memory(
BytesLruCache.get(widget.photo),
BytesLruCache.get(_photo),
gaplessPlayback: true,
).image,
context);
} else {
widget.photo.getBytes().then((data) {
_photo.getBytes().then((data) {
_onFinalImageLoaded(
Image.memory(
data,
gaplessPlayback: true,
).image,
context);
BytesLruCache.put(widget.photo, data);
BytesLruCache.put(_photo, data);
});
}
}
}
void _loadEncryptedImage() {
if (!_loadedSmallThumbnail && !_loadedFinalImage) {
if (ThumbnailFileLruCache.get(_photo) != null) {
_imageProvider = Image.file(
ThumbnailFileLruCache.get(_photo),
).image;
_loadedSmallThumbnail = true;
}
}
if (!_loadedFinalImage) {
final url = _photo.getDownloadUrl();
DefaultCacheManager().getFileFromCache(url).then((info) {
if (info == null) {
final temporaryPath = Configuration.instance.getTempDirectory() +
_photo.generatedID.toString() +
".aes";
Dio().download(url, temporaryPath).then((_) async {
final data = await CryptoUtil.decryptFileToData(
temporaryPath, Configuration.instance.getKey());
io.File(temporaryPath).deleteSync();
DefaultCacheManager().putFile(url, data);
_onFinalImageLoaded(
Image.memory(
data,
gaplessPlayback: true,
).image,
context);
});
} else {
_onFinalImageLoaded(
Image.memory(
info.file.readAsBytesSync(),
gaplessPlayback: true,
).image,
context);
}
});
}
}
void _loadLocalImage(BuildContext context) {
if (!_loadedSmallThumbnail &&
!_loadedLargeThumbnail &&
!_loadedFinalImage) {
final cachedThumbnail =
ThumbnailLruCache.get(widget.photo, THUMBNAIL_SMALL_SIZE);
ThumbnailLruCache.get(_photo, THUMBNAIL_SMALL_SIZE);
if (cachedThumbnail != null) {
_imageProvider = Image.memory(cachedThumbnail).image;
_loadedSmallThumbnail = true;
@ -118,16 +172,16 @@ class _ZoomableImageState extends State<ZoomableImage>
!_loadedFinalImage) {
_loadingLargeThumbnail = true;
final cachedThumbnail =
ThumbnailLruCache.get(widget.photo, THUMBNAIL_LARGE_SIZE);
ThumbnailLruCache.get(_photo, THUMBNAIL_LARGE_SIZE);
if (cachedThumbnail != null) {
_onLargeThumbnailLoaded(Image.memory(cachedThumbnail).image, context);
} else {
widget.photo.getAsset().then((asset) {
_photo.getAsset().then((asset) {
asset
.thumbDataWithSize(THUMBNAIL_LARGE_SIZE, THUMBNAIL_LARGE_SIZE)
.then((data) {
_onLargeThumbnailLoaded(Image.memory(data).image, context);
ThumbnailLruCache.put(widget.photo, THUMBNAIL_LARGE_SIZE, data);
ThumbnailLruCache.put(_photo, THUMBNAIL_LARGE_SIZE, data);
});
});
}
@ -135,15 +189,15 @@ class _ZoomableImageState extends State<ZoomableImage>
if (!_loadingFinalImage && !_loadedFinalImage) {
_loadingFinalImage = true;
final cachedFile = FileLruCache.get(widget.photo);
final cachedFile = FileLruCache.get(_photo);
if (cachedFile != null) {
_onFinalImageLoaded(Image.file(cachedFile).image, context);
} else {
widget.photo.getAsset().then((asset) {
_photo.getAsset().then((asset) {
asset.file.then((file) {
if (mounted) {
_onFinalImageLoaded(Image.file(file).image, context);
FileLruCache.put(widget.photo, file);
FileLruCache.put(_photo, file);
}
});
});

View file

@ -224,7 +224,7 @@ packages:
source: hosted
version: "0.5.0"
flutter_cache_manager:
dependency: transitive
dependency: "direct main"
description:
name: flutter_cache_manager
url: "https://pub.dartlang.org"

View file

@ -57,6 +57,7 @@ dependencies:
cached_network_image: ^2.3.0-beta
progress_dialog: ^1.2.4
animate_do: ^1.7.2
flutter_cache_manager: ^1.4.1
dev_dependencies:
flutter_test: