Rename File -> EnteFile (#1346)
This commit is contained in:
commit
ee107fe776
118 changed files with 567 additions and 578 deletions
9
lib/core/cache/image_cache.dart
vendored
9
lib/core/cache/image_cache.dart
vendored
|
@ -1,15 +1,16 @@
|
|||
import 'dart:io' as io;
|
||||
|
||||
import "dart:io";
|
||||
|
||||
import 'package:photos/core/cache/lru_map.dart';
|
||||
|
||||
class FileLruCache {
|
||||
static final LRUMap<String, io.File> _map = LRUMap(25);
|
||||
static final LRUMap<String, File> _map = LRUMap(25);
|
||||
|
||||
static io.File? get(String key) {
|
||||
static File? get(String key) {
|
||||
return _map.get(key);
|
||||
}
|
||||
|
||||
static void put(String key, io.File value) {
|
||||
static void put(String key, File value) {
|
||||
_map.put(key, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:typed_data';
|
|||
|
||||
import 'package:photos/core/cache/lru_map.dart';
|
||||
import 'package:photos/core/constants.dart';
|
||||
import 'package:photos/models/ente_file.dart';
|
||||
import "package:photos/models/file.dart";
|
||||
|
||||
class ThumbnailInMemoryLruCache {
|
||||
static final LRUMap<String, Uint8List?> _map = LRUMap(1000);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io' as io;
|
||||
import "dart:io";
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:bip39/bip39.dart' as bip39;
|
||||
|
@ -97,7 +97,7 @@ class Configuration {
|
|||
_secureStorage = const FlutterSecureStorage();
|
||||
_documentsDirectory = (await getApplicationDocumentsDirectory()).path;
|
||||
_tempDirectory = _documentsDirectory + "/temp/";
|
||||
final tempDirectory = io.Directory(_tempDirectory);
|
||||
final tempDirectory = Directory(_tempDirectory);
|
||||
try {
|
||||
final currentTime = DateTime.now().microsecondsSinceEpoch;
|
||||
if (tempDirectory.existsSync() &&
|
||||
|
@ -115,11 +115,11 @@ class Configuration {
|
|||
tempDirectory.createSync(recursive: true);
|
||||
final tempDirectoryPath = (await getTemporaryDirectory()).path;
|
||||
_thumbnailCacheDirectory = tempDirectoryPath + "/thumbnail-cache";
|
||||
io.Directory(_thumbnailCacheDirectory).createSync(recursive: true);
|
||||
Directory(_thumbnailCacheDirectory).createSync(recursive: true);
|
||||
_sharedTempMediaDirectory = tempDirectoryPath + "/ente-shared-media";
|
||||
io.Directory(_sharedTempMediaDirectory).createSync(recursive: true);
|
||||
Directory(_sharedTempMediaDirectory).createSync(recursive: true);
|
||||
_sharedDocumentsMediaDirectory = _documentsDirectory + "/ente-shared-media";
|
||||
io.Directory(_sharedDocumentsMediaDirectory).createSync(recursive: true);
|
||||
Directory(_sharedDocumentsMediaDirectory).createSync(recursive: true);
|
||||
if (!_preferences.containsKey(tokenKey)) {
|
||||
await _secureStorage.deleteAll(iOptions: _secureStorageOptionsIOS);
|
||||
} else {
|
||||
|
|
|
@ -375,7 +375,7 @@ extension DeviceFiles on FilesDB {
|
|||
);
|
||||
try {
|
||||
final db = await database;
|
||||
final coverFiles = <File>[];
|
||||
final coverFiles = <EnteFile>[];
|
||||
if (includeCoverThumbnail) {
|
||||
final fileRows = await db.rawQuery(
|
||||
'''SELECT * FROM FILES where local_id in (select cover_id from device_collections) group by local_id;
|
||||
|
@ -403,7 +403,7 @@ extension DeviceFiles on FilesDB {
|
|||
(element) => element.localID == deviceCollection.coverId,
|
||||
);
|
||||
if (deviceCollection.thumbnail == null) {
|
||||
final File? result =
|
||||
final EnteFile? result =
|
||||
await getDeviceCollectionThumbnail(deviceCollection.id);
|
||||
if (result == null) {
|
||||
_logger.finest(
|
||||
|
@ -430,7 +430,7 @@ extension DeviceFiles on FilesDB {
|
|||
}
|
||||
}
|
||||
|
||||
Future<File?> getDeviceCollectionThumbnail(String pathID) async {
|
||||
Future<EnteFile?> getDeviceCollectionThumbnail(String pathID) async {
|
||||
debugPrint("Call fallback method to get potential thumbnail");
|
||||
final db = await database;
|
||||
final fileRows = await db.rawQuery(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'dart:io' as io;
|
||||
import "dart:io";
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
@ -107,7 +107,7 @@ class FilesDB {
|
|||
|
||||
// this opens the database (and creates it if it doesn't exist)
|
||||
Future<Database> _initDatabase() async {
|
||||
final io.Directory documentsDirectory =
|
||||
final Directory documentsDirectory =
|
||||
await getApplicationDocumentsDirectory();
|
||||
final String path = join(documentsDirectory.path, _databaseName);
|
||||
_logger.info("DB path " + path);
|
||||
|
@ -391,23 +391,23 @@ class FilesDB {
|
|||
Future<void> deleteDB() async {
|
||||
if (kDebugMode) {
|
||||
debugPrint("Deleting files db");
|
||||
final io.Directory documentsDirectory =
|
||||
final Directory documentsDirectory =
|
||||
await getApplicationDocumentsDirectory();
|
||||
final String path = join(documentsDirectory.path, _databaseName);
|
||||
io.File(path).deleteSync(recursive: true);
|
||||
File(path).deleteSync(recursive: true);
|
||||
_dbFuture = null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> insertMultiple(
|
||||
List<File> files, {
|
||||
List<EnteFile> files, {
|
||||
ConflictAlgorithm conflictAlgorithm = ConflictAlgorithm.replace,
|
||||
}) async {
|
||||
final startTime = DateTime.now();
|
||||
final db = await database;
|
||||
var batch = db.batch();
|
||||
int batchCounter = 0;
|
||||
for (File file in files) {
|
||||
for (EnteFile file in files) {
|
||||
if (batchCounter == 400) {
|
||||
await batch.commit(noResult: true);
|
||||
batch = db.batch();
|
||||
|
@ -435,7 +435,7 @@ class FilesDB {
|
|||
);
|
||||
}
|
||||
|
||||
Future<int> insert(File file) async {
|
||||
Future<int> insert(EnteFile file) async {
|
||||
final db = await instance.database;
|
||||
return db.insert(
|
||||
filesTable,
|
||||
|
@ -444,7 +444,7 @@ class FilesDB {
|
|||
);
|
||||
}
|
||||
|
||||
Future<File?> getFile(int generatedID) async {
|
||||
Future<EnteFile?> getFile(int generatedID) async {
|
||||
final db = await instance.database;
|
||||
final results = await db.query(
|
||||
filesTable,
|
||||
|
@ -457,7 +457,7 @@ class FilesDB {
|
|||
return convertToFiles(results)[0];
|
||||
}
|
||||
|
||||
Future<File?> getUploadedFile(int uploadedID, int collectionID) async {
|
||||
Future<EnteFile?> getUploadedFile(int uploadedID, int collectionID) async {
|
||||
final db = await instance.database;
|
||||
final results = await db.query(
|
||||
filesTable,
|
||||
|
@ -580,13 +580,13 @@ class FilesDB {
|
|||
limit: limit,
|
||||
);
|
||||
final files = convertToFiles(results);
|
||||
final List<File> filteredFiles = await applyDBFilters(files, filterOptions);
|
||||
final List<EnteFile> filteredFiles = await applyDBFilters(files, filterOptions);
|
||||
return FileLoadResult(filteredFiles, files.length == limit);
|
||||
}
|
||||
|
||||
List<File> deduplicateByLocalID(List<File> files) {
|
||||
List<EnteFile> deduplicateByLocalID(List<EnteFile> files) {
|
||||
final localIDs = <String>{};
|
||||
final List<File> deduplicatedFiles = [];
|
||||
final List<EnteFile> deduplicatedFiles = [];
|
||||
for (final file in files) {
|
||||
final id = file.localID;
|
||||
if (id == null) {
|
||||
|
@ -627,7 +627,7 @@ class FilesDB {
|
|||
return FileLoadResult(files, files.length == limit);
|
||||
}
|
||||
|
||||
Future<List<File>> getAllFilesCollection(int collectionID) async {
|
||||
Future<List<EnteFile>> getAllFilesCollection(int collectionID) async {
|
||||
final db = await instance.database;
|
||||
const String whereClause = '$columnCollectionID = ?';
|
||||
final List<Object> whereArgs = [collectionID];
|
||||
|
@ -640,7 +640,7 @@ class FilesDB {
|
|||
return files;
|
||||
}
|
||||
|
||||
Future<List<File>> getNewFilesInCollection(
|
||||
Future<List<EnteFile>> getNewFilesInCollection(
|
||||
int collectionID,
|
||||
int addedTime,
|
||||
) async {
|
||||
|
@ -666,7 +666,7 @@ class FilesDB {
|
|||
bool? asc,
|
||||
}) async {
|
||||
if (collectionIDs.isEmpty) {
|
||||
return FileLoadResult(<File>[], false);
|
||||
return FileLoadResult(<EnteFile>[], false);
|
||||
}
|
||||
String inParam = "";
|
||||
for (final id in collectionIDs) {
|
||||
|
@ -695,13 +695,13 @@ class FilesDB {
|
|||
return FileLoadResult(files, files.length == limit);
|
||||
}
|
||||
|
||||
Future<List<File>> getFilesCreatedWithinDurations(
|
||||
Future<List<EnteFile>> getFilesCreatedWithinDurations(
|
||||
List<List<int>> durations,
|
||||
Set<int> ignoredCollectionIDs, {
|
||||
String order = 'ASC',
|
||||
}) async {
|
||||
if (durations.isEmpty) {
|
||||
return <File>[];
|
||||
return <EnteFile>[];
|
||||
}
|
||||
final db = await instance.database;
|
||||
String whereClause = "( ";
|
||||
|
@ -730,7 +730,7 @@ class FilesDB {
|
|||
|
||||
// Files which user added to a collection manually but they are not
|
||||
// uploaded yet or files belonging to a collection which is marked for backup
|
||||
Future<List<File>> getFilesPendingForUpload() async {
|
||||
Future<List<EnteFile>> getFilesPendingForUpload() async {
|
||||
final db = await instance.database;
|
||||
final results = await db.query(
|
||||
filesTable,
|
||||
|
@ -753,7 +753,7 @@ class FilesDB {
|
|||
return files;
|
||||
}
|
||||
|
||||
Future<List<File>> getUnUploadedLocalFiles() async {
|
||||
Future<List<EnteFile>> getUnUploadedLocalFiles() async {
|
||||
final db = await instance.database;
|
||||
final results = await db.query(
|
||||
filesTable,
|
||||
|
@ -785,7 +785,7 @@ class FilesDB {
|
|||
return uploadedFileIDs;
|
||||
}
|
||||
|
||||
Future<File?> getUploadedLocalFileInAnyCollection(
|
||||
Future<EnteFile?> getUploadedLocalFileInAnyCollection(
|
||||
int uploadedFileID,
|
||||
int userID,
|
||||
) async {
|
||||
|
@ -911,7 +911,7 @@ class FilesDB {
|
|||
This method should only return localIDs which are not uploaded yet
|
||||
and can be mapped to incoming remote entry
|
||||
*/
|
||||
Future<List<File>> getUnlinkedLocalMatchesForRemoteFile(
|
||||
Future<List<EnteFile>> getUnlinkedLocalMatchesForRemoteFile(
|
||||
int ownerID,
|
||||
String localID,
|
||||
FileType fileType, {
|
||||
|
@ -930,7 +930,7 @@ class FilesDB {
|
|||
getInt(fileType),
|
||||
title,
|
||||
];
|
||||
if (io.Platform.isAndroid) {
|
||||
if (Platform.isAndroid) {
|
||||
whereClause = ''' ($columnOwnerID = ? OR $columnOwnerID IS NULL) AND
|
||||
$columnLocalID = ? AND $columnFileType = ? AND $columnTitle=? AND $columnDeviceFolder= ?
|
||||
''';
|
||||
|
@ -952,7 +952,7 @@ class FilesDB {
|
|||
return convertToFiles(rows);
|
||||
}
|
||||
|
||||
Future<List<File>> getUploadedFilesWithHashes(
|
||||
Future<List<EnteFile>> getUploadedFilesWithHashes(
|
||||
FileHashData hashData,
|
||||
FileType fileType,
|
||||
int ownerID,
|
||||
|
@ -976,7 +976,7 @@ class FilesDB {
|
|||
return convertToFiles(rows);
|
||||
}
|
||||
|
||||
Future<int> update(File file) async {
|
||||
Future<int> update(EnteFile file) async {
|
||||
final db = await instance.database;
|
||||
return await db.update(
|
||||
filesTable,
|
||||
|
@ -986,7 +986,7 @@ class FilesDB {
|
|||
);
|
||||
}
|
||||
|
||||
Future<int> updateUploadedFileAcrossCollections(File file) async {
|
||||
Future<int> updateUploadedFileAcrossCollections(EnteFile file) async {
|
||||
final db = await instance.database;
|
||||
return await db.update(
|
||||
filesTable,
|
||||
|
@ -1043,7 +1043,7 @@ class FilesDB {
|
|||
);
|
||||
}
|
||||
|
||||
Future<int> deleteLocalFile(File file) async {
|
||||
Future<int> deleteLocalFile(EnteFile file) async {
|
||||
final db = await instance.database;
|
||||
if (file.localID != null) {
|
||||
// delete all files with same local ID
|
||||
|
@ -1077,7 +1077,7 @@ class FilesDB {
|
|||
);
|
||||
}
|
||||
|
||||
Future<List<File>> getLocalFiles(List<String> localIDs) async {
|
||||
Future<List<EnteFile>> getLocalFiles(List<String> localIDs) async {
|
||||
String inParam = "";
|
||||
for (final localID in localIDs) {
|
||||
inParam += "'" + localID + "',";
|
||||
|
@ -1173,7 +1173,7 @@ class FilesDB {
|
|||
);
|
||||
}
|
||||
|
||||
Future<List<File>> getPendingUploadForCollection(int collectionID) async {
|
||||
Future<List<EnteFile>> getPendingUploadForCollection(int collectionID) async {
|
||||
final db = await instance.database;
|
||||
final results = await db.query(
|
||||
filesTable,
|
||||
|
@ -1185,7 +1185,7 @@ class FilesDB {
|
|||
}
|
||||
|
||||
Future<Set<String>> getLocalIDsPresentInEntries(
|
||||
List<File> existingFiles,
|
||||
List<EnteFile> existingFiles,
|
||||
int collectionID,
|
||||
) async {
|
||||
String inParam = "";
|
||||
|
@ -1237,7 +1237,7 @@ class FilesDB {
|
|||
|
||||
// getCollectionFileFirstOrLast returns the first or last uploaded file in
|
||||
// the collection based on the given collectionID and the order.
|
||||
Future<File?> getCollectionFileFirstOrLast(
|
||||
Future<EnteFile?> getCollectionFileFirstOrLast(
|
||||
int collectionID,
|
||||
bool sortAsc,
|
||||
) async {
|
||||
|
@ -1292,8 +1292,8 @@ class FilesDB {
|
|||
return rows.isNotEmpty;
|
||||
}
|
||||
|
||||
Future<Map<int, File>> getFilesFromIDs(List<int> ids) async {
|
||||
final result = <int, File>{};
|
||||
Future<Map<int, EnteFile>> getFilesFromIDs(List<int> ids) async {
|
||||
final result = <int, EnteFile>{};
|
||||
if (ids.isEmpty) {
|
||||
return result;
|
||||
}
|
||||
|
@ -1314,8 +1314,8 @@ class FilesDB {
|
|||
return result;
|
||||
}
|
||||
|
||||
Future<Map<int, File>> getFilesFromGeneratedIDs(List<int> ids) async {
|
||||
final result = <int, File>{};
|
||||
Future<Map<int, EnteFile>> getFilesFromGeneratedIDs(List<int> ids) async {
|
||||
final result = <int, EnteFile>{};
|
||||
if (ids.isEmpty) {
|
||||
return result;
|
||||
}
|
||||
|
@ -1336,10 +1336,10 @@ class FilesDB {
|
|||
return result;
|
||||
}
|
||||
|
||||
Future<Map<int, List<File>>> getAllFilesGroupByCollectionID(
|
||||
Future<Map<int, List<EnteFile>>> getAllFilesGroupByCollectionID(
|
||||
List<int> ids,
|
||||
) async {
|
||||
final result = <int, List<File>>{};
|
||||
final result = <int, List<EnteFile>>{};
|
||||
if (ids.isEmpty) {
|
||||
return result;
|
||||
}
|
||||
|
@ -1354,9 +1354,9 @@ class FilesDB {
|
|||
where: '$columnUploadedFileID IN ($inParam)',
|
||||
);
|
||||
final files = convertToFiles(results);
|
||||
for (File eachFile in files) {
|
||||
for (EnteFile eachFile in files) {
|
||||
if (!result.containsKey(eachFile.collectionID)) {
|
||||
result[eachFile.collectionID as int] = <File>[];
|
||||
result[eachFile.collectionID as int] = <EnteFile>[];
|
||||
}
|
||||
result[eachFile.collectionID]!.add(eachFile);
|
||||
}
|
||||
|
@ -1381,8 +1381,8 @@ class FilesDB {
|
|||
return collectionIDsOfFile;
|
||||
}
|
||||
|
||||
List<File> convertToFiles(List<Map<String, dynamic>> results) {
|
||||
final List<File> files = [];
|
||||
List<EnteFile> convertToFiles(List<Map<String, dynamic>> results) {
|
||||
final List<EnteFile> files = [];
|
||||
for (final result in results) {
|
||||
files.add(_getFileFromRow(result));
|
||||
}
|
||||
|
@ -1467,12 +1467,12 @@ class FilesDB {
|
|||
await batch.commit(noResult: true);
|
||||
}
|
||||
|
||||
Future<List<File>> getAllFilesFromDB(Set<int> collectionsToIgnore) async {
|
||||
Future<List<EnteFile>> getAllFilesFromDB(Set<int> collectionsToIgnore) async {
|
||||
final db = await instance.database;
|
||||
final List<Map<String, dynamic>> result =
|
||||
await db.query(filesTable, orderBy: '$columnCreationTime DESC');
|
||||
final List<File> files = convertToFiles(result);
|
||||
final List<File> deduplicatedFiles = await applyDBFilters(
|
||||
final List<EnteFile> files = convertToFiles(result);
|
||||
final List<EnteFile> deduplicatedFiles = await applyDBFilters(
|
||||
files,
|
||||
DBFilterOptions(ignoredCollectionIDs: collectionsToIgnore),
|
||||
);
|
||||
|
@ -1515,11 +1515,11 @@ class FilesDB {
|
|||
limit: limit,
|
||||
);
|
||||
final files = convertToFiles(results);
|
||||
final List<File> filteredFiles = await applyDBFilters(files, filterOptions);
|
||||
final List<EnteFile> filteredFiles = await applyDBFilters(files, filterOptions);
|
||||
return FileLoadResult(filteredFiles, files.length == limit);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _getRowForFile(File file) {
|
||||
Map<String, dynamic> _getRowForFile(EnteFile file) {
|
||||
final row = <String, dynamic>{};
|
||||
if (file.generatedID != null) {
|
||||
row[columnGeneratedID] = file.generatedID;
|
||||
|
@ -1574,7 +1574,7 @@ class FilesDB {
|
|||
return row;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _getRowForFileWithoutCollection(File file) {
|
||||
Map<String, dynamic> _getRowForFileWithoutCollection(EnteFile file) {
|
||||
final row = <String, dynamic>{};
|
||||
row[columnLocalID] = file.localID;
|
||||
row[columnUploadedFileID] = file.uploadedFileID ?? -1;
|
||||
|
@ -1615,8 +1615,8 @@ class FilesDB {
|
|||
return row;
|
||||
}
|
||||
|
||||
File _getFileFromRow(Map<String, dynamic> row) {
|
||||
final file = File();
|
||||
EnteFile _getFileFromRow(Map<String, dynamic> row) {
|
||||
final file = EnteFile();
|
||||
file.generatedID = row[columnGeneratedID];
|
||||
file.localID = row[columnLocalID];
|
||||
file.uploadedFileID =
|
||||
|
|
|
@ -6,7 +6,7 @@ class CollectionUpdatedEvent extends FilesUpdatedEvent {
|
|||
|
||||
CollectionUpdatedEvent(
|
||||
this.collectionID,
|
||||
List<File> updatedFiles,
|
||||
List<EnteFile> updatedFiles,
|
||||
String? source, {
|
||||
EventType? type,
|
||||
}) : super(
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:photos/events/event.dart';
|
|||
import 'package:photos/models/file.dart';
|
||||
|
||||
class FilesUpdatedEvent extends Event {
|
||||
final List<File> updatedFiles;
|
||||
final List<EnteFile> updatedFiles;
|
||||
final EventType type;
|
||||
final String source;
|
||||
|
||||
|
|
1
lib/generated/l10n.dart
generated
1
lib/generated/l10n.dart
generated
|
@ -1,7 +1,6 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'intl/messages_all.dart';
|
||||
|
||||
// **************************************************************************
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:photos/models/file.dart';
|
|||
|
||||
class CollectionWithThumbnail {
|
||||
final Collection collection;
|
||||
final File? thumbnail;
|
||||
final EnteFile? thumbnail;
|
||||
|
||||
CollectionWithThumbnail(
|
||||
this.collection,
|
||||
|
|
|
@ -9,7 +9,7 @@ class DeviceCollection {
|
|||
UploadStrategy uploadStrategy;
|
||||
final String? coverId;
|
||||
int? collectionID;
|
||||
File? thumbnail;
|
||||
EnteFile? thumbnail;
|
||||
|
||||
bool hasCollectionID() {
|
||||
return collectionID != null && collectionID! != -1;
|
||||
|
|
|
@ -42,7 +42,7 @@ class DuplicateItems {
|
|||
}
|
||||
|
||||
class DuplicateFiles {
|
||||
final List<File> files;
|
||||
final List<EnteFile> files;
|
||||
final int size;
|
||||
static final collectionsService = CollectionsService.instance;
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
// EnteFile is base file entry for various type of files
|
||||
// like DeviceFile,RemoteFile or TrashedFile
|
||||
|
||||
abstract class EnteFile {
|
||||
// returns cacheKey which should be used while caching entry related to
|
||||
// this file.
|
||||
String cacheKey();
|
||||
}
|
|
@ -6,7 +6,6 @@ import 'package:path/path.dart';
|
|||
import 'package:photo_manager/photo_manager.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/core/constants.dart';
|
||||
import 'package:photos/models/ente_file.dart';
|
||||
import 'package:photos/models/file_type.dart';
|
||||
import 'package:photos/models/location/location.dart';
|
||||
import "package:photos/models/metadata/file_magic.dart";
|
||||
|
@ -15,7 +14,7 @@ import 'package:photos/utils/date_time_util.dart';
|
|||
import 'package:photos/utils/exif_util.dart';
|
||||
import 'package:photos/utils/file_uploader_util.dart';
|
||||
|
||||
class File extends EnteFile {
|
||||
class EnteFile {
|
||||
int? generatedID;
|
||||
int? uploadedFileID;
|
||||
int? ownerID;
|
||||
|
@ -66,10 +65,10 @@ class File extends EnteFile {
|
|||
|
||||
static final _logger = Logger('File');
|
||||
|
||||
File();
|
||||
EnteFile();
|
||||
|
||||
static Future<File> fromAsset(String pathName, AssetEntity asset) async {
|
||||
final File file = File();
|
||||
static Future<EnteFile> fromAsset(String pathName, AssetEntity asset) async {
|
||||
final EnteFile file = EnteFile();
|
||||
file.localID = asset.id;
|
||||
file.title = asset.title;
|
||||
file.deviceFolder = pathName;
|
||||
|
@ -304,7 +303,7 @@ class File extends EnteFile {
|
|||
bool operator ==(Object o) {
|
||||
if (identical(this, o)) return true;
|
||||
|
||||
return o is File &&
|
||||
return o is EnteFile &&
|
||||
o.generatedID == generatedID &&
|
||||
o.uploadedFileID == uploadedFileID &&
|
||||
o.localID == localID;
|
||||
|
@ -324,7 +323,6 @@ class File extends EnteFile {
|
|||
generatedID.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String cacheKey() {
|
||||
// todo: Neeraj: 19thJuly'22: evaluate and add fileHash as the key?
|
||||
return localID ?? uploadedFileID?.toString() ?? generatedID.toString();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:photos/models/file.dart';
|
||||
|
||||
class FileLoadResult {
|
||||
final List<File> files;
|
||||
final List<EnteFile> files;
|
||||
final bool hasMore;
|
||||
|
||||
FileLoadResult(this.files, this.hasMore);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:photos/models/file.dart';
|
||||
|
||||
class FilesSplit {
|
||||
final List<File> pendingUploads;
|
||||
final List<File> ownedByCurrentUser;
|
||||
final List<File> ownedByOtherUsers;
|
||||
final List<EnteFile> pendingUploads;
|
||||
final List<EnteFile> ownedByCurrentUser;
|
||||
final List<EnteFile> ownedByOtherUsers;
|
||||
|
||||
FilesSplit({
|
||||
required this.pendingUploads,
|
||||
|
@ -14,8 +14,8 @@ class FilesSplit {
|
|||
int get totalFileOwnedCount =>
|
||||
pendingUploads.length + ownedByCurrentUser.length;
|
||||
|
||||
static FilesSplit split(Iterable<File> files, int currentUserID) {
|
||||
final List<File> ownedByCurrentUser = [],
|
||||
static FilesSplit split(Iterable<EnteFile> files, int currentUserID) {
|
||||
final List<EnteFile> ownedByCurrentUser = [],
|
||||
ownedByOtherUsers = [],
|
||||
pendingUploads = [];
|
||||
for (var f in files) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:photos/models/file.dart';
|
||||
|
||||
class GalleryItemsFilter {
|
||||
bool shouldInclude(File file) {
|
||||
bool shouldInclude(EnteFile file) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ class ImportantItemsFilter implements GalleryItemsFilter {
|
|||
final _importantPaths = Configuration.instance.getPathsToBackUp();
|
||||
|
||||
@override
|
||||
bool shouldInclude(File file) {
|
||||
bool shouldInclude(EnteFile file) {
|
||||
if (file.uploadedFileID != null) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:photos/models/file.dart';
|
||||
|
||||
class Memory {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
int _seenTime;
|
||||
|
||||
Memory(this.file, this._seenTime);
|
||||
|
|
|
@ -18,12 +18,12 @@ class AlbumSearchResult extends SearchResult {
|
|||
}
|
||||
|
||||
@override
|
||||
File? previewThumbnail() {
|
||||
EnteFile? previewThumbnail() {
|
||||
return collectionWithThumbnail.thumbnail;
|
||||
}
|
||||
|
||||
@override
|
||||
List<File> resultFiles() {
|
||||
List<EnteFile> resultFiles() {
|
||||
// for album search result, we should open the album page directly
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:photos/models/file.dart';
|
|||
import 'package:photos/models/search/search_result.dart';
|
||||
|
||||
class FileSearchResult extends SearchResult {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
|
||||
FileSearchResult(this.file);
|
||||
|
||||
|
@ -17,12 +17,12 @@ class FileSearchResult extends SearchResult {
|
|||
}
|
||||
|
||||
@override
|
||||
File previewThumbnail() {
|
||||
EnteFile previewThumbnail() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@override
|
||||
List<File> resultFiles() {
|
||||
List<EnteFile> resultFiles() {
|
||||
// for fileSearchResult, the file detailed page view will be opened
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:photos/models/search/search_result.dart';
|
|||
|
||||
class GenericSearchResult extends SearchResult {
|
||||
final String _name;
|
||||
final List<File> _files;
|
||||
final List<EnteFile> _files;
|
||||
final ResultType _type;
|
||||
final Function(BuildContext context)? onResultTap;
|
||||
|
||||
|
@ -21,12 +21,12 @@ class GenericSearchResult extends SearchResult {
|
|||
}
|
||||
|
||||
@override
|
||||
File? previewThumbnail() {
|
||||
EnteFile? previewThumbnail() {
|
||||
return _files.first;
|
||||
}
|
||||
|
||||
@override
|
||||
List<File> resultFiles() {
|
||||
List<EnteFile> resultFiles() {
|
||||
return _files;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@ abstract class SearchResult {
|
|||
|
||||
String name();
|
||||
|
||||
File? previewThumbnail();
|
||||
EnteFile? previewThumbnail();
|
||||
|
||||
String heroTag() {
|
||||
return '${type().toString()}_${name()}';
|
||||
}
|
||||
|
||||
List<File> resultFiles();
|
||||
List<EnteFile> resultFiles();
|
||||
}
|
||||
|
||||
enum ResultType {
|
||||
|
|
|
@ -5,19 +5,19 @@ import 'package:photos/events/clear_selections_event.dart';
|
|||
import 'package:photos/models/file.dart';
|
||||
|
||||
class SelectedFiles extends ChangeNotifier {
|
||||
final files = <File>{};
|
||||
final files = <EnteFile>{};
|
||||
|
||||
///This variable is used to track the files that were involved in last selection
|
||||
///operation (select/unselect). Each [LazyGridView] checks this variable on
|
||||
///change in [SelectedFiles] to see if any of it's files were involved in last
|
||||
///select/unselect operation. If yes, then it will rebuild itself.
|
||||
final lastSelectionOperationFiles = <File>{};
|
||||
final lastSelectionOperationFiles = <EnteFile>{};
|
||||
|
||||
void toggleSelection(File fileToToggle) {
|
||||
void toggleSelection(EnteFile fileToToggle) {
|
||||
// To handle the cases, where the file might have changed due to upload
|
||||
// or any other update, using file.generatedID to track if this file was already
|
||||
// selected or not
|
||||
final File? alreadySelected = files.firstWhereOrNull(
|
||||
final EnteFile? alreadySelected = files.firstWhereOrNull(
|
||||
(element) => _isMatch(fileToToggle, element),
|
||||
);
|
||||
if (alreadySelected != null) {
|
||||
|
@ -30,7 +30,7 @@ class SelectedFiles extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
void toggleGroupSelection(Set<File> filesToToggle) {
|
||||
void toggleGroupSelection(Set<EnteFile> filesToToggle) {
|
||||
if (files.containsAll(filesToToggle)) {
|
||||
unSelectAll(filesToToggle);
|
||||
} else {
|
||||
|
@ -38,14 +38,14 @@ class SelectedFiles extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
void selectAll(Set<File> filesToSelect) {
|
||||
void selectAll(Set<EnteFile> filesToSelect) {
|
||||
files.addAll(filesToSelect);
|
||||
lastSelectionOperationFiles.clear();
|
||||
lastSelectionOperationFiles.addAll(filesToSelect);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void unSelectAll(Set<File> filesToUnselect, {bool skipNotify = false}) {
|
||||
void unSelectAll(Set<EnteFile> filesToUnselect, {bool skipNotify = false}) {
|
||||
files.removeWhere((file) => filesToUnselect.contains(file));
|
||||
lastSelectionOperationFiles.clear();
|
||||
lastSelectionOperationFiles.addAll(filesToUnselect);
|
||||
|
@ -54,21 +54,21 @@ class SelectedFiles extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
bool isFileSelected(File file) {
|
||||
final File? alreadySelected = files.firstWhereOrNull(
|
||||
bool isFileSelected(EnteFile file) {
|
||||
final EnteFile? alreadySelected = files.firstWhereOrNull(
|
||||
(element) => _isMatch(file, element),
|
||||
);
|
||||
return alreadySelected != null;
|
||||
}
|
||||
|
||||
bool isPartOfLastSelected(File file) {
|
||||
final File? matchedFile = lastSelectionOperationFiles.firstWhereOrNull(
|
||||
bool isPartOfLastSelected(EnteFile file) {
|
||||
final EnteFile? matchedFile = lastSelectionOperationFiles.firstWhereOrNull(
|
||||
(element) => _isMatch(file, element),
|
||||
);
|
||||
return matchedFile != null;
|
||||
}
|
||||
|
||||
bool _isMatch(File first, File second) {
|
||||
bool _isMatch(EnteFile first, EnteFile second) {
|
||||
if (first.generatedID != null && second.generatedID != null) {
|
||||
if (first.generatedID == second.generatedID) {
|
||||
return true;
|
||||
|
@ -88,7 +88,7 @@ class SelectedFiles extends ChangeNotifier {
|
|||
|
||||
///Retains only the files that are present in the [filesToRetain] set in
|
||||
///[files]. Takes the intersection of the two sets.
|
||||
void retainFiles(Set<File> filesToRetain) {
|
||||
void retainFiles(Set<EnteFile> filesToRetain) {
|
||||
files.retainAll(filesToRetain);
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:photos/models/file.dart';
|
||||
|
||||
class TrashFile extends File {
|
||||
class TrashFile extends EnteFile {
|
||||
// time when file was put in the trash for first time
|
||||
late int createdAt;
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class CollectionsService {
|
|||
Collection? cachedDefaultHiddenCollection;
|
||||
Future<Map<int, int>>? _collectionIDToNewestFileTime;
|
||||
Collection? cachedUncategorizedCollection;
|
||||
final Map<String, File> _coverCache = <String, File>{};
|
||||
final Map<String, EnteFile> _coverCache = <String, EnteFile>{};
|
||||
final Map<int, int> _countCache = <int, int>{};
|
||||
|
||||
CollectionsService._privateConstructor() {
|
||||
|
@ -141,7 +141,7 @@ class CollectionsService {
|
|||
if (shouldFireDeleteEvent) {
|
||||
Bus.instance.fire(
|
||||
LocalPhotosUpdatedEvent(
|
||||
List<File>.empty(),
|
||||
List<EnteFile>.empty(),
|
||||
source: "syncCollectionDeleted",
|
||||
),
|
||||
);
|
||||
|
@ -158,7 +158,7 @@ class CollectionsService {
|
|||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(
|
||||
null,
|
||||
List<File>.empty(),
|
||||
List<EnteFile>.empty(),
|
||||
"collections_updated",
|
||||
),
|
||||
);
|
||||
|
@ -236,7 +236,7 @@ class CollectionsService {
|
|||
return _collectionIDToNewestFileTime!;
|
||||
}
|
||||
|
||||
Future<File?> getCover(Collection c) async {
|
||||
Future<EnteFile?> getCover(Collection c) async {
|
||||
final int localSyncTime = getCollectionSyncTime(c.id);
|
||||
final String coverKey = '${c.id}_${localSyncTime}_${c.updationTime}';
|
||||
if (_coverCache.containsKey(coverKey)) {
|
||||
|
@ -247,7 +247,7 @@ class CollectionsService {
|
|||
}
|
||||
if (c.hasCover) {
|
||||
final coverID = c.pubMagicMetadata.coverID ?? 0;
|
||||
final File? cover = await filesDB.getUploadedFile(coverID, c.id);
|
||||
final EnteFile? cover = await filesDB.getUploadedFile(coverID, c.id);
|
||||
if (cover != null) {
|
||||
_coverCache[coverKey] = cover;
|
||||
return Future.value(cover);
|
||||
|
@ -264,7 +264,7 @@ class CollectionsService {
|
|||
return null;
|
||||
}
|
||||
|
||||
File? getCoverCache(Collection c) {
|
||||
EnteFile? getCoverCache(Collection c) {
|
||||
final int localSyncTime = getCollectionSyncTime(c.id);
|
||||
final String coverKey = '${c.id}_${localSyncTime}_${c.updationTime}';
|
||||
return _coverCache[coverKey];
|
||||
|
@ -579,7 +579,7 @@ class CollectionsService {
|
|||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(
|
||||
collection.id,
|
||||
<File>[],
|
||||
<EnteFile>[],
|
||||
"delete_collection",
|
||||
type: EventType.deletedFromRemote,
|
||||
),
|
||||
|
@ -874,7 +874,7 @@ class CollectionsService {
|
|||
await _db.insert(List.from([collection]));
|
||||
_collectionIDToCollections[collection.id] = collection;
|
||||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(collection.id, <File>[], "shareUrL"),
|
||||
CollectionUpdatedEvent(collection.id, <EnteFile>[], "shareUrL"),
|
||||
);
|
||||
} on DioError catch (e) {
|
||||
if (e.response?.statusCode == 402) {
|
||||
|
@ -903,7 +903,7 @@ class CollectionsService {
|
|||
await _db.insert(List.from([collection]));
|
||||
_collectionIDToCollections[collection.id] = collection;
|
||||
Bus.instance
|
||||
.fire(CollectionUpdatedEvent(collection.id, <File>[], "updateUrl"));
|
||||
.fire(CollectionUpdatedEvent(collection.id, <EnteFile>[], "updateUrl"));
|
||||
} on DioError catch (e) {
|
||||
if (e.response?.statusCode == 402) {
|
||||
throw SharingNotPermittedForFreeAccountsError();
|
||||
|
@ -926,7 +926,7 @@ class CollectionsService {
|
|||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(
|
||||
collection.id,
|
||||
<File>[],
|
||||
<EnteFile>[],
|
||||
"disableShareUrl",
|
||||
),
|
||||
);
|
||||
|
@ -1100,7 +1100,7 @@ class CollectionsService {
|
|||
return collection;
|
||||
}
|
||||
|
||||
Future<void> addToCollection(int collectionID, List<File> files) async {
|
||||
Future<void> addToCollection(int collectionID, List<EnteFile> files) async {
|
||||
final containsUploadedFile = files.firstWhereOrNull(
|
||||
(element) => element.uploadedFileID != null,
|
||||
) !=
|
||||
|
@ -1157,10 +1157,10 @@ class CollectionsService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<File> linkLocalFileToExistingUploadedFileInAnotherCollection(
|
||||
Future<EnteFile> linkLocalFileToExistingUploadedFileInAnotherCollection(
|
||||
int destCollectionID, {
|
||||
required File localFileToUpload,
|
||||
required File existingUploadedFile,
|
||||
required EnteFile localFileToUpload,
|
||||
required EnteFile existingUploadedFile,
|
||||
}) async {
|
||||
final params = <String, dynamic>{};
|
||||
params["collectionID"] = destCollectionID;
|
||||
|
@ -1199,7 +1199,7 @@ class CollectionsService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> restore(int toCollectionID, List<File> files) async {
|
||||
Future<void> restore(int toCollectionID, List<EnteFile> files) async {
|
||||
final params = <String, dynamic>{};
|
||||
params["collectionID"] = toCollectionID;
|
||||
final toCollectionKey = getCollectionKey(toCollectionID);
|
||||
|
@ -1268,7 +1268,7 @@ class CollectionsService {
|
|||
Future<void> move(
|
||||
int toCollectionID,
|
||||
int fromCollectionID,
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
) async {
|
||||
_validateMoveRequest(toCollectionID, fromCollectionID, files);
|
||||
files.removeWhere((element) => element.uploadedFileID == null);
|
||||
|
@ -1335,7 +1335,7 @@ class CollectionsService {
|
|||
void _validateMoveRequest(
|
||||
int toCollectionID,
|
||||
int fromCollectionID,
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
) {
|
||||
if (toCollectionID == fromCollectionID) {
|
||||
throw AssertionError("Can't move to same album");
|
||||
|
@ -1353,7 +1353,7 @@ class CollectionsService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> removeFromCollection(int collectionID, List<File> files) async {
|
||||
Future<void> removeFromCollection(int collectionID, List<EnteFile> files) async {
|
||||
final params = <String, dynamic>{};
|
||||
params["collectionID"] = collectionID;
|
||||
final batchedFiles = files.chunks(batchSize);
|
||||
|
|
|
@ -33,7 +33,7 @@ class DeduplicationService {
|
|||
final result = <DuplicateFiles>[];
|
||||
final missingFileIDs = <int>[];
|
||||
for (final dupe in dupes.duplicates) {
|
||||
final files = <File>[];
|
||||
final files = <EnteFile>[];
|
||||
for (final id in dupe.fileIDs) {
|
||||
final file = fileMap[id];
|
||||
if (file != null) {
|
||||
|
@ -76,18 +76,18 @@ class DeduplicationService {
|
|||
|
||||
List<DuplicateFiles> clubDuplicates(
|
||||
List<DuplicateFiles> dupesBySize, {
|
||||
required String? Function(File) clubbingKey,
|
||||
required String? Function(EnteFile) clubbingKey,
|
||||
}) {
|
||||
final dupesBySizeAndClubKey = <DuplicateFiles>[];
|
||||
for (final sizeBasedDupe in dupesBySize) {
|
||||
final Map<String, List<File>> clubKeyToFilesMap = {};
|
||||
final Map<String, List<EnteFile>> clubKeyToFilesMap = {};
|
||||
for (final file in sizeBasedDupe.files) {
|
||||
final String? clubKey = clubbingKey(file);
|
||||
if (clubKey == null || clubKey.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
if (!clubKeyToFilesMap.containsKey(clubKey)) {
|
||||
clubKeyToFilesMap[clubKey] = <File>[];
|
||||
clubKeyToFilesMap[clubKey] = <EnteFile>[];
|
||||
}
|
||||
clubKeyToFilesMap[clubKey]!.add(file);
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ class DeduplicationService {
|
|||
}
|
||||
|
||||
Future<List<DuplicateFiles>> _getDuplicateFilesFromLocal() async {
|
||||
final List<File> allFiles = await FilesDB.instance.getAllFilesFromDB(
|
||||
final List<EnteFile> allFiles = await FilesDB.instance.getAllFilesFromDB(
|
||||
CollectionsService.instance.getHiddenCollectionIds(),
|
||||
);
|
||||
final int ownerID = Configuration.instance.getUserID()!;
|
||||
|
@ -114,16 +114,16 @@ class DeduplicationService {
|
|||
(f.ownerID ?? 0) != ownerID ||
|
||||
(f.fileSize ?? 0) <= 0,
|
||||
);
|
||||
final Map<int, List<File>> sizeToFilesMap = {};
|
||||
final Map<int, List<EnteFile>> sizeToFilesMap = {};
|
||||
for (final file in allFiles) {
|
||||
if (!sizeToFilesMap.containsKey(file.fileSize)) {
|
||||
sizeToFilesMap[file.fileSize!] = <File>[];
|
||||
sizeToFilesMap[file.fileSize!] = <EnteFile>[];
|
||||
}
|
||||
sizeToFilesMap[file.fileSize]!.add(file);
|
||||
}
|
||||
final List<DuplicateFiles> dupesBySize = [];
|
||||
for (final size in sizeToFilesMap.keys) {
|
||||
final List<File> files = sizeToFilesMap[size]!;
|
||||
final List<EnteFile> files = sizeToFilesMap[size]!;
|
||||
if (files.length > 1) {
|
||||
dupesBySize.add(DuplicateFiles(files, size));
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ class FavoritesService {
|
|||
_cachedFavoritesCollectionID = null;
|
||||
}
|
||||
|
||||
bool isFavoriteCache(File file, {bool checkOnlyAlbum = false}) {
|
||||
bool isFavoriteCache(EnteFile file, {bool checkOnlyAlbum = false}) {
|
||||
if (file.collectionID != null &&
|
||||
_cachedFavoritesCollectionID != null &&
|
||||
file.collectionID == _cachedFavoritesCollectionID) {
|
||||
|
@ -94,7 +94,7 @@ class FavoritesService {
|
|||
return false;
|
||||
}
|
||||
|
||||
Future<bool> isFavorite(File file) async {
|
||||
Future<bool> isFavorite(EnteFile file) async {
|
||||
final collection = await _getFavoritesCollection();
|
||||
if (collection == null || file.uploadedFileID == null) {
|
||||
return false;
|
||||
|
@ -105,7 +105,7 @@ class FavoritesService {
|
|||
);
|
||||
}
|
||||
|
||||
void _updateFavoriteFilesCache(List<File> files, {required bool favFlag}) {
|
||||
void _updateFavoriteFilesCache(List<EnteFile> files, {required bool favFlag}) {
|
||||
final Set<int> updatedIDs = {};
|
||||
final Set<String> localIDs = {};
|
||||
for (var file in files) {
|
||||
|
@ -126,9 +126,9 @@ class FavoritesService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> addToFavorites(BuildContext context, File file) async {
|
||||
Future<void> addToFavorites(BuildContext context, EnteFile file) async {
|
||||
final collectionID = await _getOrCreateFavoriteCollectionID();
|
||||
final List<File> files = [file];
|
||||
final List<EnteFile> files = [file];
|
||||
if (file.uploadedFileID == null) {
|
||||
file.collectionID = collectionID;
|
||||
await _filesDB.insert(file);
|
||||
|
@ -142,7 +142,7 @@ class FavoritesService {
|
|||
|
||||
Future<void> updateFavorites(
|
||||
BuildContext context,
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
bool favFlag,
|
||||
) async {
|
||||
final int currentUserID = Configuration.instance.getUserID()!;
|
||||
|
@ -166,7 +166,7 @@ class FavoritesService {
|
|||
_updateFavoriteFilesCache(files, favFlag: favFlag);
|
||||
}
|
||||
|
||||
Future<void> removeFromFavorites(BuildContext context, File file) async {
|
||||
Future<void> removeFromFavorites(BuildContext context, EnteFile file) async {
|
||||
final fileID = file.uploadedFileID;
|
||||
if (fileID == null) {
|
||||
// Do nothing, ignore
|
||||
|
|
|
@ -32,7 +32,7 @@ class FileMagicService {
|
|||
static final FileMagicService instance =
|
||||
FileMagicService._privateConstructor();
|
||||
|
||||
Future<void> changeVisibility(List<File> files, int visibility) async {
|
||||
Future<void> changeVisibility(List<EnteFile> files, int visibility) async {
|
||||
final Map<String, dynamic> update = {magicKeyVisibility: visibility};
|
||||
await _updateMagicData(files, update);
|
||||
if (visibility == visibleVisibility) {
|
||||
|
@ -57,7 +57,7 @@ class FileMagicService {
|
|||
}
|
||||
|
||||
Future<void> updatePublicMagicMetadata(
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
Map<String, dynamic>? newMetadataUpdate, {
|
||||
Map<int, Map<String, dynamic>>? metadataUpdateMap,
|
||||
}) async {
|
||||
|
@ -129,7 +129,7 @@ class FileMagicService {
|
|||
}
|
||||
|
||||
Future<void> _updateMagicData(
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
Map<String, dynamic> newMetadataUpdate,
|
||||
) async {
|
||||
final params = <String, dynamic>{};
|
||||
|
|
|
@ -84,16 +84,16 @@ class FilesService {
|
|||
// Note: this method is not used anywhere, but it is kept for future
|
||||
// reference when we add bulk EditTime feature
|
||||
Future<void> bulkEditTime(
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
EditTimeSource source,
|
||||
) async {
|
||||
final ListMatch<File> result = files.splitMatch(
|
||||
final ListMatch<EnteFile> result = files.splitMatch(
|
||||
(element) => element.isUploaded,
|
||||
);
|
||||
final List<File> uploadedFiles = result.matched;
|
||||
final List<EnteFile> uploadedFiles = result.matched;
|
||||
// editTime For LocalFiles
|
||||
final List<File> localOnlyFiles = result.unmatched;
|
||||
for (File localFile in localOnlyFiles) {
|
||||
final List<EnteFile> localOnlyFiles = result.unmatched;
|
||||
for (EnteFile localFile in localOnlyFiles) {
|
||||
final timeResult = _parseTime(localFile, source);
|
||||
if (timeResult != null) {
|
||||
localFile.creationTime = timeResult;
|
||||
|
@ -101,9 +101,9 @@ class FilesService {
|
|||
}
|
||||
await _filesDB.insertMultiple(localOnlyFiles);
|
||||
|
||||
final List<File> remoteFilesToUpdate = [];
|
||||
final List<EnteFile> remoteFilesToUpdate = [];
|
||||
final Map<int, Map<String, int>> fileIDToUpdateMetadata = {};
|
||||
for (File remoteFile in uploadedFiles) {
|
||||
for (EnteFile remoteFile in uploadedFiles) {
|
||||
// discard files not owned by user and also dedupe already processed
|
||||
// files
|
||||
if (remoteFile.ownerID != _config.getUserID()! ||
|
||||
|
@ -127,7 +127,7 @@ class FilesService {
|
|||
}
|
||||
}
|
||||
|
||||
int? _parseTime(File file, EditTimeSource source) {
|
||||
int? _parseTime(EnteFile file, EditTimeSource source) {
|
||||
assert(
|
||||
source == EditTimeSource.fileName,
|
||||
"edit source ${source.name} is not supported yet",
|
||||
|
|
|
@ -9,11 +9,11 @@ class CollectionsIgnoreFilter extends Filter {
|
|||
|
||||
Set<int>? _ignoredUploadIDs;
|
||||
|
||||
CollectionsIgnoreFilter(this.collectionIDs, List<File> files) : super() {
|
||||
CollectionsIgnoreFilter(this.collectionIDs, List<EnteFile> files) : super() {
|
||||
init(files);
|
||||
}
|
||||
|
||||
void init(List<File> files) {
|
||||
void init(List<EnteFile> files) {
|
||||
_ignoredUploadIDs = {};
|
||||
if (collectionIDs.isEmpty) return;
|
||||
for (var file in files) {
|
||||
|
@ -26,7 +26,7 @@ class CollectionsIgnoreFilter extends Filter {
|
|||
}
|
||||
|
||||
@override
|
||||
bool filter(File file) {
|
||||
bool filter(EnteFile file) {
|
||||
if (!file.isUploaded) {
|
||||
// if file is in one of the ignored collections, filter it out. This check
|
||||
// avoids showing un-uploaded files that are going to be uploaded to one of
|
||||
|
|
|
@ -24,8 +24,8 @@ class DBFilterOptions {
|
|||
);
|
||||
}
|
||||
|
||||
Future<List<File>> applyDBFilters(
|
||||
List<File> files,
|
||||
Future<List<EnteFile>> applyDBFilters(
|
||||
List<EnteFile> files,
|
||||
DBFilterOptions? options,
|
||||
) async {
|
||||
if (options == null) {
|
||||
|
@ -48,7 +48,7 @@ Future<List<File>> applyDBFilters(
|
|||
CollectionsIgnoreFilter(options.ignoredCollectionIDs!, files);
|
||||
filters.add(collectionIgnoreFilter);
|
||||
}
|
||||
final List<File> filterFiles = [];
|
||||
final List<EnteFile> filterFiles = [];
|
||||
for (final file in files) {
|
||||
if (filters.every((f) => f.filter(file))) {
|
||||
filterFiles.add(file);
|
||||
|
|
|
@ -7,7 +7,7 @@ class DedupeUploadIDFilter extends Filter {
|
|||
final Set<int> trackedUploadIDs = {};
|
||||
|
||||
@override
|
||||
bool filter(File file) {
|
||||
bool filter(EnteFile file) {
|
||||
if (!file.isUploaded) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import "package:photos/models/file.dart";
|
||||
|
||||
abstract class Filter {
|
||||
bool filter(File file);
|
||||
bool filter(EnteFile file);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class TypeFilter extends Filter {
|
|||
});
|
||||
|
||||
@override
|
||||
bool filter(File file) {
|
||||
bool filter(EnteFile file) {
|
||||
return reverse ? file.fileType != type : file.fileType == type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class UploadIgnoreFilter extends Filter {
|
|||
UploadIgnoreFilter(this.idToReasonMap) : super();
|
||||
|
||||
@override
|
||||
bool filter(File file) {
|
||||
bool filter(EnteFile file) {
|
||||
// Already uploaded files pass the filter
|
||||
if (file.isUploaded) return true;
|
||||
return !IgnoredFilesService.instance.shouldSkipUpload(idToReasonMap, file);
|
||||
|
|
|
@ -106,7 +106,7 @@ extension HiddenService on CollectionsService {
|
|||
|
||||
Future<bool> hideFiles(
|
||||
BuildContext context,
|
||||
List<File> filesToHide, {
|
||||
List<EnteFile> filesToHide, {
|
||||
bool forceHide = false,
|
||||
}) async {
|
||||
final int userID = config.getUserID()!;
|
||||
|
@ -117,7 +117,7 @@ extension HiddenService on CollectionsService {
|
|||
);
|
||||
await dialog.show();
|
||||
try {
|
||||
for (File file in filesToHide) {
|
||||
for (EnteFile file in filesToHide) {
|
||||
if (file.uploadedFileID == null) {
|
||||
throw AssertionError("Can only hide uploaded files");
|
||||
}
|
||||
|
@ -128,9 +128,9 @@ extension HiddenService on CollectionsService {
|
|||
}
|
||||
|
||||
final defaultHiddenCollection = await getDefaultHiddenCollection();
|
||||
final Map<int, List<File>> collectionToFilesMap =
|
||||
final Map<int, List<EnteFile>> collectionToFilesMap =
|
||||
await filesDB.getAllFilesGroupByCollectionID(uploadedIDs);
|
||||
for (MapEntry<int, List<File>> entry in collectionToFilesMap.entries) {
|
||||
for (MapEntry<int, List<EnteFile>> entry in collectionToFilesMap.entries) {
|
||||
if (entry.key == defaultHiddenCollection.id) {
|
||||
_logger.finest('file already part of hidden collection');
|
||||
continue;
|
||||
|
|
|
@ -39,7 +39,7 @@ class IgnoredFilesService {
|
|||
// to avoid making it async in nature.
|
||||
// This syntax is intentional as we want to ensure that ignoredIDs are loaded
|
||||
// from the DB before calling this method.
|
||||
bool shouldSkipUpload(Map<String, String> idToReasonMap, File file) {
|
||||
bool shouldSkipUpload(Map<String, String> idToReasonMap, EnteFile file) {
|
||||
final id = _getIgnoreID(file.localID, file.deviceFolder, file.title);
|
||||
if (id != null && id.isNotEmpty) {
|
||||
return idToReasonMap.containsKey(id);
|
||||
|
@ -47,7 +47,7 @@ class IgnoredFilesService {
|
|||
return false;
|
||||
}
|
||||
|
||||
String? getUploadSkipReason(Map<String, String> idToReasonMap, File file) {
|
||||
String? getUploadSkipReason(Map<String, String> idToReasonMap, EnteFile file) {
|
||||
final id = _getIgnoreID(file.localID, file.deviceFolder, file.title);
|
||||
if (id != null && id.isNotEmpty) {
|
||||
return idToReasonMap[id];
|
||||
|
@ -55,14 +55,14 @@ class IgnoredFilesService {
|
|||
return null;
|
||||
}
|
||||
|
||||
Future<bool> shouldSkipUploadAsync(File file) async {
|
||||
Future<bool> shouldSkipUploadAsync(EnteFile file) async {
|
||||
final ignoredID = await idToIgnoreReasonMap;
|
||||
return shouldSkipUpload(ignoredID, file);
|
||||
}
|
||||
|
||||
// removeIgnoredMappings is used to remove the ignore mapping for the given
|
||||
// set of files so that they can be uploaded.
|
||||
Future<void> removeIgnoredMappings(List<File> files) async {
|
||||
Future<void> removeIgnoredMappings(List<EnteFile> files) async {
|
||||
final List<IgnoredFile> ignoredFiles = [];
|
||||
final Set<String> idsToRemoveFromCache = {};
|
||||
final Map<String, String> currentlyIgnoredIDs = await idToIgnoreReasonMap;
|
||||
|
@ -114,7 +114,7 @@ class IgnoredFilesService {
|
|||
);
|
||||
}
|
||||
|
||||
String? getIgnoredIDForFile(File file) {
|
||||
String? getIgnoredIDForFile(EnteFile file) {
|
||||
return _getIgnoreID(
|
||||
file.localID,
|
||||
file.deviceFolder,
|
||||
|
|
|
@ -13,7 +13,7 @@ final _logger = Logger("FileSyncUtil");
|
|||
const ignoreSizeConstraint = SizeConstraint(ignoreSize: true);
|
||||
const assetFetchPageSize = 2000;
|
||||
|
||||
Future<Tuple2<List<LocalPathAsset>, List<File>>> getLocalPathAssetsAndFiles(
|
||||
Future<Tuple2<List<LocalPathAsset>, List<EnteFile>>> getLocalPathAssetsAndFiles(
|
||||
int fromTime,
|
||||
int toTime,
|
||||
) async {
|
||||
|
@ -27,10 +27,10 @@ Future<Tuple2<List<LocalPathAsset>, List<File>>> getLocalPathAssetsAndFiles(
|
|||
// localID if it's already present in another album. This only impacts iOS
|
||||
// devices where a file can belong to multiple
|
||||
final Set<String> alreadySeenLocalIDs = {};
|
||||
final List<File> uniqueFiles = [];
|
||||
final List<EnteFile> uniqueFiles = [];
|
||||
for (AssetPathEntity pathEntity in pathEntities) {
|
||||
final List<AssetEntity> assetsInPath = await _getAllAssetLists(pathEntity);
|
||||
late Tuple2<Set<String>, List<File>> result;
|
||||
late Tuple2<Set<String>, List<EnteFile>> result;
|
||||
if (assetsInPath.isEmpty) {
|
||||
result = const Tuple2({}, []);
|
||||
} else {
|
||||
|
@ -191,11 +191,11 @@ LocalDiffResult _getLocalAssetsDiff(Map<String, dynamic> args) {
|
|||
);
|
||||
}
|
||||
|
||||
Future<List<File>> _convertLocalAssetsToUniqueFiles(
|
||||
Future<List<EnteFile>> _convertLocalAssetsToUniqueFiles(
|
||||
List<LocalPathAsset> assets,
|
||||
) async {
|
||||
final Set<String> alreadySeenLocalIDs = <String>{};
|
||||
final List<File> files = [];
|
||||
final List<EnteFile> files = [];
|
||||
for (LocalPathAsset localPathAsset in assets) {
|
||||
final String localPathName = localPathAsset.pathName;
|
||||
for (final String localID in localPathAsset.localIDs) {
|
||||
|
@ -206,7 +206,7 @@ Future<List<File>> _convertLocalAssetsToUniqueFiles(
|
|||
continue;
|
||||
}
|
||||
files.add(
|
||||
await File.fromAsset(localPathName, assetEntity),
|
||||
await EnteFile.fromAsset(localPathName, assetEntity),
|
||||
);
|
||||
alreadySeenLocalIDs.add(localID);
|
||||
}
|
||||
|
@ -285,14 +285,14 @@ Future<List<AssetEntity>> _getAllAssetLists(AssetPathEntity pathEntity) async {
|
|||
|
||||
// review: do we need to run this inside compute, after making File.FromAsset
|
||||
// sync. If yes, update the method documentation with reason.
|
||||
Future<Tuple2<Set<String>, List<File>>> _getLocalIDsAndFilesFromAssets(
|
||||
Future<Tuple2<Set<String>, List<EnteFile>>> _getLocalIDsAndFilesFromAssets(
|
||||
Map<String, dynamic> args,
|
||||
) async {
|
||||
final pathEntity = args["pathEntity"] as AssetPathEntity;
|
||||
final assetList = args["assetList"];
|
||||
final fromTime = args["fromTime"];
|
||||
final alreadySeenLocalIDs = args["alreadySeenLocalIDs"] as Set<String>;
|
||||
final List<File> files = [];
|
||||
final List<EnteFile> files = [];
|
||||
final Set<String> localIDs = {};
|
||||
for (AssetEntity entity in assetList) {
|
||||
localIDs.add(entity.id);
|
||||
|
@ -304,7 +304,7 @@ Future<Tuple2<Set<String>, List<File>>> _getLocalIDsAndFilesFromAssets(
|
|||
if (!alreadySeenLocalIDs.contains(entity.id) &&
|
||||
assetCreatedOrUpdatedAfterGivenTime) {
|
||||
try {
|
||||
final file = await File.fromAsset(pathEntity.name, entity);
|
||||
final file = await EnteFile.fromAsset(pathEntity.name, entity);
|
||||
files.add(file);
|
||||
} catch (e) {
|
||||
_logger.severe(e);
|
||||
|
@ -331,7 +331,7 @@ class LocalDiffResult {
|
|||
final List<LocalPathAsset>? localPathAssets;
|
||||
|
||||
// set of File object created from localPathAssets
|
||||
List<File>? uniqueLocalFiles;
|
||||
List<EnteFile>? uniqueLocalFiles;
|
||||
|
||||
// newPathToLocalIDs represents new entries which needs to be synced to
|
||||
// the local db
|
||||
|
|
|
@ -7,7 +7,7 @@ import "package:photos/core/configuration.dart";
|
|||
import 'package:photos/core/errors.dart';
|
||||
import 'package:photos/db/file_updation_db.dart';
|
||||
import 'package:photos/db/files_db.dart';
|
||||
import 'package:photos/models/file.dart' as ente;
|
||||
import 'package:photos/models/file.dart';
|
||||
import "package:photos/models/file_type.dart";
|
||||
import 'package:photos/utils/file_uploader_util.dart';
|
||||
import 'package:photos/utils/file_util.dart';
|
||||
|
@ -116,16 +116,16 @@ class LocalFileUpdateService {
|
|||
) async {
|
||||
_logger.info("files to process ${localIDsToProcess.length} for reupload");
|
||||
final int userID = Configuration.instance.getUserID()!;
|
||||
final List<ente.File> result =
|
||||
final List<EnteFile> result =
|
||||
await FilesDB.instance.getLocalFiles(localIDsToProcess);
|
||||
final List<ente.File> localFilesForUser = [];
|
||||
for (ente.File file in result) {
|
||||
final List<EnteFile> localFilesForUser = [];
|
||||
for (EnteFile file in result) {
|
||||
if (file.ownerID == null || file.ownerID == userID) {
|
||||
localFilesForUser.add(file);
|
||||
}
|
||||
}
|
||||
final Set<String> processedIDs = {};
|
||||
for (ente.File file in localFilesForUser) {
|
||||
for (EnteFile file in localFilesForUser) {
|
||||
if (processedIDs.contains(file.localID)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ class LocalFileUpdateService {
|
|||
);
|
||||
}
|
||||
|
||||
Future<MediaUploadData> getUploadData(ente.File file) async {
|
||||
Future<MediaUploadData> getUploadData(EnteFile file) async {
|
||||
final mediaUploadData = await getUploadDataFromEnteFile(file);
|
||||
// delete the file from app's internal cache if it was copied to app
|
||||
// for upload. Shared Media should only be cleared when the upload
|
||||
|
|
|
@ -204,7 +204,7 @@ class LocalSyncService {
|
|||
return hasUnsyncedFiles;
|
||||
}
|
||||
|
||||
Future<void> ignoreUpload(File file, InvalidFileError error) async {
|
||||
Future<void> ignoreUpload(EnteFile file, InvalidFileError error) async {
|
||||
if (file.localID == null ||
|
||||
file.deviceFolder == null ||
|
||||
file.title == null) {
|
||||
|
@ -276,10 +276,10 @@ class LocalSyncService {
|
|||
required int fromTime,
|
||||
required int toTime,
|
||||
}) async {
|
||||
final Tuple2<List<LocalPathAsset>, List<File>> result =
|
||||
final Tuple2<List<LocalPathAsset>, List<EnteFile>> result =
|
||||
await getLocalPathAssetsAndFiles(fromTime, toTime);
|
||||
|
||||
final List<File> files = result.item2;
|
||||
final List<EnteFile> files = result.item2;
|
||||
if (files.isNotEmpty) {
|
||||
// Update the mapping for device path_id to local file id. Also, keep track
|
||||
// of newly discovered device paths
|
||||
|
@ -297,7 +297,7 @@ class LocalSyncService {
|
|||
);
|
||||
await _trackUpdatedFiles(files, existingLocalDs);
|
||||
// keep reference of all Files for firing LocalPhotosUpdatedEvent
|
||||
final List<File> allFiles = [];
|
||||
final List<EnteFile> allFiles = [];
|
||||
allFiles.addAll(files);
|
||||
// remove existing files and insert newly imported files in the table
|
||||
files.removeWhere((file) => existingLocalDs.contains(file.localID));
|
||||
|
@ -314,7 +314,7 @@ class LocalSyncService {
|
|||
}
|
||||
|
||||
Future<void> _trackUpdatedFiles(
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
Set<String> existingLocalFileIDs,
|
||||
) async {
|
||||
final List<String> updatedLocalIDs = files
|
||||
|
|
|
@ -357,7 +357,7 @@ class RemoteSyncService {
|
|||
);
|
||||
final filesWithCollectionID =
|
||||
await _db.getLocalFiles(localIDsToSync.toList());
|
||||
final List<File> newFilesToInsert = [];
|
||||
final List<EnteFile> newFilesToInsert = [];
|
||||
final Set<String> fileFoundForLocalIDs = {};
|
||||
for (var existingFile in filesWithCollectionID) {
|
||||
final String localID = existingFile.localID!;
|
||||
|
@ -401,7 +401,7 @@ class RemoteSyncService {
|
|||
Configuration.instance.setSelectAllFoldersForBackup(false).ignore();
|
||||
}
|
||||
Bus.instance.fire(
|
||||
LocalPhotosUpdatedEvent(<File>[], source: "deviceFolderSync"),
|
||||
LocalPhotosUpdatedEvent(<EnteFile>[], source: "deviceFolderSync"),
|
||||
);
|
||||
Bus.instance.fire(BackupFoldersUpdatedEvent());
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ class RemoteSyncService {
|
|||
*/
|
||||
_logger.info("Removing files for collections $collectionIDs");
|
||||
for (int collectionID in collectionIDs) {
|
||||
final List<File> pendingUploads =
|
||||
final List<EnteFile> pendingUploads =
|
||||
await _db.getPendingUploadForCollection(collectionID);
|
||||
if (pendingUploads.isEmpty) {
|
||||
continue;
|
||||
|
@ -434,9 +434,9 @@ class RemoteSyncService {
|
|||
"RemovingFiles $collectionIDs: filesInOtherCollection "
|
||||
"${localIDsInOtherFileEntries.length}",
|
||||
);
|
||||
final List<File> entriesToUpdate = [];
|
||||
final List<EnteFile> entriesToUpdate = [];
|
||||
final List<int> entriesToDelete = [];
|
||||
for (File pendingUpload in pendingUploads) {
|
||||
for (EnteFile pendingUpload in pendingUploads) {
|
||||
if (localIDsInOtherFileEntries.contains(pendingUpload.localID)) {
|
||||
entriesToDelete.add(pendingUpload.generatedID!);
|
||||
} else {
|
||||
|
@ -486,19 +486,19 @@ class RemoteSyncService {
|
|||
return collection.id;
|
||||
}
|
||||
|
||||
Future<List<File>> _getFilesToBeUploaded() async {
|
||||
final List<File> originalFiles = await _db.getFilesPendingForUpload();
|
||||
Future<List<EnteFile>> _getFilesToBeUploaded() async {
|
||||
final List<EnteFile> originalFiles = await _db.getFilesPendingForUpload();
|
||||
if (originalFiles.isEmpty) {
|
||||
return originalFiles;
|
||||
}
|
||||
final bool shouldRemoveVideos =
|
||||
!_config.shouldBackupVideos() || _shouldThrottleSync();
|
||||
final ignoredIDs = await IgnoredFilesService.instance.idToIgnoreReasonMap;
|
||||
bool shouldSkipUploadFunc(File file) {
|
||||
bool shouldSkipUploadFunc(EnteFile file) {
|
||||
return IgnoredFilesService.instance.shouldSkipUpload(ignoredIDs, file);
|
||||
}
|
||||
|
||||
final List<File> filesToBeUploaded = [];
|
||||
final List<EnteFile> filesToBeUploaded = [];
|
||||
int ignoredForUpload = 0;
|
||||
int skippedVideos = 0;
|
||||
for (var file in originalFiles) {
|
||||
|
@ -521,7 +521,7 @@ class RemoteSyncService {
|
|||
return filesToBeUploaded;
|
||||
}
|
||||
|
||||
Future<bool> _uploadFiles(List<File> filesToBeUploaded) async {
|
||||
Future<bool> _uploadFiles(List<EnteFile> filesToBeUploaded) async {
|
||||
final int ownerID = _config.getUserID()!;
|
||||
final updatedFileIDs = await _db.getUploadedFileIDsToBeUpdated(ownerID);
|
||||
if (updatedFileIDs.isNotEmpty) {
|
||||
|
@ -590,14 +590,14 @@ class RemoteSyncService {
|
|||
return _completedUploads > 0;
|
||||
}
|
||||
|
||||
void _uploadFile(File file, int collectionID, List<Future> futures) {
|
||||
void _uploadFile(EnteFile file, int collectionID, List<Future> futures) {
|
||||
final future = _uploader
|
||||
.upload(file, collectionID)
|
||||
.then((uploadedFile) => _onFileUploaded(uploadedFile));
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
Future<void> _onFileUploaded(File file) async {
|
||||
Future<void> _onFileUploaded(EnteFile file) async {
|
||||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(file.collectionID, [file], "fileUpload"),
|
||||
);
|
||||
|
@ -643,7 +643,7 @@ class RemoteSyncService {
|
|||
[Existing]
|
||||
]
|
||||
*/
|
||||
Future<void> _storeDiff(List<File> diff, int collectionID) async {
|
||||
Future<void> _storeDiff(List<EnteFile> diff, int collectionID) async {
|
||||
int sharedFileNew = 0,
|
||||
sharedFileUpdated = 0,
|
||||
localUploadedFromDevice = 0,
|
||||
|
@ -657,11 +657,11 @@ class RemoteSyncService {
|
|||
// as we update the generatedID for remoteFile to local file's genID
|
||||
final Set<int> alreadyClaimedLocalFilesGenID = {};
|
||||
|
||||
final List<File> toBeInserted = [];
|
||||
for (File remoteFile in diff) {
|
||||
final List<EnteFile> toBeInserted = [];
|
||||
for (EnteFile remoteFile in diff) {
|
||||
// existingFile will be either set to existing collectionID+localID or
|
||||
// to the unclaimed aka not already linked to any uploaded file.
|
||||
File? existingFile;
|
||||
EnteFile? existingFile;
|
||||
if (remoteFile.generatedID != null) {
|
||||
// Case [1] Check and clear local cache when uploadedFile already exist
|
||||
// Note: Existing file can be null here if it's replaced by the time we
|
||||
|
@ -785,14 +785,14 @@ class RemoteSyncService {
|
|||
}
|
||||
}
|
||||
|
||||
bool _shouldClearCache(File remoteFile, File existingFile) {
|
||||
bool _shouldClearCache(EnteFile remoteFile, EnteFile existingFile) {
|
||||
if (remoteFile.hash != null && existingFile.hash != null) {
|
||||
return remoteFile.hash != existingFile.hash;
|
||||
}
|
||||
return remoteFile.updationTime != (existingFile.updationTime ?? 0);
|
||||
}
|
||||
|
||||
bool _shouldReloadHomeGallery(File remoteFile, File existingFile) {
|
||||
bool _shouldReloadHomeGallery(EnteFile remoteFile, EnteFile existingFile) {
|
||||
int remoteCreationTime = remoteFile.creationTime!;
|
||||
if (remoteFile.pubMmdVersion > 0 &&
|
||||
(remoteFile.pubMagicMetadata?.editedTime ?? 0) != 0) {
|
||||
|
@ -841,7 +841,7 @@ class RemoteSyncService {
|
|||
|
||||
// _sortByTimeAndType moves videos to end and sort by creation time (desc).
|
||||
// This is done to upload most recent photo first.
|
||||
void _sortByTimeAndType(List<File> file) {
|
||||
void _sortByTimeAndType(List<EnteFile> file) {
|
||||
file.sort((first, second) {
|
||||
if (first.fileType == second.fileType) {
|
||||
return second.creationTime!.compareTo(first.creationTime!);
|
||||
|
|
|
@ -23,7 +23,7 @@ import "package:photos/utils/navigation_util.dart";
|
|||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class SearchService {
|
||||
Future<List<File>>? _cachedFilesFuture;
|
||||
Future<List<EnteFile>>? _cachedFilesFuture;
|
||||
final _logger = Logger((SearchService).toString());
|
||||
final _collectionService = CollectionsService.instance;
|
||||
static const _maximumResultsLimit = 20;
|
||||
|
@ -43,7 +43,7 @@ class SearchService {
|
|||
return CollectionsService.instance.getHiddenCollectionIds();
|
||||
}
|
||||
|
||||
Future<List<File>> getAllFiles() async {
|
||||
Future<List<EnteFile>> getAllFiles() async {
|
||||
if (_cachedFilesFuture != null) {
|
||||
return _cachedFilesFuture!;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ class SearchService {
|
|||
c.displayName.toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
)) {
|
||||
final File? thumbnail = await _collectionService.getCover(c);
|
||||
final EnteFile? thumbnail = await _collectionService.getCover(c);
|
||||
collectionSearchResults
|
||||
.add(AlbumSearchResult(CollectionWithThumbnail(c, thumbnail)));
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ class SearchService {
|
|||
final List<GenericSearchResult> searchResults = [];
|
||||
for (var yearData in YearsData.instance.yearsData) {
|
||||
if (yearData.year.startsWith(yearFromQuery)) {
|
||||
final List<File> filesInYear = await _getFilesInYear(yearData.duration);
|
||||
final List<EnteFile> filesInYear = await _getFilesInYear(yearData.duration);
|
||||
if (filesInYear.isNotEmpty) {
|
||||
searchResults.add(
|
||||
GenericSearchResult(
|
||||
|
@ -135,7 +135,7 @@ class SearchService {
|
|||
String query,
|
||||
) async {
|
||||
final List<GenericSearchResult> searchResults = [];
|
||||
final List<File> allFiles = await getAllFiles();
|
||||
final List<EnteFile> allFiles = await getAllFiles();
|
||||
for (var fileType in FileType.values) {
|
||||
final String fileTypeString = getHumanReadableString(fileType);
|
||||
if (fileTypeString.toLowerCase().startsWith(query.toLowerCase())) {
|
||||
|
@ -163,10 +163,10 @@ class SearchService {
|
|||
return searchResults;
|
||||
}
|
||||
final RegExp pattern = RegExp(query, caseSensitive: false);
|
||||
final List<File> allFiles = await getAllFiles();
|
||||
final List<File> captionMatch = <File>[];
|
||||
final List<File> displayNameMatch = <File>[];
|
||||
for (File eachFile in allFiles) {
|
||||
final List<EnteFile> allFiles = await getAllFiles();
|
||||
final List<EnteFile> captionMatch = <EnteFile>[];
|
||||
final List<EnteFile> displayNameMatch = <EnteFile>[];
|
||||
for (EnteFile eachFile in allFiles) {
|
||||
if (eachFile.caption != null && pattern.hasMatch(eachFile.caption!)) {
|
||||
captionMatch.add(eachFile);
|
||||
}
|
||||
|
@ -203,20 +203,20 @@ class SearchService {
|
|||
return searchResults;
|
||||
}
|
||||
|
||||
final List<File> allFiles = await getAllFiles();
|
||||
final Map<String, List<File>> resultMap = <String, List<File>>{};
|
||||
final List<EnteFile> allFiles = await getAllFiles();
|
||||
final Map<String, List<EnteFile>> resultMap = <String, List<EnteFile>>{};
|
||||
|
||||
for (File eachFile in allFiles) {
|
||||
for (EnteFile eachFile in allFiles) {
|
||||
final String fileName = eachFile.displayName;
|
||||
if (fileName.contains(query)) {
|
||||
final String exnType = fileName.split(".").last.toUpperCase();
|
||||
if (!resultMap.containsKey(exnType)) {
|
||||
resultMap[exnType] = <File>[];
|
||||
resultMap[exnType] = <EnteFile>[];
|
||||
}
|
||||
resultMap[exnType]!.add(eachFile);
|
||||
}
|
||||
}
|
||||
for (MapEntry<String, List<File>> entry in resultMap.entries) {
|
||||
for (MapEntry<String, List<EnteFile>> entry in resultMap.entries) {
|
||||
searchResults.add(
|
||||
GenericSearchResult(
|
||||
ResultType.fileExtension,
|
||||
|
@ -233,7 +233,7 @@ class SearchService {
|
|||
) async {
|
||||
final locationTagEntities =
|
||||
(await LocationService.instance.getLocationTags());
|
||||
final Map<LocalEntity<LocationTag>, List<File>> result = {};
|
||||
final Map<LocalEntity<LocationTag>, List<EnteFile>> result = {};
|
||||
final bool showNoLocationTag = query.length > 2 &&
|
||||
"No Location Tag".toLowerCase().startsWith(query.toLowerCase());
|
||||
|
||||
|
@ -248,7 +248,7 @@ class SearchService {
|
|||
return searchResults;
|
||||
}
|
||||
final allFiles = await getAllFiles();
|
||||
for (File file in allFiles) {
|
||||
for (EnteFile file in allFiles) {
|
||||
if (file.hasLocation) {
|
||||
for (LocalEntity<LocationTag> tag in result.keys) {
|
||||
if (LocationService.instance.isFileInsideLocationTag(
|
||||
|
@ -290,7 +290,7 @@ class SearchService {
|
|||
);
|
||||
}
|
||||
}
|
||||
for (MapEntry<LocalEntity<LocationTag>, List<File>> entry
|
||||
for (MapEntry<LocalEntity<LocationTag>, List<EnteFile>> entry
|
||||
in result.entries) {
|
||||
if (entry.value.isNotEmpty) {
|
||||
searchResults.add(
|
||||
|
@ -374,7 +374,7 @@ class SearchService {
|
|||
.toList();
|
||||
}
|
||||
|
||||
Future<List<File>> _getFilesInYear(List<int> durationOfYear) async {
|
||||
Future<List<EnteFile>> _getFilesInYear(List<int> durationOfYear) async {
|
||||
return await FilesDB.instance.getFilesCreatedWithinDurations(
|
||||
[durationOfYear],
|
||||
ignoreCollections(),
|
||||
|
|
|
@ -74,7 +74,7 @@ class TrashSyncService {
|
|||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(
|
||||
0,
|
||||
<File>[],
|
||||
<EnteFile>[],
|
||||
"trash_change",
|
||||
),
|
||||
);
|
||||
|
@ -132,7 +132,7 @@ class TrashSyncService {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> deleteFromTrash(List<File> files) async {
|
||||
Future<void> deleteFromTrash(List<EnteFile> files) async {
|
||||
final params = <String, dynamic>{};
|
||||
final uniqueFileIds = files.map((e) => e.uploadedFileID!).toSet().toList();
|
||||
final batchedFileIDs = uniqueFileIds.chunks(batchSize);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'dart:io' as io;
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:bip39/bip39.dart' as bip39;
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
|
@ -43,7 +43,7 @@ class RecoveryKeyPage extends StatefulWidget {
|
|||
|
||||
class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
|
||||
bool _hasTriedToSave = false;
|
||||
final _recoveryKeyFile = io.File(
|
||||
final _recoveryKeyFile = File(
|
||||
Configuration.instance.getTempDirectory() + "ente-recovery-key.txt",
|
||||
);
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ extension CollectionFileActions on CollectionActions {
|
|||
BuildContext context,
|
||||
int collectionID,
|
||||
bool showProgressDialog, {
|
||||
List<File>? selectedFiles,
|
||||
List<EnteFile>? selectedFiles,
|
||||
List<SharedMediaFile>? sharedFiles,
|
||||
List<AssetEntity>? picketAssets,
|
||||
}) async {
|
||||
|
@ -94,8 +94,8 @@ extension CollectionFileActions on CollectionActions {
|
|||
: null;
|
||||
await dialog?.show();
|
||||
try {
|
||||
final List<File> files = [];
|
||||
final List<File> filesPendingUpload = [];
|
||||
final List<EnteFile> files = [];
|
||||
final List<EnteFile> filesPendingUpload = [];
|
||||
final int currentUserID = Configuration.instance.getUserID()!;
|
||||
if (sharedFiles != null) {
|
||||
filesPendingUpload.addAll(
|
||||
|
@ -113,7 +113,7 @@ extension CollectionFileActions on CollectionActions {
|
|||
);
|
||||
} else {
|
||||
for (final file in selectedFiles!) {
|
||||
File? currentFile;
|
||||
EnteFile? currentFile;
|
||||
if (file.uploadedFileID != null) {
|
||||
currentFile = file;
|
||||
} else if (file.generatedID != null) {
|
||||
|
@ -151,7 +151,7 @@ extension CollectionFileActions on CollectionActions {
|
|||
}
|
||||
final Collection uncat =
|
||||
await CollectionsService.instance.getUncategorizedCollection();
|
||||
for (File unuploadedFile in filesPendingUpload) {
|
||||
for (EnteFile unuploadedFile in filesPendingUpload) {
|
||||
final uploadedFile = await FileUploader.instance.forceUpload(
|
||||
unuploadedFile,
|
||||
uncat.id,
|
||||
|
@ -192,7 +192,7 @@ extension CollectionFileActions on CollectionActions {
|
|||
|
||||
Future<bool> updateFavorites(
|
||||
BuildContext context,
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
bool markAsFavorite,
|
||||
) async {
|
||||
final ProgressDialog dialog = createProgressDialog(
|
||||
|
|
|
@ -103,7 +103,7 @@ class CollectionActions {
|
|||
|
||||
Future<Collection?> createSharedCollectionLink(
|
||||
BuildContext context,
|
||||
List<File> files,
|
||||
List<EnteFile> files,
|
||||
) async {
|
||||
final dialog = createProgressDialog(
|
||||
context,
|
||||
|
@ -115,10 +115,10 @@ class CollectionActions {
|
|||
// create album with emptyName, use collectionCreationTime on UI to
|
||||
// show name
|
||||
logger.finest("creating album for sharing files");
|
||||
final File fileWithMinCreationTime = files.reduce(
|
||||
final EnteFile fileWithMinCreationTime = files.reduce(
|
||||
(a, b) => (a.creationTime ?? 0) < (b.creationTime ?? 0) ? a : b,
|
||||
);
|
||||
final File fileWithMaxCreationTime = files.reduce(
|
||||
final EnteFile fileWithMaxCreationTime = files.reduce(
|
||||
(a, b) => (a.creationTime ?? 0) > (b.creationTime ?? 0) ? a : b,
|
||||
);
|
||||
final String dummyName = getNameForDateRange(
|
||||
|
@ -365,7 +365,7 @@ class CollectionActions {
|
|||
}
|
||||
|
||||
Future<void> trashCollectionKeepingPhotos(Collection collection, BuildContext bContext) async {
|
||||
final List<File> files =
|
||||
final List<EnteFile> files =
|
||||
await FilesDB.instance.getAllFilesCollection(collection.id);
|
||||
await moveFilesFromCurrentCollection(bContext, collection, files);
|
||||
// collection should be empty on server now
|
||||
|
@ -409,7 +409,7 @@ class CollectionActions {
|
|||
Future<void> moveFilesFromCurrentCollection(
|
||||
BuildContext context,
|
||||
Collection collection,
|
||||
Iterable<File> files,
|
||||
Iterable<EnteFile> files,
|
||||
) async {
|
||||
final int currentUserID = Configuration.instance.getUserID()!;
|
||||
final isCollectionOwner = collection.owner!.id == currentUserID;
|
||||
|
@ -439,38 +439,38 @@ class CollectionActions {
|
|||
|
||||
// pendingAssignMap keeps a track of files which are yet to be assigned to
|
||||
// to destination collection.
|
||||
final Map<int, File> pendingAssignMap = {};
|
||||
final Map<int, EnteFile> pendingAssignMap = {};
|
||||
// destCollectionToFilesMap contains the destination collection and
|
||||
// files entry which needs to be moved in destination.
|
||||
// After the end of mapping logic, the number of files entries in
|
||||
// pendingAssignMap should be equal to files in destCollectionToFilesMap
|
||||
final Map<int, List<File>> destCollectionToFilesMap = {};
|
||||
final Map<int, List<EnteFile>> destCollectionToFilesMap = {};
|
||||
final List<int> uploadedIDs = [];
|
||||
for (File f in split.ownedByCurrentUser) {
|
||||
for (EnteFile f in split.ownedByCurrentUser) {
|
||||
if (f.uploadedFileID != null) {
|
||||
pendingAssignMap[f.uploadedFileID!] = f;
|
||||
uploadedIDs.add(f.uploadedFileID!);
|
||||
}
|
||||
}
|
||||
|
||||
final Map<int, List<File>> collectionToFilesMap =
|
||||
final Map<int, List<EnteFile>> collectionToFilesMap =
|
||||
await FilesDB.instance.getAllFilesGroupByCollectionID(uploadedIDs);
|
||||
|
||||
// Find and map the files from current collection to to entries in other
|
||||
// collections. This mapping is done to avoid moving all the files to
|
||||
// uncategorized during remove from album.
|
||||
for (MapEntry<int, List<File>> entry in collectionToFilesMap.entries) {
|
||||
for (MapEntry<int, List<EnteFile>> entry in collectionToFilesMap.entries) {
|
||||
if (!_isAutoMoveCandidate(collection.id, entry.key, currentUserID)) {
|
||||
continue;
|
||||
}
|
||||
final targetCollection = collectionsService.getCollectionByID(entry.key)!;
|
||||
// for each file which already exist in the destination collection
|
||||
// add entries in the moveDestCollectionToFiles map
|
||||
for (File file in entry.value) {
|
||||
for (EnteFile file in entry.value) {
|
||||
// Check if the uploaded file is still waiting to be mapped
|
||||
if (pendingAssignMap.containsKey(file.uploadedFileID)) {
|
||||
if (!destCollectionToFilesMap.containsKey(targetCollection.id)) {
|
||||
destCollectionToFilesMap[targetCollection.id] = <File>[];
|
||||
destCollectionToFilesMap[targetCollection.id] = <EnteFile>[];
|
||||
}
|
||||
destCollectionToFilesMap[targetCollection.id]!
|
||||
.add(pendingAssignMap[file.uploadedFileID!]!);
|
||||
|
@ -483,11 +483,11 @@ class CollectionActions {
|
|||
final Collection uncategorizedCollection =
|
||||
await collectionsService.getUncategorizedCollection();
|
||||
final int toCollectionID = uncategorizedCollection.id;
|
||||
for (MapEntry<int, File> entry in pendingAssignMap.entries) {
|
||||
for (MapEntry<int, EnteFile> entry in pendingAssignMap.entries) {
|
||||
final file = entry.value;
|
||||
if (pendingAssignMap.containsKey(file.uploadedFileID)) {
|
||||
if (!destCollectionToFilesMap.containsKey(toCollectionID)) {
|
||||
destCollectionToFilesMap[toCollectionID] = <File>[];
|
||||
destCollectionToFilesMap[toCollectionID] = <EnteFile>[];
|
||||
}
|
||||
destCollectionToFilesMap[toCollectionID]!
|
||||
.add(pendingAssignMap[file.uploadedFileID!]!);
|
||||
|
@ -507,7 +507,7 @@ class CollectionActions {
|
|||
);
|
||||
}
|
||||
|
||||
for (MapEntry<int, List<File>> entry in destCollectionToFilesMap.entries) {
|
||||
for (MapEntry<int, List<EnteFile>> entry in destCollectionToFilesMap.entries) {
|
||||
await collectionsService.move(entry.key, collection.id, entry.value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ import "package:photos/utils/toast_util.dart";
|
|||
|
||||
Future<void> showSingleFileDeleteSheet(
|
||||
BuildContext context,
|
||||
File file, {
|
||||
Function(File)? onFileRemoved,
|
||||
EnteFile file, {
|
||||
Function(EnteFile)? onFileRemoved,
|
||||
}) async {
|
||||
final List<ButtonWidget> buttons = [];
|
||||
final String fileType = file.fileType == FileType.video
|
||||
|
@ -129,7 +129,7 @@ Future<void> showSingleFileDeleteSheet(
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> showDetailsSheet(BuildContext context, File file) async {
|
||||
Future<void> showDetailsSheet(BuildContext context, EnteFile file) async {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
return showBarModalBottomSheet(
|
||||
topControl: const SizedBox.shrink(),
|
||||
|
|
|
@ -37,7 +37,7 @@ class AlbumColumnItemWidget extends StatelessWidget {
|
|||
child: SizedBox(
|
||||
height: sideOfThumbnail,
|
||||
width: sideOfThumbnail,
|
||||
child: FutureBuilder<File?>(
|
||||
child: FutureBuilder<EnteFile?>(
|
||||
future: CollectionsService.instance.getCover(collection),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
|
|
|
@ -57,10 +57,10 @@ class AlbumRowItemWidget extends StatelessWidget {
|
|||
width: sideOfThumbnail,
|
||||
child: Stack(
|
||||
children: [
|
||||
FutureBuilder<File?>(
|
||||
FutureBuilder<EnteFile?>(
|
||||
future: CollectionsService.instance.getCover(c),
|
||||
builder: (context, snapshot) {
|
||||
File? thumbnail;
|
||||
EnteFile? thumbnail;
|
||||
if (snapshot.hasData) {
|
||||
thumbnail = snapshot.data!;
|
||||
} else {
|
||||
|
|
|
@ -340,8 +340,8 @@ class AlbumVerticalListWidget extends StatelessWidget {
|
|||
: null;
|
||||
await dialog?.show();
|
||||
try {
|
||||
final List<File> files = [];
|
||||
final List<File> filesPendingUpload = [];
|
||||
final List<EnteFile> files = [];
|
||||
final List<EnteFile> filesPendingUpload = [];
|
||||
final int currentUserID = Configuration.instance.getUserID()!;
|
||||
if (sharedFiles != null) {
|
||||
filesPendingUpload.addAll(
|
||||
|
@ -352,7 +352,7 @@ class AlbumVerticalListWidget extends StatelessWidget {
|
|||
);
|
||||
} else {
|
||||
for (final file in selectedFiles!.files) {
|
||||
File? currentFile;
|
||||
EnteFile? currentFile;
|
||||
if (file.uploadedFileID != null) {
|
||||
currentFile = file;
|
||||
} else if (file.generatedID != null) {
|
||||
|
|
|
@ -207,7 +207,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
|
|||
}
|
||||
|
||||
Widget _buildBottomIcons() {
|
||||
final File currentFile = widget.memories[_index].file;
|
||||
final EnteFile currentFile = widget.memories[_index].file;
|
||||
final List<Widget> rowChildren = [
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import "package:photos/models/file.dart";
|
||||
|
||||
class ImageMarker {
|
||||
final File imageFile;
|
||||
final EnteFile imageFile;
|
||||
final double latitude;
|
||||
final double longitude;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import "package:photos/ui/viewer/actions/file_selection_overlay_bar.dart";
|
|||
import "package:photos/ui/viewer/gallery/gallery.dart";
|
||||
|
||||
class MapPullUpGallery extends StatefulWidget {
|
||||
final StreamController<List<File>> visibleImages;
|
||||
final StreamController<List<EnteFile>> visibleImages;
|
||||
final double bottomUnsafeArea;
|
||||
final double bottomSheetDraggableAreaHeight;
|
||||
static const gridCrossAxisSpacing = 4.0;
|
||||
|
@ -104,11 +104,11 @@ class _MapPullUpGalleryState extends State<MapPullUpGallery> {
|
|||
duration: const Duration(milliseconds: 200),
|
||||
switchInCurve: Curves.easeInOutExpo,
|
||||
switchOutCurve: Curves.easeInOutExpo,
|
||||
child: StreamBuilder<List<File>>(
|
||||
child: StreamBuilder<List<EnteFile>>(
|
||||
stream: widget.visibleImages.stream,
|
||||
builder: (
|
||||
BuildContext context,
|
||||
AsyncSnapshot<List<File>> snapshot,
|
||||
AsyncSnapshot<List<EnteFile>> snapshot,
|
||||
) {
|
||||
if (!snapshot.hasData) {
|
||||
return SizedBox(
|
||||
|
|
|
@ -20,7 +20,7 @@ import "package:photos/utils/toast_util.dart";
|
|||
class MapScreen extends StatefulWidget {
|
||||
// Add a function parameter where the function returns a Future<List<File>>
|
||||
|
||||
final Future<List<File>> Function() filesFutureFn;
|
||||
final Future<List<EnteFile>> Function() filesFutureFn;
|
||||
|
||||
const MapScreen({
|
||||
super.key,
|
||||
|
@ -35,9 +35,9 @@ class MapScreen extends StatefulWidget {
|
|||
|
||||
class _MapScreenState extends State<MapScreen> {
|
||||
List<ImageMarker> imageMarkers = [];
|
||||
List<File> allImages = [];
|
||||
StreamController<List<File>> visibleImages =
|
||||
StreamController<List<File>>.broadcast();
|
||||
List<EnteFile> allImages = [];
|
||||
StreamController<List<EnteFile>> visibleImages =
|
||||
StreamController<List<EnteFile>>.broadcast();
|
||||
MapController mapController = MapController();
|
||||
bool isLoading = true;
|
||||
double initialZoom = 4.5;
|
||||
|
@ -49,7 +49,7 @@ class _MapScreenState extends State<MapScreen> {
|
|||
StreamSubscription? _mapMoveSubscription;
|
||||
Isolate? isolate;
|
||||
static const bottomSheetDraggableAreaHeight = 32.0;
|
||||
List<File>? prevMessage;
|
||||
List<EnteFile>? prevMessage;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -73,10 +73,10 @@ class _MapScreenState extends State<MapScreen> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> processFiles(List<File> files) async {
|
||||
Future<void> processFiles(List<EnteFile> files) async {
|
||||
final List<ImageMarker> tempMarkers = [];
|
||||
bool hasAnyLocation = false;
|
||||
File? mostRecentFile;
|
||||
EnteFile? mostRecentFile;
|
||||
for (var file in files) {
|
||||
if (file.hasLocation && file.location != null) {
|
||||
hasAnyLocation = true;
|
||||
|
@ -141,7 +141,7 @@ class _MapScreenState extends State<MapScreen> {
|
|||
);
|
||||
|
||||
_mapMoveSubscription = receivePort.listen((dynamic message) async {
|
||||
if (message is List<File>) {
|
||||
if (message is List<EnteFile>) {
|
||||
if (!message.equals(prevMessage ?? [])) {
|
||||
visibleImages.sink.add(message);
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ class _MapScreenState extends State<MapScreen> {
|
|||
final imageMarkers = message.imageMarkers;
|
||||
final SendPort sendPort = message.sendPort;
|
||||
try {
|
||||
final List<File> visibleFiles = [];
|
||||
final List<EnteFile> visibleFiles = [];
|
||||
for (var imageMarker in imageMarkers) {
|
||||
final point = LatLng(imageMarker.latitude, imageMarker.longitude);
|
||||
if (bounds.contains(point)) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import "package:photos/theme/ente_theme.dart";
|
|||
import "package:photos/ui/viewer/file/thumbnail_widget.dart";
|
||||
|
||||
class MarkerImage extends StatelessWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final double seperator;
|
||||
|
||||
const MarkerImage({super.key, required this.file, required this.seperator});
|
||||
|
|
|
@ -407,7 +407,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
|
|||
});
|
||||
}
|
||||
|
||||
Widget _getThumbnail(File file, bool isSelected) {
|
||||
Widget _getThumbnail(EnteFile file, bool isSelected) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: SizedBox(
|
||||
|
|
|
@ -31,7 +31,7 @@ class QuickLinkAlbumItem extends StatelessWidget {
|
|||
child: SizedBox(
|
||||
height: 60,
|
||||
width: 60,
|
||||
child: FutureBuilder<File?>(
|
||||
child: FutureBuilder<EnteFile?>(
|
||||
future: CollectionsService.instance.getCover(c),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
|
|
|
@ -12,7 +12,7 @@ class CollageCreatorPage extends StatelessWidget {
|
|||
static const int collageItemsMin = 2;
|
||||
static const int collageItemsMax = 6;
|
||||
|
||||
final List<File> files;
|
||||
final List<EnteFile> files;
|
||||
|
||||
const CollageCreatorPage(this.files, {super.key});
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class CollageItemWidget extends StatelessWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -53,7 +53,7 @@ class SaveCollageButton extends StatelessWidget {
|
|||
showShortToast(context, S.of(context).fileFailedToSaveToGallery);
|
||||
return;
|
||||
}
|
||||
final newFile = await File.fromAsset("ente Collages", newAsset);
|
||||
final newFile = await EnteFile.fromAsset("ente Collages", newAsset);
|
||||
SyncService.instance.sync();
|
||||
showShortToast(context, S.of(context).collageSaved);
|
||||
replacePage(
|
||||
|
|
|
@ -22,7 +22,7 @@ class CollageWithFiveItems extends StatefulWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
final File first, second, third, fourth, fifth;
|
||||
final EnteFile first, second, third, fourth, fifth;
|
||||
|
||||
@override
|
||||
State<CollageWithFiveItems> createState() => _CollageWithFiveItemsState();
|
||||
|
|
|
@ -21,7 +21,7 @@ class CollageWithFourItems extends StatefulWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
final File first, second, third, fourth;
|
||||
final EnteFile first, second, third, fourth;
|
||||
|
||||
@override
|
||||
State<CollageWithFourItems> createState() => _CollageWithFourItemsState();
|
||||
|
|
|
@ -23,7 +23,7 @@ class CollageWithSixItems extends StatefulWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
final File first, second, third, fourth, fifth, sixth;
|
||||
final EnteFile first, second, third, fourth, fifth, sixth;
|
||||
|
||||
@override
|
||||
State<CollageWithSixItems> createState() => _CollageWithSixItemsState();
|
||||
|
|
|
@ -21,7 +21,7 @@ class CollageWithThreeItems extends StatefulWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
final File first, second, third;
|
||||
final EnteFile first, second, third;
|
||||
|
||||
@override
|
||||
State<CollageWithThreeItems> createState() => _CollageWithThreeItemsState();
|
||||
|
|
|
@ -19,7 +19,7 @@ class CollageWithTwoItems extends StatefulWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
final File first, second;
|
||||
final EnteFile first, second;
|
||||
|
||||
@override
|
||||
State<CollageWithTwoItems> createState() => _CollageWithTwoItemsState();
|
||||
|
|
|
@ -45,7 +45,7 @@ class _DeduplicatePageState extends State<DeduplicatePage> {
|
|||
),
|
||||
);
|
||||
|
||||
final Set<File> _selectedFiles = <File>{};
|
||||
final Set<EnteFile> _selectedFiles = <EnteFile>{};
|
||||
final Map<int?, int> _fileSizeMap = {};
|
||||
late List<DuplicateFiles> _duplicates;
|
||||
bool _shouldClubByCaptureTime = false;
|
||||
|
@ -58,7 +58,7 @@ class _DeduplicatePageState extends State<DeduplicatePage> {
|
|||
void initState() {
|
||||
_duplicates = DeduplicationService.instance.clubDuplicates(
|
||||
widget.duplicates,
|
||||
clubbingKey: (File f) => f.hash,
|
||||
clubbingKey: (EnteFile f) => f.hash,
|
||||
);
|
||||
_selectAllFilesButFirst();
|
||||
|
||||
|
@ -268,13 +268,13 @@ class _DeduplicatePageState extends State<DeduplicatePage> {
|
|||
|
||||
void _resetEntriesAndSelection() {
|
||||
_duplicates = widget.duplicates;
|
||||
late String? Function(File) clubbingKeyFn;
|
||||
late String? Function(EnteFile) clubbingKeyFn;
|
||||
if (_shouldClubByCaptureTime) {
|
||||
clubbingKeyFn = (File f) => f.creationTime?.toString() ?? '';
|
||||
clubbingKeyFn = (EnteFile f) => f.creationTime?.toString() ?? '';
|
||||
} else if (_shouldClubByFileName) {
|
||||
clubbingKeyFn = (File f) => f.displayName;
|
||||
clubbingKeyFn = (EnteFile f) => f.displayName;
|
||||
} else {
|
||||
clubbingKeyFn = (File f) => f.hash;
|
||||
clubbingKeyFn = (EnteFile f) => f.hash;
|
||||
}
|
||||
_duplicates = DeduplicationService.instance.clubDuplicates(
|
||||
_duplicates,
|
||||
|
@ -442,7 +442,7 @@ class _DeduplicatePageState extends State<DeduplicatePage> {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildFile(BuildContext context, File file, int index) {
|
||||
Widget _buildFile(BuildContext context, EnteFile file, int index) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (_selectedFiles.contains(file)) {
|
||||
|
|
|
@ -31,7 +31,7 @@ import 'package:syncfusion_flutter_sliders/sliders.dart';
|
|||
class ImageEditorPage extends StatefulWidget {
|
||||
final ImageProvider imageProvider;
|
||||
final DetailPageConfiguration detailPageConfig;
|
||||
final ente.File originalFile;
|
||||
final ente.EnteFile originalFile;
|
||||
|
||||
const ImageEditorPage(
|
||||
this.imageProvider,
|
||||
|
@ -351,7 +351,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
|
|||
PhotoManager.stopChangeNotify();
|
||||
final AssetEntity? newAsset =
|
||||
await (PhotoManager.editor.saveImage(result, title: fileName));
|
||||
final newFile = await ente.File.fromAsset(
|
||||
final newFile = await ente.EnteFile.fromAsset(
|
||||
widget.originalFile.deviceFolder ?? '',
|
||||
newAsset!,
|
||||
);
|
||||
|
|
|
@ -90,7 +90,7 @@ class _DeleteEmptyAlbumsState extends State<DeleteEmptyAlbums> {
|
|||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(
|
||||
0,
|
||||
<File>[],
|
||||
<EnteFile>[],
|
||||
"empty_albums_deleted",
|
||||
),
|
||||
);
|
||||
|
|
|
@ -63,7 +63,7 @@ class _FileSelectionActionsWidgetState
|
|||
@override
|
||||
void initState() {
|
||||
currentUserID = Configuration.instance.getUserID()!;
|
||||
split = FilesSplit.split(<File>[], currentUserID);
|
||||
split = FilesSplit.split(<EnteFile>[], currentUserID);
|
||||
widget.selectedFiles.addListener(_selectFileChangeListener);
|
||||
collectionActions = CollectionActions(CollectionsService.instance);
|
||||
isCollectionOwner =
|
||||
|
|
|
@ -8,8 +8,8 @@ import 'package:photos/core/errors.dart';
|
|||
import "package:photos/generated/l10n.dart";
|
||||
import 'package:photos/models/file.dart';
|
||||
import 'package:photos/ui/tools/editor/image_editor_page.dart';
|
||||
import 'package:photos/ui/viewer/file/fading_app_bar.dart';
|
||||
import 'package:photos/ui/viewer/file/fading_bottom_bar.dart';
|
||||
import "package:photos/ui/viewer/file/file_app_bar.dart";
|
||||
import "package:photos/ui/viewer/file/file_bottom_bar.dart";
|
||||
import 'package:photos/ui/viewer/file/file_widget.dart';
|
||||
import 'package:photos/ui/viewer/gallery/gallery.dart';
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
|
@ -23,7 +23,7 @@ enum DetailPageMode {
|
|||
}
|
||||
|
||||
class DetailPageConfiguration {
|
||||
final List<File> files;
|
||||
final List<EnteFile> files;
|
||||
final GalleryLoader? asyncLoader;
|
||||
final int selectedIndex;
|
||||
final String tagPrefix;
|
||||
|
@ -40,7 +40,7 @@ class DetailPageConfiguration {
|
|||
});
|
||||
|
||||
DetailPageConfiguration copyWith({
|
||||
List<File>? files,
|
||||
List<EnteFile>? files,
|
||||
GalleryLoader? asyncLoader,
|
||||
int? selectedIndex,
|
||||
String? tagPrefix,
|
||||
|
@ -69,7 +69,7 @@ class _DetailPageState extends State<DetailPage> {
|
|||
static const kLoadLimit = 100;
|
||||
final _logger = Logger("DetailPageState");
|
||||
bool _shouldDisableScroll = false;
|
||||
List<File>? _files;
|
||||
List<EnteFile>? _files;
|
||||
late PageController _pageController;
|
||||
final _selectedIndexNotifier = ValueNotifier(0);
|
||||
bool _hasLoadedTillStart = false;
|
||||
|
@ -116,7 +116,7 @@ class _DetailPageState extends State<DetailPage> {
|
|||
preferredSize: const Size.fromHeight(80),
|
||||
child: ValueListenableBuilder(
|
||||
builder: (BuildContext context, int selectedIndex, _) {
|
||||
return FadingAppBar(
|
||||
return FileAppBar(
|
||||
_files![selectedIndex],
|
||||
_onFileRemoved,
|
||||
Configuration.instance.getUserID(),
|
||||
|
@ -136,7 +136,7 @@ class _DetailPageState extends State<DetailPage> {
|
|||
_buildPageView(context),
|
||||
ValueListenableBuilder(
|
||||
builder: (BuildContext context, int selectedIndex, _) {
|
||||
return FadingBottomBar(
|
||||
return FileBottomBar(
|
||||
_files![_selectedIndexNotifier.value],
|
||||
_onEditFileRequested,
|
||||
widget.config.mode == DetailPageMode.minimalistic,
|
||||
|
@ -253,7 +253,7 @@ class _DetailPageState extends State<DetailPage> {
|
|||
setState(() {
|
||||
// Returned result could be a subtype of File
|
||||
// ignore: unnecessary_cast
|
||||
final files = result.files.reversed.map((e) => e as File).toList();
|
||||
final files = result.files.reversed.map((e) => e as EnteFile).toList();
|
||||
if (!result.hasMore) {
|
||||
_hasLoadedTillStart = true;
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ class _DetailPageState extends State<DetailPage> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _onFileRemoved(File file) async {
|
||||
Future<void> _onFileRemoved(EnteFile file) async {
|
||||
final totalFiles = _files!.length;
|
||||
if (totalFiles == 1) {
|
||||
// Deleted the only file
|
||||
|
@ -324,7 +324,7 @@ class _DetailPageState extends State<DetailPage> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _onEditFileRequested(File file) async {
|
||||
Future<void> _onEditFileRequested(EnteFile file) async {
|
||||
if (file.uploadedFileID != null &&
|
||||
file.ownerID != Configuration.instance.getUserID()) {
|
||||
_logger.severe(
|
||||
|
|
|
@ -8,7 +8,7 @@ import 'package:photos/ui/common/loading_widget.dart';
|
|||
import 'package:photos/utils/exif_util.dart';
|
||||
|
||||
class ExifInfoDialog extends StatelessWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
const ExifInfoDialog(this.file, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:io';
|
||||
import 'dart:io' as io;
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -30,15 +29,15 @@ import 'package:photos/utils/file_util.dart';
|
|||
import "package:photos/utils/magic_util.dart";
|
||||
import 'package:photos/utils/toast_util.dart';
|
||||
|
||||
class FadingAppBar extends StatefulWidget {
|
||||
final File file;
|
||||
final Function(File) onFileRemoved;
|
||||
class FileAppBar extends StatefulWidget {
|
||||
final EnteFile file;
|
||||
final Function(EnteFile) onFileRemoved;
|
||||
final double height;
|
||||
final bool shouldShowActions;
|
||||
final int? userID;
|
||||
final ValueNotifier<bool> enableFullScreenNotifier;
|
||||
|
||||
const FadingAppBar(
|
||||
const FileAppBar(
|
||||
this.file,
|
||||
this.onFileRemoved,
|
||||
this.userID,
|
||||
|
@ -49,10 +48,10 @@ class FadingAppBar extends StatefulWidget {
|
|||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
FadingAppBarState createState() => FadingAppBarState();
|
||||
FileAppBarState createState() => FileAppBarState();
|
||||
}
|
||||
|
||||
class FadingAppBarState extends State<FadingAppBar> {
|
||||
class FileAppBarState extends State<FileAppBar> {
|
||||
final _logger = Logger("FadingAppBar");
|
||||
|
||||
@override
|
||||
|
@ -277,7 +276,7 @@ class FadingAppBarState extends State<FadingAppBar> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> _toggleFileArchiveStatus(File file) async {
|
||||
Future<void> _toggleFileArchiveStatus(EnteFile file) async {
|
||||
final bool isArchived =
|
||||
widget.file.magicMetadata.visibility == archiveVisibility;
|
||||
await changeVisibility(
|
||||
|
@ -290,7 +289,7 @@ class FadingAppBarState extends State<FadingAppBar> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _download(File file) async {
|
||||
Future<void> _download(EnteFile file) async {
|
||||
final dialog = createProgressDialog(context, "Downloading...");
|
||||
await dialog.show();
|
||||
try {
|
||||
|
@ -298,7 +297,7 @@ class FadingAppBarState extends State<FadingAppBar> {
|
|||
final bool downloadLivePhotoOnDroid =
|
||||
type == FileType.livePhoto && Platform.isAndroid;
|
||||
AssetEntity? savedAsset;
|
||||
final io.File? fileToSave = await getFile(file);
|
||||
final File? fileToSave = await getFile(file);
|
||||
//Disabling notifications for assets changing to insert the file into
|
||||
//files db before triggering a sync.
|
||||
PhotoManager.stopChangeNotify();
|
||||
|
@ -309,7 +308,7 @@ class FadingAppBarState extends State<FadingAppBar> {
|
|||
savedAsset = await PhotoManager.editor
|
||||
.saveVideo(fileToSave!, title: file.title!);
|
||||
} else if (type == FileType.livePhoto) {
|
||||
final io.File? liveVideoFile =
|
||||
final File? liveVideoFile =
|
||||
await getFileFromServer(file, liveVideo: true);
|
||||
if (liveVideoFile == null) {
|
||||
throw AssertionError("Live video can not be null");
|
||||
|
@ -350,9 +349,9 @@ class FadingAppBarState extends State<FadingAppBar> {
|
|||
}
|
||||
|
||||
Future<void> _saveLivePhotoOnDroid(
|
||||
io.File image,
|
||||
io.File video,
|
||||
File enteFile,
|
||||
File image,
|
||||
File video,
|
||||
EnteFile enteFile,
|
||||
) async {
|
||||
debugPrint("Downloading LivePhoto on Droid");
|
||||
AssetEntity? savedAsset = await (PhotoManager.editor
|
||||
|
@ -386,11 +385,11 @@ class FadingAppBarState extends State<FadingAppBar> {
|
|||
await IgnoredFilesService.instance.cacheAndInsert([ignoreVideoFile]);
|
||||
}
|
||||
|
||||
Future<void> _setAs(File file) async {
|
||||
Future<void> _setAs(EnteFile file) async {
|
||||
final dialog = createProgressDialog(context, S.of(context).pleaseWait);
|
||||
await dialog.show();
|
||||
try {
|
||||
final io.File? fileToSave = await (getFile(file));
|
||||
final File? fileToSave = await (getFile(file));
|
||||
if (fileToSave == null) {
|
||||
throw Exception("Fail to get file for setAs operation");
|
||||
}
|
|
@ -14,15 +14,15 @@ import 'package:photos/ui/collections/collection_action_sheet.dart';
|
|||
import 'package:photos/utils/delete_file_util.dart';
|
||||
import 'package:photos/utils/share_util.dart';
|
||||
|
||||
class FadingBottomBar extends StatefulWidget {
|
||||
final File file;
|
||||
final Function(File) onEditRequested;
|
||||
final Function(File) onFileRemoved;
|
||||
class FileBottomBar extends StatefulWidget {
|
||||
final EnteFile file;
|
||||
final Function(EnteFile) onEditRequested;
|
||||
final Function(EnteFile) onFileRemoved;
|
||||
final bool showOnlyInfoButton;
|
||||
final int? userID;
|
||||
final ValueNotifier<bool> enableFullScreenNotifier;
|
||||
|
||||
const FadingBottomBar(
|
||||
const FileBottomBar(
|
||||
this.file,
|
||||
this.onEditRequested,
|
||||
this.showOnlyInfoButton, {
|
||||
|
@ -33,10 +33,10 @@ class FadingBottomBar extends StatefulWidget {
|
|||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
FadingBottomBarState createState() => FadingBottomBarState();
|
||||
FileBottomBarState createState() => FileBottomBarState();
|
||||
}
|
||||
|
||||
class FadingBottomBarState extends State<FadingBottomBar> {
|
||||
class FileBottomBarState extends State<FileBottomBar> {
|
||||
final GlobalKey shareButtonKey = GlobalKey();
|
||||
|
||||
@override
|
||||
|
@ -206,7 +206,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> _showSingleFileDeleteSheet(File file) async {
|
||||
Future<void> _showSingleFileDeleteSheet(EnteFile file) async {
|
||||
await showSingleFileDeleteSheet(
|
||||
context,
|
||||
file,
|
||||
|
@ -262,7 +262,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> _displayDetails(File file) async {
|
||||
Future<void> _displayDetails(EnteFile file) async {
|
||||
await showDetailsSheet(context, file);
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ class FileCaptionReadyOnly extends StatelessWidget {
|
|||
}
|
||||
|
||||
class FileCaptionWidget extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
|
||||
const FileCaptionWidget({required this.file, super.key});
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import "package:photos/ui/viewer/file_details/objects_item_widget.dart";
|
|||
import "package:photos/utils/exif_util.dart";
|
||||
|
||||
class FileDetailsWidget extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
|
||||
const FileDetailsWidget(
|
||||
this.file, {
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:photos/ui/viewer/file/video_widget.dart';
|
|||
import 'package:photos/ui/viewer/file/zoomable_live_image.dart';
|
||||
|
||||
class FileWidget extends StatelessWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final String? tagPrefix;
|
||||
final Function(bool)? shouldDisableScroll;
|
||||
final Function(bool)? playbackCallback;
|
||||
|
|
|
@ -20,7 +20,7 @@ import 'package:photos/utils/file_util.dart';
|
|||
import 'package:photos/utils/thumbnail_util.dart';
|
||||
|
||||
class ThumbnailWidget extends StatefulWidget {
|
||||
final File? file;
|
||||
final EnteFile? file;
|
||||
final BoxFit fit;
|
||||
final bool shouldShowSyncStatus;
|
||||
final bool shouldShowArchiveStatus;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io' as io;
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
@ -21,7 +21,7 @@ import 'package:visibility_detector/visibility_detector.dart';
|
|||
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||
|
||||
class VideoWidget extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final bool? autoPlay;
|
||||
final String? tagPrefix;
|
||||
final Function(bool)? playbackCallback;
|
||||
|
@ -53,7 +53,7 @@ class _VideoWidgetState extends State<VideoWidget> {
|
|||
_loadNetworkVideo();
|
||||
_setFileSizeIfNull();
|
||||
} else if (widget.file.isSharedMediaToAppSandbox) {
|
||||
final localFile = io.File(getSharedMediaFilePath(widget.file));
|
||||
final localFile = File(getSharedMediaFilePath(widget.file));
|
||||
if (localFile.existsSync()) {
|
||||
_logger.fine("loading from app cache");
|
||||
_setVideoPlayerController(file: localFile);
|
||||
|
@ -125,7 +125,7 @@ class _VideoWidgetState extends State<VideoWidget> {
|
|||
|
||||
void _setVideoPlayerController({
|
||||
String? url,
|
||||
io.File? file,
|
||||
File? file,
|
||||
}) {
|
||||
if (!mounted) {
|
||||
// Note: Do not initiale video player if widget is not mounted.
|
||||
|
|
|
@ -21,7 +21,7 @@ import 'package:photos/utils/image_util.dart';
|
|||
import 'package:photos/utils/thumbnail_util.dart';
|
||||
|
||||
class ZoomableImage extends StatefulWidget {
|
||||
final File photo;
|
||||
final EnteFile photo;
|
||||
final Function(bool)? shouldDisableScroll;
|
||||
final String? tagPrefix;
|
||||
final Decoration? backgroundDecoration;
|
||||
|
@ -43,7 +43,7 @@ class ZoomableImage extends StatefulWidget {
|
|||
class _ZoomableImageState extends State<ZoomableImage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late Logger _logger;
|
||||
late File _photo;
|
||||
late EnteFile _photo;
|
||||
ImageProvider? _imageProvider;
|
||||
bool _loadedSmallThumbnail = false;
|
||||
bool _loadingLargeThumbnail = false;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'dart:io' as io;
|
||||
import "dart:io";
|
||||
|
||||
import 'package:chewie/chewie.dart';
|
||||
|
@ -19,7 +18,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|||
import 'package:video_player/video_player.dart';
|
||||
|
||||
class ZoomableLiveImage extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final Function(bool)? shouldDisableScroll;
|
||||
final String? tagPrefix;
|
||||
final Decoration? backgroundDecoration;
|
||||
|
@ -39,7 +38,7 @@ class ZoomableLiveImage extends StatefulWidget {
|
|||
class _ZoomableLiveImageState extends State<ZoomableLiveImage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
final Logger _logger = Logger("ZoomableLiveImage");
|
||||
late File _file;
|
||||
late EnteFile _file;
|
||||
bool _showVideo = false;
|
||||
bool _isLoadingVideoPlayer = false;
|
||||
|
||||
|
@ -125,7 +124,7 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
|
|||
return;
|
||||
}
|
||||
_isLoadingVideoPlayer = true;
|
||||
final io.File? videoFile = _file.fileType == FileType.livePhoto
|
||||
final File? videoFile = _file.fileType == FileType.livePhoto
|
||||
? await _getLivePhotoVideo()
|
||||
: await _getMotionPhotoVideo();
|
||||
|
||||
|
@ -137,12 +136,12 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
|
|||
_isLoadingVideoPlayer = false;
|
||||
}
|
||||
|
||||
Future<io.File?> _getLivePhotoVideo() async {
|
||||
Future<File?> _getLivePhotoVideo() async {
|
||||
if (_file.isRemoteFile && !(await isFileCached(_file, liveVideo: true))) {
|
||||
showShortToast(context, S.of(context).downloading);
|
||||
}
|
||||
|
||||
io.File? videoFile = await getFile(widget.file, liveVideo: true)
|
||||
File? videoFile = await getFile(widget.file, liveVideo: true)
|
||||
.timeout(const Duration(seconds: 15))
|
||||
.onError((dynamic e, s) {
|
||||
_logger.info("getFile failed ${_file.tag}", e);
|
||||
|
@ -164,12 +163,12 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
|
|||
return videoFile;
|
||||
}
|
||||
|
||||
Future<io.File?> _getMotionPhotoVideo() async {
|
||||
Future<File?> _getMotionPhotoVideo() async {
|
||||
if (_file.isRemoteFile && !(await isFileCached(_file))) {
|
||||
showShortToast(context, S.of(context).downloading);
|
||||
}
|
||||
|
||||
final io.File? imageFile = await getFile(
|
||||
final File? imageFile = await getFile(
|
||||
widget.file,
|
||||
isOrigin: !Platform.isAndroid,
|
||||
).timeout(const Duration(seconds: 15)).onError((dynamic e, s) {
|
||||
|
@ -196,7 +195,7 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
|
|||
return null;
|
||||
}
|
||||
|
||||
VideoPlayerController _setVideoPlayerController({required io.File file}) {
|
||||
VideoPlayerController _setVideoPlayerController({required File file}) {
|
||||
final videoPlayerController = VideoPlayerController.file(file);
|
||||
return _videoPlayerController = videoPlayerController
|
||||
..initialize().whenComplete(() {
|
||||
|
|
|
@ -5,7 +5,7 @@ import "package:photos/services/collections_service.dart";
|
|||
import "package:photos/theme/ente_theme.dart";
|
||||
|
||||
class AddedByWidget extends StatelessWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final int currentUserID;
|
||||
const AddedByWidget(this.file, this.currentUserID, {super.key});
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import "package:photos/ui/viewer/gallery/collection_page.dart";
|
|||
import "package:photos/utils/navigation_util.dart";
|
||||
|
||||
class AlbumsItemWidget extends StatelessWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final int currentUserID;
|
||||
const AlbumsItemWidget(
|
||||
this.file,
|
||||
|
|
|
@ -6,7 +6,7 @@ import "package:photos/ui/components/info_item_widget.dart";
|
|||
import "package:photos/utils/date_time_util.dart";
|
||||
|
||||
class BackedUpTimeItemWidget extends StatelessWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
const BackedUpTimeItemWidget(this.file, {super.key});
|
||||
|
||||
@override
|
||||
|
|
|
@ -9,7 +9,7 @@ import "package:photos/utils/date_time_util.dart";
|
|||
import "package:photos/utils/magic_util.dart";
|
||||
|
||||
class CreationTimeItem extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final int currentUserID;
|
||||
const CreationTimeItem(this.file, this.currentUserID, {super.key});
|
||||
|
||||
|
@ -45,7 +45,7 @@ class _CreationTimeItemState extends State<CreationTimeItem> {
|
|||
);
|
||||
}
|
||||
|
||||
void _showDateTimePicker(File file) async {
|
||||
void _showDateTimePicker(EnteFile file) async {
|
||||
final dateResult = await DatePickerBdaya.showDatePicker(
|
||||
context,
|
||||
minTime: DateTime(1800, 1, 1),
|
||||
|
|
|
@ -46,7 +46,7 @@ class BasicExifItemWidget extends StatelessWidget {
|
|||
}
|
||||
|
||||
class AllExifItemWidget extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final Map<String, IfdTag>? exif;
|
||||
const AllExifItemWidget(
|
||||
this.file,
|
||||
|
@ -78,7 +78,7 @@ class _AllExifItemWidgetState extends State<AllExifItemWidget> {
|
|||
|
||||
Future<List<Widget>> _exifButton(
|
||||
BuildContext context,
|
||||
File file,
|
||||
EnteFile file,
|
||||
Map<String, IfdTag>? exif,
|
||||
) async {
|
||||
late final String label;
|
||||
|
|
|
@ -9,7 +9,7 @@ import "package:photos/utils/dialog_util.dart";
|
|||
import "package:photos/utils/toast_util.dart";
|
||||
|
||||
class FavoriteWidget extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
|
||||
const FavoriteWidget(
|
||||
this.file, {
|
||||
|
|
|
@ -9,7 +9,7 @@ import "package:photos/utils/file_util.dart";
|
|||
import "package:photos/utils/magic_util.dart";
|
||||
|
||||
class FilePropertiesItemWidget extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final bool isImage;
|
||||
final Map<String, dynamic> exifData;
|
||||
final int currentUserID;
|
||||
|
|
|
@ -9,7 +9,7 @@ import "package:photos/ui/components/info_item_widget.dart";
|
|||
import "package:photos/utils/thumbnail_util.dart";
|
||||
|
||||
class ObjectsItemWidget extends StatelessWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
const ObjectsItemWidget(this.file, {super.key});
|
||||
|
||||
@override
|
||||
|
@ -24,7 +24,7 @@ class ObjectsItemWidget extends StatelessWidget {
|
|||
|
||||
Future<List<ChipButtonWidget>> _objectTags(
|
||||
BuildContext context,
|
||||
File file,
|
||||
EnteFile file,
|
||||
) async {
|
||||
try {
|
||||
final chipButtons = <ChipButtonWidget>[];
|
||||
|
|
|
@ -17,7 +17,7 @@ import "package:photos/ui/common/loading_widget.dart";
|
|||
import "package:photos/utils/toast_util.dart";
|
||||
|
||||
class UploadIconWidget extends StatefulWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
|
||||
const UploadIconWidget({super.key, required this.file});
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class CollectionPage extends StatelessWidget {
|
|||
c.collection,
|
||||
Configuration.instance.getUserID()!,
|
||||
);
|
||||
final List<File>? initialFiles =
|
||||
final List<EnteFile>? initialFiles =
|
||||
c.thumbnail != null ? [c.thumbnail!] : null;
|
||||
final gallery = Gallery(
|
||||
asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) async {
|
||||
|
|
|
@ -15,13 +15,13 @@ import "package:photos/utils/file_util.dart";
|
|||
import "package:photos/utils/navigation_util.dart";
|
||||
|
||||
class GalleryFileWidget extends StatelessWidget {
|
||||
final File file;
|
||||
final EnteFile file;
|
||||
final SelectedFiles? selectedFiles;
|
||||
final bool limitSelectionToOne;
|
||||
final String tag;
|
||||
final int photoGridSize;
|
||||
final int? currentUserID;
|
||||
final List<File> filesInGroup;
|
||||
final List<EnteFile> filesInGroup;
|
||||
final GalleryLoader asyncLoader;
|
||||
const GalleryFileWidget({
|
||||
required this.file,
|
||||
|
@ -103,18 +103,18 @@ class GalleryFileWidget extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
void _toggleFileSelection(File file) {
|
||||
void _toggleFileSelection(EnteFile file) {
|
||||
selectedFiles!.toggleSelection(file);
|
||||
}
|
||||
|
||||
void _onTapWithSelectionLimit(File file) {
|
||||
void _onTapWithSelectionLimit(EnteFile file) {
|
||||
if (selectedFiles!.files.isNotEmpty && selectedFiles!.files.first != file) {
|
||||
selectedFiles!.clearAll();
|
||||
}
|
||||
_toggleFileSelection(file);
|
||||
}
|
||||
|
||||
void _onTapNoSelectionLimit(BuildContext context, File file) async {
|
||||
void _onTapNoSelectionLimit(BuildContext context, EnteFile file) async {
|
||||
final bool shouldToggleSelection =
|
||||
(selectedFiles?.files.isNotEmpty ?? false) ||
|
||||
GalleryContextState.of(context)!.inSelectionMode;
|
||||
|
@ -131,7 +131,7 @@ class GalleryFileWidget extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
void _onLongPressNoSelectionLimit(BuildContext context, File file) {
|
||||
void _onLongPressNoSelectionLimit(BuildContext context, EnteFile file) {
|
||||
if (selectedFiles!.files.isNotEmpty) {
|
||||
_routeToDetailPage(file, context);
|
||||
} else if (AppLifecycleService.instance.mediaExtensionAction.action ==
|
||||
|
@ -143,7 +143,7 @@ class GalleryFileWidget extends StatelessWidget {
|
|||
|
||||
Future<void> _onLongPressWithSelectionLimit(
|
||||
BuildContext context,
|
||||
File file,
|
||||
EnteFile file,
|
||||
) async {
|
||||
if (AppLifecycleService.instance.mediaExtensionAction.action ==
|
||||
IntentAction.pick) {
|
||||
|
@ -154,7 +154,7 @@ class GalleryFileWidget extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
void _routeToDetailPage(File file, BuildContext context) {
|
||||
void _routeToDetailPage(EnteFile file, BuildContext context) {
|
||||
final page = DetailPage(
|
||||
DetailPageConfiguration(
|
||||
List.unmodifiable(filesInGroup),
|
||||
|
|
|
@ -6,7 +6,7 @@ import "package:photos/ui/viewer/gallery/component/gallery_file_widget.dart";
|
|||
import "package:photos/ui/viewer/gallery/gallery.dart";
|
||||
|
||||
class GalleryGridViewWidget extends StatelessWidget {
|
||||
final List<File> filesInGroup;
|
||||
final List<EnteFile> filesInGroup;
|
||||
final int photoGridSize;
|
||||
final SelectedFiles? selectedFiles;
|
||||
final bool limitSelectionToOne;
|
||||
|
|
|
@ -13,7 +13,7 @@ import "package:photos/ui/viewer/gallery/gallery.dart";
|
|||
|
||||
class LazyGridView extends StatefulWidget {
|
||||
final String tag;
|
||||
final List<File> filesInGroup;
|
||||
final List<EnteFile> filesInGroup;
|
||||
final GalleryLoader asyncLoader;
|
||||
final SelectedFiles? selectedFiles;
|
||||
final bool shouldRender;
|
||||
|
|
|
@ -8,7 +8,7 @@ import "package:visibility_detector/visibility_detector.dart";
|
|||
|
||||
class NonRecyclableGridViewWidget extends StatefulWidget {
|
||||
final bool shouldRender;
|
||||
final List<File> filesInGroup;
|
||||
final List<EnteFile> filesInGroup;
|
||||
final int photoGridSize;
|
||||
final bool limitSelectionToOne;
|
||||
final String tag;
|
||||
|
|
|
@ -8,7 +8,7 @@ import "package:visibility_detector/visibility_detector.dart";
|
|||
|
||||
class RecyclableGridViewWidget extends StatefulWidget {
|
||||
final bool shouldRender;
|
||||
final List<File> filesInGroup;
|
||||
final List<EnteFile> filesInGroup;
|
||||
final int photoGridSize;
|
||||
final bool limitSelectionToOne;
|
||||
final String tag;
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'package:photos/ui/viewer/gallery/gallery.dart';
|
|||
|
||||
class GroupGallery extends StatelessWidget {
|
||||
final int photoGridSize;
|
||||
final List<File> files;
|
||||
final List<EnteFile> files;
|
||||
final String tag;
|
||||
final GalleryLoader asyncLoader;
|
||||
final SelectedFiles? selectedFiles;
|
||||
|
|
|
@ -15,7 +15,7 @@ import 'package:photos/ui/viewer/gallery/gallery.dart';
|
|||
import "package:photos/ui/viewer/gallery/state/gallery_context_state.dart";
|
||||
|
||||
class LazyGroupGallery extends StatefulWidget {
|
||||
final List<File> files;
|
||||
final List<EnteFile> files;
|
||||
final int index;
|
||||
final Stream<FilesUpdatedEvent>? reloadEvent;
|
||||
final Set<EventType> removalEventTypes;
|
||||
|
@ -56,8 +56,8 @@ class _LazyGroupGalleryState extends State<LazyGroupGallery> {
|
|||
|
||||
late Logger _logger;
|
||||
|
||||
late List<File> _files;
|
||||
Set<File>? _filesAsSet;
|
||||
late List<EnteFile> _files;
|
||||
Set<EnteFile>? _filesAsSet;
|
||||
late StreamSubscription<FilesUpdatedEvent>? _reloadEventSubscription;
|
||||
late StreamSubscription<int> _currentIndexSubscription;
|
||||
bool? _shouldRender;
|
||||
|
@ -90,7 +90,7 @@ class _LazyGroupGalleryState extends State<LazyGroupGallery> {
|
|||
});
|
||||
}
|
||||
|
||||
Set<File> get _setOfFiles {
|
||||
Set<EnteFile> get _setOfFiles {
|
||||
_filesAsSet ??= _files.toSet();
|
||||
return _filesAsSet!;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ group into multiple grid views during rendering.
|
|||
*/
|
||||
class MultipleGroupsGalleryView extends StatelessWidget {
|
||||
final ItemScrollController itemScroller;
|
||||
final List<List<File>> groupedFiles;
|
||||
final List<List<EnteFile>> groupedFiles;
|
||||
final bool disableScroll;
|
||||
final Widget? header;
|
||||
final Widget? footer;
|
||||
|
@ -65,7 +65,7 @@ class MultipleGroupsGalleryView extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return HugeListView<List<File>>(
|
||||
return HugeListView<List<EnteFile>>(
|
||||
controller: itemScroller,
|
||||
startIndex: 0,
|
||||
totalCount: groupedFiles.length,
|
||||
|
|
|
@ -90,7 +90,7 @@ class BackupHeaderWidget extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _BackupHeaderWidgetState extends State<BackupHeaderWidget> {
|
||||
late Future<List<File>> filesInDeviceCollection;
|
||||
late Future<List<EnteFile>> filesInDeviceCollection;
|
||||
late ValueNotifier<bool> shouldBackup;
|
||||
final Logger _logger = Logger("_BackupHeaderWidgetState");
|
||||
@override
|
||||
|
@ -191,7 +191,7 @@ class _BackupHeaderWidgetState extends State<BackupHeaderWidget> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<List<File>> _filesInDeviceCollection() async {
|
||||
Future<List<EnteFile>> _filesInDeviceCollection() async {
|
||||
return (await FilesDB.instance.getFilesInDeviceCollection(
|
||||
widget.deviceCollection,
|
||||
Configuration.instance.getUserID(),
|
||||
|
@ -202,15 +202,15 @@ class _BackupHeaderWidgetState extends State<BackupHeaderWidget> {
|
|||
}
|
||||
|
||||
Future<bool> _hasIgnoredFiles(
|
||||
Future<List<File>> filesInDeviceCollection,
|
||||
Future<List<EnteFile>> filesInDeviceCollection,
|
||||
) async {
|
||||
final List<File> deviceCollectionFiles = await filesInDeviceCollection;
|
||||
final List<EnteFile> deviceCollectionFiles = await filesInDeviceCollection;
|
||||
final allIgnoredIDs =
|
||||
await IgnoredFilesService.instance.idToIgnoreReasonMap;
|
||||
if (allIgnoredIDs.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
for (File file in deviceCollectionFiles) {
|
||||
for (EnteFile file in deviceCollectionFiles) {
|
||||
final String? ignoreID =
|
||||
IgnoredFilesService.instance.getIgnoredIDForFile(file);
|
||||
if (ignoreID != null && allIgnoredIDs.containsKey(ignoreID!)) {
|
||||
|
@ -222,7 +222,7 @@ class _BackupHeaderWidgetState extends State<BackupHeaderWidget> {
|
|||
}
|
||||
|
||||
class ResetIgnoredFilesWidget extends StatefulWidget {
|
||||
final Future<List<File>> filesInDeviceCollection;
|
||||
final Future<List<EnteFile>> filesInDeviceCollection;
|
||||
final VoidCallback parentSetState;
|
||||
const ResetIgnoredFilesWidget(
|
||||
this.filesInDeviceCollection,
|
||||
|
@ -268,9 +268,9 @@ class _ResetIgnoredFilesWidgetState extends State<ResetIgnoredFilesWidget> {
|
|||
}
|
||||
|
||||
Future<void> _removeFilesFromIgnoredFiles(
|
||||
Future<List<File>> filesInDeviceCollection,
|
||||
Future<List<EnteFile>> filesInDeviceCollection,
|
||||
) async {
|
||||
final List<File> deviceCollectionFiles = await filesInDeviceCollection;
|
||||
final List<EnteFile> deviceCollectionFiles = await filesInDeviceCollection;
|
||||
await IgnoredFilesService.instance
|
||||
.removeIgnoredMappings(deviceCollectionFiles);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ typedef SortAscFn = bool Function();
|
|||
|
||||
class Gallery extends StatefulWidget {
|
||||
final GalleryLoader asyncLoader;
|
||||
final List<File>? initialFiles;
|
||||
final List<EnteFile>? initialFiles;
|
||||
final Stream<FilesUpdatedEvent>? reloadEvent;
|
||||
final List<Stream<Event>>? forceReloadEvents;
|
||||
final Set<EventType> removalEventTypes;
|
||||
|
@ -91,7 +91,7 @@ class _GalleryState extends State<Gallery> {
|
|||
static const int kInitialLoadLimit = 100;
|
||||
|
||||
late Logger _logger;
|
||||
List<List<File>> _currentGroupedFiles = [];
|
||||
List<List<EnteFile>> _currentGroupedFiles = [];
|
||||
bool _hasLoadedFiles = false;
|
||||
late ItemScrollController _itemScroller;
|
||||
StreamSubscription<FilesUpdatedEvent>? _reloadEventSubscription;
|
||||
|
@ -159,7 +159,7 @@ class _GalleryState extends State<Gallery> {
|
|||
super.initState();
|
||||
}
|
||||
|
||||
void _setFilesAndReload(List<File> files) {
|
||||
void _setFilesAndReload(List<EnteFile> files) {
|
||||
final hasReloaded = _onFilesLoaded(files);
|
||||
if (!hasReloaded && mounted) {
|
||||
setState(() {});
|
||||
|
@ -194,7 +194,7 @@ class _GalleryState extends State<Gallery> {
|
|||
|
||||
// group files into multiple groups and returns `true` if it resulted in a
|
||||
// gallery reload
|
||||
bool _onFilesLoaded(List<File> files) {
|
||||
bool _onFilesLoaded(List<EnteFile> files) {
|
||||
final updatedGroupedFiles =
|
||||
widget.enableFileGrouping ? _groupFiles(files) : [files];
|
||||
if (_currentGroupedFiles.length != updatedGroupedFiles.length ||
|
||||
|
@ -254,9 +254,9 @@ class _GalleryState extends State<Gallery> {
|
|||
);
|
||||
}
|
||||
|
||||
List<List<File>> _groupFiles(List<File> files) {
|
||||
List<File> dailyFiles = [];
|
||||
final List<List<File>> resultGroupedFiles = [];
|
||||
List<List<EnteFile>> _groupFiles(List<EnteFile> files) {
|
||||
List<EnteFile> dailyFiles = [];
|
||||
final List<List<EnteFile>> resultGroupedFiles = [];
|
||||
for (int index = 0; index < files.length; index++) {
|
||||
if (index > 0 &&
|
||||
!areFromSameDay(
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue