소스 검색

Download and render encrypted files

Vishnu Mohandas 4 년 전
부모
커밋
228ea5990d
3개의 변경된 파일71개의 추가작업 그리고 16개의 파일을 삭제
  1. 69 15
      lib/ui/zoomable_image.dart
  2. 1 1
      pubspec.lock
  3. 1 0
      pubspec.yaml

+ 69 - 15
lib/ui/zoomable_image.dart

@@ -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);
             }
           });
         });

+ 1 - 1
pubspec.lock

@@ -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"

+ 1 - 0
pubspec.yaml

@@ -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: