Browse Source

Merge pull request #449 from ente-io/hide-files

Hide files
Ashil 2 năm trước cách đây
mục cha
commit
d686e4aba4

+ 61 - 8
lib/db/files_db.dart

@@ -9,6 +9,7 @@ import 'package:photos/models/file_load_result.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/location.dart';
 import 'package:photos/models/location.dart';
 import 'package:photos/models/magic_metadata.dart';
 import 'package:photos/models/magic_metadata.dart';
+import 'package:photos/services/feature_flag_service.dart';
 import 'package:sqflite/sqflite.dart';
 import 'package:sqflite/sqflite.dart';
 import 'package:sqflite_migration/sqflite_migration.dart';
 import 'package:sqflite_migration/sqflite_migration.dart';
 
 
@@ -95,7 +96,8 @@ class FilesDB {
 
 
   // this opens the database (and creates it if it doesn't exist)
   // this opens the database (and creates it if it doesn't exist)
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    final Directory documentsDirectory = await getApplicationDocumentsDirectory();
+    final Directory documentsDirectory =
+        await getApplicationDocumentsDirectory();
     final String path = join(documentsDirectory.path, _databaseName);
     final String path = join(documentsDirectory.path, _databaseName);
     _logger.info("DB path " + path);
     _logger.info("DB path " + path);
     return await openDatabaseWithMigration(path, dbConfig);
     return await openDatabaseWithMigration(path, dbConfig);
@@ -430,6 +432,26 @@ class FilesDB {
     return FileLoadResult(deduplicatedFiles, files.length == limit);
     return FileLoadResult(deduplicatedFiles, files.length == limit);
   }
   }
 
 
