Jelajahi Sumber

Make backup folder selection skippable

Vishnu Mohandas 4 tahun lalu
induk
melakukan
c1e1a99163

+ 10 - 0
lib/core/configuration.dart

@@ -37,6 +37,8 @@ class Configuration {
   static const keyShouldBackupOverMobileData = "should_backup_over_mobile_data";
   static const keyShouldBackupOverMobileData = "should_backup_over_mobile_data";
   static const keyShouldHideFromRecents = "should_hide_from_recents";
   static const keyShouldHideFromRecents = "should_hide_from_recents";
   static const keyShouldShowLockScreen = "should_show_lock_screen";
   static const keyShouldShowLockScreen = "should_show_lock_screen";
+  static const keyHasSkippedBackupFolderSelection =
+      "has_skipped_backup_folder_selection";
   static const lastTempFolderClearTimeKey = "last_temp_folder_clear_time";
   static const lastTempFolderClearTimeKey = "last_temp_folder_clear_time";
   static const nameKey = "name";
   static const nameKey = "name";
   static const secretKeyKey = "secret_key";
   static const secretKeyKey = "secret_key";
@@ -426,4 +428,12 @@ class Configuration {
   String getVolatilePassword() {
   String getVolatilePassword() {
     return _volatilePassword;
     return _volatilePassword;
   }
   }
+
+  Future<void> skipBackupFolderSelection() async {
+    await _preferences.setBool(keyHasSkippedBackupFolderSelection, true);
+  }
+
+  bool hasSkippedBackupFolderSelection() {
+    return _preferences.getBool(keyHasSkippedBackupFolderSelection) ?? false;
+  }
 }
 }

+ 3 - 0
lib/events/permission_granted_event.dart

@@ -0,0 +1,3 @@
+import 'package:photos/events/event.dart';
+
+class PermissionGrantedEvent extends Event {}

+ 2 - 0
lib/services/sync_service.dart

@@ -11,6 +11,7 @@ import 'package:photos/core/network.dart';
 import 'package:photos/db/files_db.dart';
 import 'package:photos/db/files_db.dart';
 import 'package:photos/events/collection_updated_event.dart';
 import 'package:photos/events/collection_updated_event.dart';
 import 'package:photos/events/local_photos_updated_event.dart';
 import 'package:photos/events/local_photos_updated_event.dart';
+import 'package:photos/events/permission_granted_event.dart';
 import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/events/trigger_logout_event.dart';
 import 'package:photos/events/trigger_logout_event.dart';
@@ -175,6 +176,7 @@ class SyncService {
 
 
   Future<void> onPermissionGranted() async {
   Future<void> onPermissionGranted() async {
     await _prefs.setBool(kHasGrantedPermissionsKey, true);
     await _prefs.setBool(kHasGrantedPermissionsKey, true);
+    Bus.instance.fire(PermissionGrantedEvent());
     _doSync();
     _doSync();
   }
   }
 
 

+ 25 - 14
lib/ui/backup_folder_selection_page.dart

@@ -8,7 +8,6 @@ import 'package:photos/events/backup_folders_updated_event.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/ui/collections_gallery_widget.dart';
 import 'package:photos/ui/collections_gallery_widget.dart';
 import 'package:photos/ui/common_elements.dart';
 import 'package:photos/ui/common_elements.dart';
-import 'package:photos/ui/home_widget.dart';
 import 'package:photos/ui/loading_widget.dart';
 import 'package:photos/ui/loading_widget.dart';
 import 'package:photos/ui/thumbnail_widget.dart';
 import 'package:photos/ui/thumbnail_widget.dart';
 
 
@@ -46,10 +45,17 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
             padding: EdgeInsets.all(12),
             padding: EdgeInsets.all(12),
           ),
           ),
           Center(
           Center(
-              child: SectionTitle(
-            "select folders to preserve",
-            alignment: Alignment.center,
-          )),
+            child: Hero(
+              tag: "select_folders",
+              child: Material(
+                type: MaterialType.transparency,
+                child: SectionTitle(
+                  "select folders to preserve",
+                  alignment: Alignment.center,
+                ),
+              ),
+            ),
+          ),
           Padding(
           Padding(
             padding: EdgeInsets.all(12),
             padding: EdgeInsets.all(12),
           ),
           ),
@@ -70,15 +76,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                       await Configuration.instance
                       await Configuration.instance
                           .setPathsToBackUp(_backedupFolders);
                           .setPathsToBackUp(_backedupFolders);
                       Bus.instance.fire(BackupFoldersUpdatedEvent());
                       Bus.instance.fire(BackupFoldersUpdatedEvent());
