From f6e4659fb67f71c15b9781a82fe2f7cae33a2e39 Mon Sep 17 00:00:00 2001 From: ashilkn Date: Fri, 26 Aug 2022 17:44:40 +0530 Subject: [PATCH 1/8] hid hidden files from albums --- lib/db/files_db.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/db/files_db.dart b/lib/db/files_db.dart index a34de3974..1f41fd0a5 100644 --- a/lib/db/files_db.dart +++ b/lib/db/files_db.dart @@ -529,14 +529,15 @@ class FilesDB { int endTime, { int limit, bool asc, + int visibility = kVisibilityVisible, }) async { final db = await instance.database; final order = (asc ?? false ? 'ASC' : 'DESC'); final results = await db.query( table, where: - '$columnCollectionID = ? AND $columnCreationTime >= ? AND $columnCreationTime <= ?', - whereArgs: [collectionID, startTime, endTime], + '$columnCollectionID = ? AND $columnCreationTime >= ? AND $columnCreationTime <= ? AND $columnMMdVisibility = ?', + whereArgs: [collectionID, startTime, endTime, visibility], orderBy: '$columnCreationTime ' + order + ', $columnModificationTime ' + order, limit: limit, From 66a50ff04552b1d901d688de0b39ee6a5e84921a Mon Sep 17 00:00:00 2001 From: ashilkn Date: Fri, 26 Aug 2022 17:57:59 +0530 Subject: [PATCH 2/8] get latest visible file from collection on getLatestVisibleFiles() --- lib/db/files_db.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/db/files_db.dart b/lib/db/files_db.dart index 1f41fd0a5..a80c9f874 100644 --- a/lib/db/files_db.dart +++ b/lib/db/files_db.dart @@ -1016,7 +1016,7 @@ class FilesDB { ( SELECT $columnCollectionID, MAX($columnCreationTime) AS max_creation_time FROM $table - WHERE ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1) + WHERE ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1 AND $columnMMdVisibility = $kVisibilityVisible) GROUP BY $columnCollectionID ) latest_files ON $table.$columnCollectionID = latest_files.$columnCollectionID From 5fac3dae60c0daacd23b0054cdd81e07a26ee5fb Mon Sep 17 00:00:00 2001 From: ashilkn Date: Fri, 26 Aug 2022 20:14:11 +0530 Subject: [PATCH 3/8] made a service to get set of collectionIDs of collections with hidden files --- lib/db/files_db.dart | 20 +++++++++++++++++++- lib/ui/home_widget.dart | 2 +- lib/ui/viewer/gallery/archive_page.dart | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/db/files_db.dart b/lib/db/files_db.dart index a80c9f874..1ce42aad7 100644 --- a/lib/db/files_db.dart +++ b/lib/db/files_db.dart @@ -403,7 +403,7 @@ class FilesDB { return BackedUpFileIDs(localIDs.toList(), uploadedIDs.toList()); } - Future getAllUploadedFiles( + Future getAllUploadedVisibleFiles( int startTime, int endTime, int ownerID, { @@ -430,6 +430,24 @@ class FilesDB { return FileLoadResult(deduplicatedFiles, files.length == limit); } + Future> getCollectionIDsOfHiddenFiles( + int ownerID, { + int visibility = kVisibilityArchive, + }) async { + final db = await instance.database; + final results = await db.query( + table, + where: '$columnOwnerID = ? AND $columnMMdVisibility = ?', + columns: [columnCollectionID], + whereArgs: [ownerID, visibility], + ); + List collectionIDsOfHiddenFiles = []; + for (var result in results) { + collectionIDsOfHiddenFiles.add(result['collection_id']); + } + return collectionIDsOfHiddenFiles.toSet(); + } + Future getAllLocalAndUploadedFiles( int startTime, int endTime, diff --git a/lib/ui/home_widget.dart b/lib/ui/home_widget.dart index 14c964801..173f2a469 100644 --- a/lib/ui/home_widget.dart +++ b/lib/ui/home_widget.dart @@ -416,7 +416,7 @@ class _HomeWidgetState extends State { ignoredCollectionIDs: archivedCollectionIds, ); } else { - result = await FilesDB.instance.getAllUploadedFiles( + result = await FilesDB.instance.getAllUploadedVisibleFiles( creationStartTime, creationEndTime, ownerID, diff --git a/lib/ui/viewer/gallery/archive_page.dart b/lib/ui/viewer/gallery/archive_page.dart index 42c7f219c..c052d88e5 100644 --- a/lib/ui/viewer/gallery/archive_page.dart +++ b/lib/ui/viewer/gallery/archive_page.dart @@ -27,7 +27,7 @@ class ArchivePage extends StatelessWidget { Widget build(Object context) { final gallery = Gallery( asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) { - return FilesDB.instance.getAllUploadedFiles( + return FilesDB.instance.getAllUploadedVisibleFiles( creationStartTime, creationEndTime, Configuration.instance.getUserID(), From 82b008496a67ca1d7d9df28990466e76415086a6 Mon Sep 17 00:00:00 2001 From: ashilkn Date: Sat, 27 Aug 2022 13:00:40 +0530 Subject: [PATCH 4/8] warn user before sharing an album containing hidden files --- .../gallery/gallery_app_bar_widget.dart | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/lib/ui/viewer/gallery/gallery_app_bar_widget.dart index 54ab543b0..d30da3bf7 100644 --- a/lib/ui/viewer/gallery/gallery_app_bar_widget.dart +++ b/lib/ui/viewer/gallery/gallery_app_bar_widget.dart @@ -4,12 +4,15 @@ import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; import 'package:photos/core/configuration.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/models/collection.dart'; import 'package:photos/models/gallery_type.dart'; import 'package:photos/models/magic_metadata.dart'; import 'package:photos/models/selected_files.dart'; import 'package:photos/services/collections_service.dart'; +import 'package:photos/ui/common/dialogs.dart'; import 'package:photos/ui/common/rename_dialog.dart'; import 'package:photos/ui/sharing/share_collection_widget.dart'; import 'package:photos/utils/dialog_util.dart'; @@ -128,8 +131,25 @@ class _GalleryAppBarWidgetState extends State { message: "Share", child: IconButton( icon: Icon(Icons.adaptive.share), - onPressed: () { - _showShareCollectionDialog(); + onPressed: () async { + if (await _collectionHasSharedFiles()) { + 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) { + return; + } else { + _showShareCollectionDialog(); + } + } else { + _showShareCollectionDialog(); + } }, ), ), @@ -225,4 +245,12 @@ class _GalleryAppBarWidgetState extends State { showGenericErrorDialog(context); } } + + Future _collectionHasSharedFiles() async { + final collectionIDsWithHiddenFiles = + await FilesDB.instance.getCollectionIDsOfHiddenFiles( + Configuration.instance.getUserID(), + ); + return collectionIDsWithHiddenFiles.contains(widget.collection.id); + } } From 89892ea9f1b24b0d783e3816cd3647e1c94f0665 Mon Sep 17 00:00:00 2001 From: ashilkn Date: Sat, 27 Aug 2022 15:24:06 +0530 Subject: [PATCH 5/8] enable extra hidden features only for internal testers or on debug build --- lib/db/files_db.dart | 47 +++++++++++++++---- lib/services/feature_flag_service.dart | 4 +- lib/ui/home_widget.dart | 2 +- lib/ui/viewer/gallery/archive_page.dart | 2 +- .../gallery/gallery_app_bar_widget.dart | 4 +- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/lib/db/files_db.dart b/lib/db/files_db.dart index 1ce42aad7..56acd344e 100644 --- a/lib/db/files_db.dart +++ b/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/location.dart'; import 'package:photos/models/magic_metadata.dart'; +import 'package:photos/services/feature_flag_service.dart'; import 'package:sqflite/sqflite.dart'; import 'package:sqflite_migration/sqflite_migration.dart'; @@ -403,7 +404,7 @@ class FilesDB { return BackedUpFileIDs(localIDs.toList(), uploadedIDs.toList()); } - Future getAllUploadedVisibleFiles( + Future getAllUploadedFiles( int startTime, int endTime, int ownerID, { @@ -551,11 +552,22 @@ class FilesDB { }) async { final db = await instance.database; final order = (asc ?? false ? 'ASC' : 'DESC'); + String whereClause; + List 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( table, - where: - '$columnCollectionID = ? AND $columnCreationTime >= ? AND $columnCreationTime <= ? AND $columnMMdVisibility = ?', - whereArgs: [collectionID, startTime, endTime, visibility], + where: whereClause, + whereArgs: whereArgs, orderBy: '$columnCreationTime ' + order + ', $columnModificationTime ' + order, limit: limit, @@ -1025,9 +1037,9 @@ class FilesDB { } Future> 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 @@ -1039,7 +1051,26 @@ class FilesDB { ) latest_files ON $table.$columnCollectionID = latest_files.$columnCollectionID AND $table.$columnCreationTime = latest_files.max_creation_time; - ''', + '''; + } else { + 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) + GROUP BY $columnCollectionID + ) latest_files + ON $table.$columnCollectionID = latest_files.$columnCollectionID + AND $table.$columnCreationTime = latest_files.max_creation_time; + '''; + } + + final db = await instance.database; + final rows = await db.rawQuery( + query, ); final files = _convertToFiles(rows); // TODO: Do this de-duplication within the SQL Query diff --git a/lib/services/feature_flag_service.dart b/lib/services/feature_flag_service.dart index 346a0ee30..fb71ebc87 100644 --- a/lib/services/feature_flag_service.dart +++ b/lib/services/feature_flag_service.dart @@ -86,14 +86,14 @@ class FeatureFlagService { bool enableSearch() { try { - return _isInternalUserOrDebugBuild() || _getFeatureFlags().enableSearch; + return isInternalUserOrDebugBuild() || _getFeatureFlags().enableSearch; } catch (e) { _logger.severe("failed to getSearchFeatureFlag", e); return FFDefault.enableSearch; } } - bool _isInternalUserOrDebugBuild() { + bool isInternalUserOrDebugBuild() { String email = Configuration.instance.getEmail(); return (email != null && email.endsWith("@ente.io")) || kDebugMode; } diff --git a/lib/ui/home_widget.dart b/lib/ui/home_widget.dart index 173f2a469..14c964801 100644 --- a/lib/ui/home_widget.dart +++ b/lib/ui/home_widget.dart @@ -416,7 +416,7 @@ class _HomeWidgetState extends State { ignoredCollectionIDs: archivedCollectionIds, ); } else { - result = await FilesDB.instance.getAllUploadedVisibleFiles( + result = await FilesDB.instance.getAllUploadedFiles( creationStartTime, creationEndTime, ownerID, diff --git a/lib/ui/viewer/gallery/archive_page.dart b/lib/ui/viewer/gallery/archive_page.dart index c052d88e5..42c7f219c 100644 --- a/lib/ui/viewer/gallery/archive_page.dart +++ b/lib/ui/viewer/gallery/archive_page.dart @@ -27,7 +27,7 @@ class ArchivePage extends StatelessWidget { Widget build(Object context) { final gallery = Gallery( asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) { - return FilesDB.instance.getAllUploadedVisibleFiles( + return FilesDB.instance.getAllUploadedFiles( creationStartTime, creationEndTime, Configuration.instance.getUserID(), diff --git a/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/lib/ui/viewer/gallery/gallery_app_bar_widget.dart index d30da3bf7..b0ce7e060 100644 --- a/lib/ui/viewer/gallery/gallery_app_bar_widget.dart +++ b/lib/ui/viewer/gallery/gallery_app_bar_widget.dart @@ -12,6 +12,7 @@ import 'package:photos/models/gallery_type.dart'; import 'package:photos/models/magic_metadata.dart'; import 'package:photos/models/selected_files.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/sharing/share_collection_widget.dart'; @@ -132,7 +133,8 @@ class _GalleryAppBarWidgetState extends State { child: IconButton( icon: Icon(Icons.adaptive.share), onPressed: () async { - if (await _collectionHasSharedFiles()) { + if (FeatureFlagService.instance.isInternalUserOrDebugBuild() && + await _collectionHasSharedFiles()) { final choice = await showChoiceDialog( context, 'Share hidden items?', From a278df2f23573920f30803cf642d49b0fb76933f Mon Sep 17 00:00:00 2001 From: Ashil Kandapath Date: Mon, 29 Aug 2022 20:14:07 +0530 Subject: [PATCH 6/8] exclude collectionID = -1 rows while querying for c-ids of hidden files --- lib/db/files_db.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/db/files_db.dart b/lib/db/files_db.dart index 56acd344e..6ae4429ef 100644 --- a/lib/db/files_db.dart +++ b/lib/db/files_db.dart @@ -438,7 +438,8 @@ class FilesDB { final db = await instance.database; final results = await db.query( table, - where: '$columnOwnerID = ? AND $columnMMdVisibility = ?', + where: + '$columnOwnerID = ? AND $columnMMdVisibility = ? AND $columnCollectionID != -1', columns: [columnCollectionID], whereArgs: [ownerID, visibility], ); From 5850074120264b504625824044eb1c74c4f877e7 Mon Sep 17 00:00:00 2001 From: Ashil Kandapath Date: Tue, 30 Aug 2022 12:13:51 +0530 Subject: [PATCH 7/8] minor changes --- lib/db/files_db.dart | 4 +++- lib/services/feature_flag_service.dart | 5 ----- lib/ui/viewer/gallery/gallery_app_bar_widget.dart | 4 +--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/db/files_db.dart b/lib/db/files_db.dart index 2cf2a96b3..7cdc8a3fb 100644 --- a/lib/db/files_db.dart +++ b/lib/db/files_db.dart @@ -96,7 +96,8 @@ class FilesDB { // this opens the database (and creates it if it doesn't exist) Future _initDatabase() async { - final Directory documentsDirectory = await getApplicationDocumentsDirectory(); + final Directory documentsDirectory = + await getApplicationDocumentsDirectory(); final String path = join(documentsDirectory.path, _databaseName); _logger.info("DB path " + path); return await openDatabaseWithMigration(path, dbConfig); @@ -442,6 +443,7 @@ class FilesDB { '$columnOwnerID = ? AND $columnMMdVisibility = ? AND $columnCollectionID != -1', columns: [columnCollectionID], whereArgs: [ownerID, visibility], + distinct: true, ); List collectionIDsOfHiddenFiles = []; for (var result in results) { diff --git a/lib/services/feature_flag_service.dart b/lib/services/feature_flag_service.dart index 1722292be..fb71ebc87 100644 --- a/lib/services/feature_flag_service.dart +++ b/lib/services/feature_flag_service.dart @@ -93,13 +93,8 @@ class FeatureFlagService { } } -<<<<<<< HEAD bool isInternalUserOrDebugBuild() { String email = Configuration.instance.getEmail(); -======= - bool _isInternalUserOrDebugBuild() { - final String email = Configuration.instance.getEmail(); ->>>>>>> master return (email != null && email.endsWith("@ente.io")) || kDebugMode; } diff --git a/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/lib/ui/viewer/gallery/gallery_app_bar_widget.dart index 82df39c12..16beffa6e 100644 --- a/lib/ui/viewer/gallery/gallery_app_bar_widget.dart +++ b/lib/ui/viewer/gallery/gallery_app_bar_widget.dart @@ -144,9 +144,7 @@ class _GalleryAppBarWidgetState extends State { secondActionColor: Theme.of(context).colorScheme.defaultTextColor, ); - if (choice != DialogUserChoice.secondChoice) { - return; - } else { + if (choice == DialogUserChoice.secondChoice) { _showShareCollectionDialog(); } } else { From d78075202811085d710401ac809e8ee089d88c6e Mon Sep 17 00:00:00 2001 From: Ashil Kandapath Date: Tue, 30 Aug 2022 13:46:40 +0530 Subject: [PATCH 8/8] minor changes --- lib/db/files_db.dart | 4 ++-- lib/ui/viewer/gallery/gallery_app_bar_widget.dart | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/db/files_db.dart b/lib/db/files_db.dart index 7cdc8a3fb..544f1e2b0 100644 --- a/lib/db/files_db.dart +++ b/lib/db/files_db.dart @@ -445,11 +445,11 @@ class FilesDB { whereArgs: [ownerID, visibility], distinct: true, ); - List collectionIDsOfHiddenFiles = []; + Set collectionIDsOfHiddenFiles = {}; for (var result in results) { collectionIDsOfHiddenFiles.add(result['collection_id']); } - return collectionIDsOfHiddenFiles.toSet(); + return collectionIDsOfHiddenFiles; } Future getAllLocalAndUploadedFiles( diff --git a/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/lib/ui/viewer/gallery/gallery_app_bar_widget.dart index 16beffa6e..a26bc1bb1 100644 --- a/lib/ui/viewer/gallery/gallery_app_bar_widget.dart +++ b/lib/ui/viewer/gallery/gallery_app_bar_widget.dart @@ -134,7 +134,7 @@ class _GalleryAppBarWidgetState extends State { icon: Icon(Icons.adaptive.share), onPressed: () async { if (FeatureFlagService.instance.isInternalUserOrDebugBuild() && - await _collectionHasSharedFiles()) { + await _collectionHasHiddenFiles(widget.collection.id)) { final choice = await showChoiceDialog( context, 'Share hidden items?', @@ -246,11 +246,11 @@ class _GalleryAppBarWidgetState extends State { } } - Future _collectionHasSharedFiles() async { + Future _collectionHasHiddenFiles(int collectionID) async { final collectionIDsWithHiddenFiles = await FilesDB.instance.getCollectionIDsOfHiddenFiles( Configuration.instance.getUserID(), ); - return collectionIDsWithHiddenFiles.contains(widget.collection.id); + return collectionIDsWithHiddenFiles.contains(collectionID); } }