+  Future<Set<int>> getCollectionIDsOfHiddenFiles(
+    int ownerID, {
+    int visibility = kVisibilityArchive,
+  }) async {
+    final db = await instance.database;
+    final results = await db.query(
+      table,
+      where:
+          '$columnOwnerID = ? AND $columnMMdVisibility = ? AND $columnCollectionID != -1',
+      columns: [columnCollectionID],
+      whereArgs: [ownerID, visibility],
+      distinct: true,
+    );
+    Set<int> collectionIDsOfHiddenFiles = {};
+    for (var result in results) {
+      collectionIDsOfHiddenFiles.add(result['collection_id']);
+    }
+    return collectionIDsOfHiddenFiles;
+  }
+
   Future<FileLoadResult> getAllLocalAndUploadedFiles(
   Future<FileLoadResult> getAllLocalAndUploadedFiles(
     int startTime,
     int startTime,
     int endTime,
     int endTime,
@@ -529,14 +551,26 @@ class FilesDB {
     int endTime, {
     int endTime, {
     int limit,
     int limit,
     bool asc,
     bool asc,
+    int visibility = kVisibilityVisible,
   }) async {
   }) async {
     final db = await instance.database;
     final db = await instance.database;
     final order = (asc ?? false ? 'ASC' : 'DESC');
     final order = (asc ?? false ? 'ASC' : 'DESC');
+    String whereClause;
+    List<Object> whereArgs;
+    if (FeatureFlagService.instance.isInternalUserOrDebugBuild()) {
+      whereClause =
+          '$columnCollectionID = ? AND $columnCreationTime >= ? AND $columnCreationTime <= ? AND $columnMMdVisibility = ?';
+      whereArgs = [collectionID, startTime, endTime, visibility];
+    } else {
+      whereClause =
+          '$columnCollectionID = ? AND $columnCreationTime >= ? AND $columnCreationTime <= ?';
+      whereArgs = [collectionID, startTime, endTime];
+    }
+
     final results = await db.query(
     final results = await db.query(
       table,
       table,
-      where:
-          '$columnCollectionID = ? AND $columnCreationTime >= ? AND $columnCreationTime <= ?',
-      whereArgs: [collectionID, startTime, endTime],
+      where: whereClause,
+      whereArgs: whereArgs,
       orderBy:
       orderBy:
           '$columnCreationTime ' + order + ', $columnModificationTime ' + order,
           '$columnCreationTime ' + order + ', $columnModificationTime ' + order,
       limit: limit,
       limit: limit,
@@ -1006,9 +1040,23 @@ class FilesDB {
   }
   }
 
 
   Future<List<File>> getLatestCollectionFiles() async {
   Future<List<File>> getLatestCollectionFiles() async {
-    final db = await instance.database;
-    final rows = await db.rawQuery(
-      '''
+    String query;
+    if (FeatureFlagService.instance.isInternalUserOrDebugBuild()) {
+      query = '''
+      SELECT $table.*
+      FROM $table
+      INNER JOIN
+        (
+          SELECT $columnCollectionID, MAX($columnCreationTime) AS max_creation_time
+          FROM $table
+          WHERE ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1 AND $columnMMdVisibility = $kVisibilityVisible)
+          GROUP BY $columnCollectionID
+        ) latest_files
+        ON $table.$columnCollectionID = latest_files.$columnCollectionID
+        AND $table.$columnCreationTime = latest_files.max_creation_time;
+    ''';
+    } else {
+      query = '''
       SELECT $table.*
       SELECT $table.*
       FROM $table
       FROM $table
       INNER JOIN
       INNER JOIN
@@ -1020,7 +1068,12 @@ class FilesDB {
         ) latest_files
         ) latest_files
         ON $table.$columnCollectionID = latest_files.$columnCollectionID
         ON $table.$columnCollectionID = latest_files.$columnCollectionID
         AND $table.$columnCreationTime = latest_files.max_creation_time;
         AND $table.$columnCreationTime = latest_files.max_creation_time;
-    ''',
+    ''';
+    }
+
+    final db = await instance.database;
+    final rows = await db.rawQuery(
+      query,
     );
     );
     final files = _convertToFiles(rows);
     final files = _convertToFiles(rows);
     // TODO: Do this de-duplication within the SQL Query
     // TODO: Do this de-duplication within the SQL Query

+ 3 - 3
lib/services/feature_flag_service.dart

@@ -86,15 +86,15 @@ class FeatureFlagService {
 
 
   bool enableSearch() {
   bool enableSearch() {
     try {
     try {
-      return _isInternalUserOrDebugBuild() || _getFeatureFlags().enableSearch;
+      return isInternalUserOrDebugBuild() || _getFeatureFlags().enableSearch;
     } catch (e) {
     } catch (e) {
       _logger.severe("failed to getSearchFeatureFlag", e);
       _logger.severe("failed to getSearchFeatureFlag", e);
       return FFDefault.enableSearch;
       return FFDefault.enableSearch;
     }
     }
   }
   }
 
 
-  bool _isInternalUserOrDebugBuild() {
-    final String email = Configuration.instance.getEmail();
+  bool isInternalUserOrDebugBuild() {
+    String email = Configuration.instance.getEmail();
     return (email != null && email.endsWith("@ente.io")) || kDebugMode;
     return (email != null && email.endsWith("@ente.io")) || kDebugMode;
   }
   }
 
 

+ 30 - 2
lib/ui/viewer/gallery/gallery_app_bar_widget.dart

@@ -4,12 +4,16 @@ import 'package:flutter/material.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
+import 'package:photos/db/files_db.dart';
+import 'package:photos/ente_theme_data.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/models/collection.dart';
 import 'package:photos/models/collection.dart';
 import 'package:photos/models/gallery_type.dart';
 import 'package:photos/models/gallery_type.dart';
 import 'package:photos/models/magic_metadata.dart';
 import 'package:photos/models/magic_metadata.dart';
 import 'package:photos/models/selected_files.dart';
 import 'package:photos/models/selected_files.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/collections_service.dart';
+import 'package:photos/services/feature_flag_service.dart';
+import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/rename_dialog.dart';
 import 'package:photos/ui/common/rename_dialog.dart';
 import 'package:photos/ui/sharing/share_collection_widget.dart';
 import 'package:photos/ui/sharing/share_collection_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
@@ -128,8 +132,24 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
           message: "Share",
           message: "Share",
           child: IconButton(
           child: IconButton(
             icon: Icon(Icons.adaptive.share),
             icon: Icon(Icons.adaptive.share),
-            onPressed: () {
-              _showShareCollectionDialog();
+            onPressed: () async {
+              if (FeatureFlagService.instance.isInternalUserOrDebugBuild() &&
+                  await _collectionHasHiddenFiles(widget.collection.id)) {
+                final choice = await showChoiceDialog(
+                  context,
+                  'Share hidden items?',
+                  "Looks like you're trying to share an album that has some hidden items.\n\nThese hidden items can be seen by the recipient.",
+                  firstAction: "Cancel",
+                  secondAction: "Share anyway",
+                  secondActionColor:
+                      Theme.of(context).colorScheme.defaultTextColor,
+                );
+                if (choice == DialogUserChoice.secondChoice) {
+                  _showShareCollectionDialog();
+                }
+              } else {
+                _showShareCollectionDialog();
+              }
             },
             },
           ),
           ),
         ),
         ),
@@ -225,4 +245,12 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
       showGenericErrorDialog(context);
       showGenericErrorDialog(context);
     }
     }
   }
   }
+
+  Future<bool> _collectionHasHiddenFiles(int collectionID) async {
+    final collectionIDsWithHiddenFiles =
+        await FilesDB.instance.getCollectionIDsOfHiddenFiles(
+      Configuration.instance.getUserID(),
+    );
+    return collectionIDsWithHiddenFiles.contains(collectionID);
+  }
 }
 }