Browse Source

Sync photos on resume

Vishnu Mohandas 5 years ago
parent
commit
46f0e7905f
6 changed files with 59 additions and 175 deletions
  1. 15 5
      lib/main.dart
  2. 3 151
      lib/photo_provider.dart
  3. 24 11
      lib/photo_sync_manager.dart
  4. 3 2
      lib/ui/detail_page.dart
  5. 2 6
      lib/ui/gallery.dart
  6. 12 0
      lib/ui/thumbnail_widget.dart

+ 15 - 5
lib/main.dart

@@ -6,19 +6,20 @@ import 'package:myapp/photo_sync_manager.dart';
 import 'package:myapp/ui/home_widget.dart';
 import 'package:provider/provider.dart';
 
-final provider = PhotoProvider();
-final logger = Logger();
-
 void main() async {
   WidgetsFlutterBinding.ensureInitialized();
   runApp(MyApp());
-  provider.refreshGalleryList().then((_) => PhotoSyncManager(provider.list));
+  PhotoProvider.instance
+      .refreshGalleryList()
+      .then((_) => PhotoSyncManager.instance.load(PhotoProvider.instance.list));
 }
 
-class MyApp extends StatelessWidget {
+class MyApp extends StatelessWidget with WidgetsBindingObserver {
   final _title = 'Orma';
   @override
   Widget build(BuildContext context) {
+    WidgetsBinding.instance.addObserver(this);
+
     return MaterialApp(
       title: _title,
       theme: ThemeData.dark(),
@@ -28,4 +29,13 @@ class MyApp extends StatelessWidget {
       ),
     );
   }
+
+  @override
+  void didChangeAppLifecycleState(AppLifecycleState state) {
+    if (state == AppLifecycleState.resumed) {
+      PhotoProvider.instance.refreshGalleryList().then((_) {
+        return PhotoSyncManager.instance.load(PhotoProvider.instance.list);
+      });
+    }
+  }
 }

+ 3 - 151
lib/photo_provider.dart

@@ -1,89 +1,13 @@
 import 'package:flutter/foundation.dart';
 import 'package:photo_manager/photo_manager.dart';
 
-import 'main.dart';
-
 class PhotoProvider extends ChangeNotifier {
-  List<AssetPathEntity> list = [];
-
-  RequestType type = RequestType.all;
-
-  DateTime dt = DateTime.now();
-
-  var hasAll = true;
-
-  var onlyAll = false;
-
-  Map<AssetPathEntity, PathProvider> pathProviderMap = {};
-
-  bool _notifying = false;
-
-  bool _needTitle = false;
-
-  bool get needTitle => _needTitle;
-
-  set needTitle(bool needTitle) {
-    _needTitle = needTitle;
-    notifyListeners();
-  }
-
-  bool get notifying => _notifying;
-
-  Duration _minDuration = Duration(seconds: 10);
-
-  Duration get minDuration => _minDuration;
-
-  set minDuration(Duration minDuration) {
-    _minDuration = minDuration;
-    notifyListeners();
-  }
-
-  Duration _maxDuration = Duration(hours: 1);
-
-  Duration get maxDuration => _maxDuration;
-
-  set maxDuration(Duration maxDuration) {
-    _maxDuration = maxDuration;
-    notifyListeners();
-  }
-
-  set notifying(bool notifying) {
-    _notifying = notifying;
-    notifyListeners();
-  }
-
-  void changeType(RequestType type) {
-    this.type = type;
-    notifyListeners();
-  }
-
-  void changeHasAll(bool value) {
-    this.hasAll = value;
-    notifyListeners();
-  }
-
-  void changeOnlyAll(bool value) {
-    this.onlyAll = value;
-    notifyListeners();
-  }
-
-  void changeDateToNow() {
-    this.dt = DateTime.now();
-    notifyListeners();
-  }
+  PhotoProvider._privateConstructor();
+  static final PhotoProvider instance = PhotoProvider._privateConstructor();
 
-  void changeDate(DateTime pickDt) {
-    this.dt = pickDt;
-    notifyListeners();
-  }
-
-  void reset() {
-    this.list.clear();
-    pathProviderMap.clear();
-  }
+  List<AssetPathEntity> list = [];
 
   Future<void> refreshGalleryList() async {
-    reset();
     var result = await PhotoManager.requestPermission();
     if (!result) {
       print("Did not get permission");
@@ -100,76 +24,4 @@ class PhotoProvider extends ChangeNotifier {
     this.list.clear();
     this.list.addAll(galleryList);
   }
-
-  Future<void> refreshAllGalleryProperties() async {
-    for (var gallery in list) {
-      await gallery.refreshPathProperties();
-    }
-    notifyListeners();
-  }
-
-  PathProvider getOrCreatePathProvider(AssetPathEntity pathEntity) {
-    pathProviderMap[pathEntity] ??= PathProvider(pathEntity);
-    return pathProviderMap[pathEntity];
-  }
-}
-
-class PathProvider extends ChangeNotifier {
-  static const loadCount = 50;
-
-  bool isInit = false;
-
-  final AssetPathEntity path;
-  PathProvider(this.path);
-
-  List<AssetEntity> list = [];
-
-  var page = 0;
-
-  int get showItemCount {
-    if (list.length == path.assetCount) {
-      return path.assetCount;
-    } else {
-      return path.assetCount;
-    }
-  }
-
-  Future onRefresh() async {
-    final list = await path.getAssetListPaged(0, loadCount);
-    page = 0;
-    this.list.clear();
-    this.list.addAll(list);
-    isInit = true;
-    notifyListeners();
-    printListLength("onRefresh");
-  }
-
-  Future<void> onLoadMore() async {
-    if (showItemCount > path.assetCount) {
-      print("already max");
-      return;
-    }
-    final list = await path.getAssetListPaged(page + 1, loadCount);
-    page = page + 1;
-    this.list.addAll(list);
-    notifyListeners();
-    printListLength("loadmore");
-  }
-
-  void delete(AssetEntity entity) async {
-    final result = await PhotoManager.editor.deleteWithIds([entity.id]);
-    if (result.isNotEmpty) {
-      await Future.delayed(Duration(seconds: 3));
-      await provider.refreshAllGalleryProperties();
-      final list =
-          await path.getAssetListRange(start: 0, end: this.list.length);
-      printListLength("deleted");
-      this.list.clear();
-      this.list.addAll(list);
-    }
-  }
-
-  void printListLength(String tag) {
-    print("$tag length : ${list.length}");
-  }
 }

+ 24 - 11
lib/photo_sync_manager.dart

@@ -15,14 +15,22 @@ import 'package:myapp/core/constants.dart' as Constants;
 class PhotoSyncManager {
   final _logger = Logger();
   final _dio = Dio();
+  bool _isLoadInProgress = false;
+
   static final _lastSyncTimestampKey = "last_sync_timestamp_0";
   static final _lastDBUpdateTimestampKey = "last_db_update_timestamp";
 
-  PhotoSyncManager(List<AssetPathEntity> pathEntities) {
-    init(pathEntities);
-  }
+  PhotoSyncManager._privateConstructor();
+  static final PhotoSyncManager instance =
+      PhotoSyncManager._privateConstructor();
 
-  Future<void> init(List<AssetPathEntity> pathEntities) async {
+  Future<void> load(List<AssetPathEntity> pathEntities) async {
+    if (_isLoadInProgress) {
+      _logger.w("Load already in progress, skipping.");
+      return;
+    }
+    _isLoadInProgress = true;
+    _logger.i("Loading...");
     final prefs = await SharedPreferences.getInstance();
     var lastDBUpdateTimestamp = prefs.getInt(_lastDBUpdateTimestampKey);
     if (lastDBUpdateTimestamp == null) {
@@ -47,14 +55,19 @@ class PhotoSyncManager {
         }
       }
     }
-    photos.sort((first, second) =>
-        first.createTimestamp.compareTo(second.createTimestamp));
-
-    _updateDatabase(photos, prefs, lastDBUpdateTimestamp).then((_) {
-      _syncPhotos().then((_) {
-        _deletePhotos();
+    if (photos.isEmpty) {
+      _isLoadInProgress = false;
+      return;
+    } else {
+      photos.sort((first, second) =>
+          first.createTimestamp.compareTo(second.createTimestamp));
+      _updateDatabase(photos, prefs, lastDBUpdateTimestamp).then((_) {
+        _isLoadInProgress = false;
+        _syncPhotos().then((_) {
+          _deletePhotos();
+        });
       });
-    });
+    }
   }
 
   Future<bool> _updateDatabase(final List<Photo> photos,

+ 3 - 2
lib/ui/detail_page.dart

@@ -26,7 +26,6 @@ class _DetailPageState extends State<DetailPage> {
 
   @override
   void initState() {
-    Logger().i("initState");
     _photos = widget.photos;
     _selectedIndex = widget.selectedIndex;
     _cachedImages = LRUMap<int, ZoomableImage>(5);
@@ -36,10 +35,12 @@ class _DetailPageState extends State<DetailPage> {
   @override
   Widget build(BuildContext context) {
     Logger().i("Opening " +
+        _photos[_selectedIndex].title +
+        ", " +
         _selectedIndex.toString() +
         " / " +
         _photos.length.toString() +
-        "photos .");
+        " photos .");
     return Scaffold(
       appBar: _buildAppBar(),
       body: Center(

+ 2 - 6
lib/ui/gallery.dart

@@ -34,14 +34,10 @@ class _GalleryState extends State<Gallery> {
   bool _shouldSelectOnTap = false;
   List<Photo> _photos;
 
-  @override
-  void initState() {
-    _photos = widget.photos;
-    super.initState();
-  }
-
   @override
   Widget build(BuildContext context) {
+    _photos = widget.photos;
+    Logger().i("Building with " + _photos.length.toString());
     _collatePhotos();
 
     return ListView.builder(

+ 12 - 0
lib/ui/thumbnail_widget.dart

@@ -60,4 +60,16 @@ class _ThumbnailWidgetState extends State<ThumbnailWidget> {
       return loadingWidget;
     }
   }
+
+  @override
+  void didUpdateWidget(ThumbnailWidget oldWidget) {
+    super.didUpdateWidget(oldWidget);
+    if (widget.photo.generatedId != oldWidget.photo.generatedId) {
+      setState(() {
+        _loadedSmallThumbnail = false;
+        _loadedLargeThumbnail = false;
+        _imageProvider = null;
+      });
+    }
+  }
 }