-                      Navigator.of(context).pushReplacement(
-                        MaterialPageRoute(
-                          builder: (BuildContext context) {
-                            return Scaffold(
-                              body: HomeWidget(),
-                            );
-                          },
-                        ),
-                      );
+                      Navigator.of(context).pop();
                     },
                     },
             ),
             ),
           ),
           ),
@@ -94,6 +92,19 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
               textAlign: TextAlign.center,
               textAlign: TextAlign.center,
             ),
             ),
           ),
           ),
+          GestureDetector(
+            behavior: HitTestBehavior.translucent,
+            onTap: () async {
+              Navigator.of(context).pop();
+            },
+            child: Padding(
+              padding: const EdgeInsets.fromLTRB(40, 8, 40, 20),
+              child: Text(
+                "skip",
+                style: TextStyle(color: Colors.white.withOpacity(0.8)),
+              ),
+            ),
+          )
         ],
         ],
       ),
       ),
     );
     );

+ 1 - 9
lib/ui/grant_permissions_page.dart → lib/ui/grant_permissions_widget.dart

@@ -2,9 +2,8 @@ import 'package:flutter/material.dart';
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/ui/common_elements.dart';
 import 'package:photos/ui/common_elements.dart';
-import 'package:photos/ui/loading_photos_page.dart';
 
 
-class GrantPermissionsPage extends StatelessWidget {
+class GrantPermissionsWidget extends StatelessWidget {
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     return Center(
     return Center(
@@ -55,13 +54,6 @@ class GrantPermissionsPage extends StatelessWidget {
                 final granted = await PhotoManager.requestPermission();
                 final granted = await PhotoManager.requestPermission();
                 if (granted) {
                 if (granted) {
                   await SyncService.instance.onPermissionGranted();
                   await SyncService.instance.onPermissionGranted();
-                  Navigator.of(context).pushReplacement(
-                    MaterialPageRoute(
-                      builder: (BuildContext context) {
-                        return LoadingPhotosPage();
-                      },
-                    ),
-                  );
                 }
                 }
               },
               },
             ),
             ),

+ 67 - 10
lib/ui/home_widget.dart

@@ -11,7 +11,9 @@ import 'package:photos/core/event_bus.dart';
 import 'package:photos/db/files_db.dart';
 import 'package:photos/db/files_db.dart';
 import 'package:photos/events/backup_folders_updated_event.dart';
 import 'package:photos/events/backup_folders_updated_event.dart';
 import 'package:photos/events/local_photos_updated_event.dart';
 import 'package:photos/events/local_photos_updated_event.dart';
+import 'package:photos/events/permission_granted_event.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
+import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/events/tab_changed_event.dart';
 import 'package:photos/events/tab_changed_event.dart';
 import 'package:photos/events/trigger_logout_event.dart';
 import 'package:photos/events/trigger_logout_event.dart';
 import 'package:photos/events/user_logged_out_event.dart';
 import 'package:photos/events/user_logged_out_event.dart';
@@ -21,21 +23,23 @@ import 'package:photos/services/update_service.dart';
 import 'package:photos/ui/app_update_dialog.dart';
 import 'package:photos/ui/app_update_dialog.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
 import 'package:photos/ui/collections_gallery_widget.dart';
 import 'package:photos/ui/collections_gallery_widget.dart';
+import 'package:photos/ui/common_elements.dart';
 import 'package:photos/ui/extents_page_view.dart';
 import 'package:photos/ui/extents_page_view.dart';
 import 'package:photos/ui/gallery.dart';
 import 'package:photos/ui/gallery.dart';
 import 'package:photos/ui/gallery_app_bar_widget.dart';
 import 'package:photos/ui/gallery_app_bar_widget.dart';
 import 'package:photos/ui/gallery_footer_widget.dart';
 import 'package:photos/ui/gallery_footer_widget.dart';
-import 'package:photos/ui/grant_permissions_page.dart';
-import 'package:photos/ui/loading_photos_page.dart';
+import 'package:photos/ui/grant_permissions_widget.dart';
+import 'package:photos/ui/loading_photos_widget.dart';
 import 'package:photos/ui/memories_widget.dart';
 import 'package:photos/ui/memories_widget.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/nav_bar.dart';
 import 'package:photos/ui/nav_bar.dart';
 import 'package:photos/ui/settings_button.dart';
 import 'package:photos/ui/settings_button.dart';
 import 'package:photos/ui/shared_collections_gallery.dart';
 import 'package:photos/ui/shared_collections_gallery.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
-import 'package:photos/ui/landing_page.dart';
+import 'package:photos/ui/landing_page_widget.dart';
 import 'package:photos/ui/sync_indicator.dart';
 import 'package:photos/ui/sync_indicator.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
+import 'package:photos/utils/navigation_util.dart';
 import 'package:uni_links/uni_links.dart';
 import 'package:uni_links/uni_links.dart';
 
 
 class HomeWidget extends StatefulWidget {
 class HomeWidget extends StatefulWidget {
@@ -61,6 +65,9 @@ class _HomeWidgetState extends State<HomeWidget> {
   StreamSubscription<SubscriptionPurchasedEvent> _subscriptionPurchaseEvent;
   StreamSubscription<SubscriptionPurchasedEvent> _subscriptionPurchaseEvent;
   StreamSubscription<TriggerLogoutEvent> _triggerLogoutEvent;
   StreamSubscription<TriggerLogoutEvent> _triggerLogoutEvent;
   StreamSubscription<UserLoggedOutEvent> _loggedOutEvent;
   StreamSubscription<UserLoggedOutEvent> _loggedOutEvent;
+  StreamSubscription<PermissionGrantedEvent> _permissionGrantedEvent;
+  StreamSubscription<SyncStatusUpdate> _firstImportEvent;
+  StreamSubscription<BackupFoldersUpdatedEvent> _backupFoldersUpdatedEvent;
 
 
   @override
   @override
   void initState() {
   void initState() {
@@ -127,6 +134,25 @@ class _HomeWidgetState extends State<HomeWidget> {
     _loggedOutEvent = Bus.instance.on<UserLoggedOutEvent>().listen((event) {
     _loggedOutEvent = Bus.instance.on<UserLoggedOutEvent>().listen((event) {
       setState(() {});
       setState(() {});
     });
     });
+    _permissionGrantedEvent =
+        Bus.instance.on<PermissionGrantedEvent>().listen((event) async {
+      if (mounted) {
+        setState(() {});
+      }
+    });
+    _firstImportEvent =
+        Bus.instance.on<SyncStatusUpdate>().listen((event) async {
+      if (mounted &&
+          event.status == SyncStatus.completed_first_gallery_import) {
+        setState(() {});
+      }
+    });
+    _backupFoldersUpdatedEvent =
+        Bus.instance.on<BackupFoldersUpdatedEvent>().listen((event) async {
+      if (mounted) {
+        setState(() {});
+      }
+    });
     _initDeepLinks();
     _initDeepLinks();
     UpdateService.instance.shouldUpdate().then((shouldUpdate) {
     UpdateService.instance.shouldUpdate().then((shouldUpdate) {
       if (shouldUpdate) {
       if (shouldUpdate) {
@@ -174,23 +200,22 @@ class _HomeWidgetState extends State<HomeWidget> {
 
 
   Widget _getBody() {
   Widget _getBody() {
     if (!Configuration.instance.hasConfiguredAccount()) {
     if (!Configuration.instance.hasConfiguredAccount()) {
-      return LandingPage();
+      return LandingPageWidget();
     }
     }
     if (!SyncService.instance.hasGrantedPermissions()) {
     if (!SyncService.instance.hasGrantedPermissions()) {
-      return GrantPermissionsPage();
+      return GrantPermissionsWidget();
     }
     }
     if (!SyncService.instance.hasCompletedFirstImport()) {
     if (!SyncService.instance.hasCompletedFirstImport()) {
-      return LoadingPhotosPage();
-    }
-    if (Configuration.instance.getPathsToBackUp().isEmpty) {
-      return BackupFolderSelectionPage();
+      return LoadingPhotosWidget();
     }
     }
 
 
     return Stack(
     return Stack(
       children: [
       children: [
         ExtentsPageView(
         ExtentsPageView(
           children: [
           children: [
-            _getMainGalleryWidget(),
+            Configuration.instance.getPathsToBackUp().isEmpty
+                ? _getBackupFolderSelectionHook()
+                : _getMainGalleryWidget(),
             _deviceFolderGalleryWidget,
             _deviceFolderGalleryWidget,
             _sharedCollectionGallery,
             _sharedCollectionGallery,
           ],
           ],
@@ -286,6 +311,36 @@ class _HomeWidgetState extends State<HomeWidget> {
     );
     );
   }
   }
 
 
+  Widget _getBackupFolderSelectionHook() {
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+      children: [
+        _headerWidgetWithSettingsButton,
+        Center(
+          child: Hero(
+            tag: "select_folders",
+            child: Material(
+              type: MaterialType.transparency,
+              child: Container(
+                width: double.infinity,
+                height: 80,
+                padding: const EdgeInsets.fromLTRB(64, 0, 64, 0),
+                child: button(
+                  "select folders\nto preserve",
+                  fontSize: 16,
+                  onPressed: () async {
+                    routeToPage(context, BackupFolderSelectionPage());
+                  },
+                ),
+              ),
+            ),
+          ),
+        ),
+        Padding(padding: EdgeInsets.all(50)),
+      ],
+    );
+  }
+
   Widget _buildBottomNavigationBar() {
   Widget _buildBottomNavigationBar() {
     return Container(
     return Container(
       decoration: BoxDecoration(
       decoration: BoxDecoration(
@@ -340,6 +395,8 @@ class _HomeWidgetState extends State<HomeWidget> {
     _subscriptionPurchaseEvent.cancel();
     _subscriptionPurchaseEvent.cancel();
     _triggerLogoutEvent.cancel();
     _triggerLogoutEvent.cancel();
     _loggedOutEvent.cancel();
     _loggedOutEvent.cancel();
+    _permissionGrantedEvent.cancel();
+    _firstImportEvent.cancel();
     super.dispose();
     super.dispose();
   }
   }
 }
 }

+ 4 - 4
lib/ui/landing_page.dart → lib/ui/landing_page_widget.dart

@@ -8,14 +8,14 @@ import 'package:photos/ui/password_entry_page.dart';
 import 'package:photos/ui/password_reentry_page.dart';
 import 'package:photos/ui/password_reentry_page.dart';
 import 'package:photos/ui/subscription_page.dart';
 import 'package:photos/ui/subscription_page.dart';
 
 
-class LandingPage extends StatefulWidget {
-  const LandingPage({Key key}) : super(key: key);
+class LandingPageWidget extends StatefulWidget {
+  const LandingPageWidget({Key key}) : super(key: key);
 
 
   @override
   @override
-  _LandingPageState createState() => _LandingPageState();
+  _LandingPageWidgetState createState() => _LandingPageWidgetState();
 }
 }
 
 
-class _LandingPageState extends State<LandingPage> {
+class _LandingPageWidgetState extends State<LandingPageWidget> {
   double _featureIndex = 0;
   double _featureIndex = 0;
 
 
   @override
   @override

+ 6 - 11
lib/ui/loading_photos_page.dart → lib/ui/loading_photos_widget.dart

@@ -5,15 +5,16 @@ import 'package:loading_animations/loading_animations.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
+import 'package:photos/utils/navigation_util.dart';
 
 
-class LoadingPhotosPage extends StatefulWidget {
-  const LoadingPhotosPage({Key key}) : super(key: key);
+class LoadingPhotosWidget extends StatefulWidget {
+  const LoadingPhotosWidget({Key key}) : super(key: key);
 
 
   @override
   @override
-  _LoadingPhotosPageState createState() => _LoadingPhotosPageState();
+  _LoadingPhotosWidgetState createState() => _LoadingPhotosWidgetState();
 }
 }
 
 
-class _LoadingPhotosPageState extends State<LoadingPhotosPage> {
+class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
   StreamSubscription<SyncStatusUpdate> _firstImportEvent;
   StreamSubscription<SyncStatusUpdate> _firstImportEvent;
   int _currentPage = 0;
   int _currentPage = 0;
   PageController _pageController = PageController(
   PageController _pageController = PageController(
@@ -37,13 +38,7 @@ class _LoadingPhotosPageState extends State<LoadingPhotosPage> {
         Bus.instance.on<SyncStatusUpdate>().listen((event) async {
         Bus.instance.on<SyncStatusUpdate>().listen((event) async {
       if (mounted &&
       if (mounted &&
           event.status == SyncStatus.completed_first_gallery_import) {
           event.status == SyncStatus.completed_first_gallery_import) {
-        Navigator.of(context).pushReplacement(
-          MaterialPageRoute(
-            builder: (BuildContext context) {
-              return BackupFolderSelectionPage();
-            },
-          ),
-        );
+        routeToPage(context, BackupFolderSelectionPage());
       }
       }
     });
     });