Use sqlite async for fetching files for gallery (#1397)
## Description - Migrated from `sqflite` to `sqlite_async` when fetching files for gallery (Home gallery, Collections page, Archive page & Add photos sheet gallery ). This has made gallery load significantly faster and has gotten rid of logs like `NativeAlloc concurrent copying GC freed 392872(19MB) AllocSpace objects, 139(4024KB) LOS objects, 38% free, 38MB/62MB, paused 2.868ms,93us total 324.898ms`. The initial load(100 files) and final load completes instantaneously even before the user starts interacting with the app which has gotten rid of the jank which was present before on the final load. - In the 'Add Photos sheet', it takes time for the gallery to load when using `sqflite` and images are rendered after this delay. After migrating to `sqlite_async`, since the gallery loads instantly and images are rendered right after, the animation of the bottom sheet coming up became a bit janky. To make it smooth, have added a delay to load gallery only after the bottom sheet is up fully. ## Tests - [x] Did basic testing to make sure the migrations are working fine.
This commit is contained in:
commit
b8be65862f
4 changed files with 120 additions and 72 deletions
|
@ -573,31 +573,34 @@ class FilesDB {
|
|||
bool applyOwnerCheck = false,
|
||||
}) async {
|
||||
final stopWatch = EnteWatch('getAllPendingOrUploadedFiles')..start();
|
||||
late String whereQuery;
|
||||
late List<Object?>? whereArgs;
|
||||
final order = (asc ?? false ? 'ASC' : 'DESC');
|
||||
|
||||
late String query;
|
||||
late List<Object?>? args;
|
||||
if (applyOwnerCheck) {
|
||||
whereQuery = '$columnCreationTime >= ? AND $columnCreationTime <= ? '
|
||||
query =
|
||||
'SELECT * FROM $filesTable WHERE $columnCreationTime >= ? AND $columnCreationTime <= ? '
|
||||
'AND ($columnOwnerID IS NULL OR $columnOwnerID = ?) '
|
||||
'AND ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1)'
|
||||
' AND $columnMMdVisibility = ?';
|
||||
whereArgs = [startTime, endTime, ownerID, visibility];
|
||||
' AND $columnMMdVisibility = ? ORDER BY $columnCreationTime $order, $columnModificationTime $order';
|
||||
|
||||
args = [startTime, endTime, ownerID, visibility];
|
||||
} else {
|
||||
whereQuery =
|
||||
'$columnCreationTime >= ? AND $columnCreationTime <= ? AND ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1)'
|
||||
' AND $columnMMdVisibility = ?';
|
||||
whereArgs = [startTime, endTime, visibility];
|
||||
query =
|
||||
'SELECT * FROM $filesTable WHERE $columnCreationTime >= ? AND $columnCreationTime <= ? '
|
||||
'AND ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1)'
|
||||
' AND $columnMMdVisibility = ? ORDER BY $columnCreationTime $order, $columnModificationTime $order';
|
||||
args = [startTime, endTime, visibility];
|
||||
}
|
||||
|
||||
final db = await instance.database;
|
||||
final order = (asc ?? false ? 'ASC' : 'DESC');
|
||||
final results = await db.query(
|
||||
filesTable,
|
||||
where: whereQuery,
|
||||
whereArgs: whereArgs,
|
||||
orderBy:
|
||||
'$columnCreationTime ' + order + ', $columnModificationTime ' + order,
|
||||
limit: limit,
|
||||
);
|
||||
if (limit != null) {
|
||||
query += ' LIMIT ?';
|
||||
args.add(limit);
|
||||
}
|
||||
|
||||
final db = await instance.sqliteAsyncDB;
|
||||
final results = await db.getAll(query, args);
|
||||
_logger.info("message");
|
||||
stopWatch.log('queryDone');
|
||||
final files = convertToFiles(results);
|
||||
stopWatch.log('convertDone');
|
||||
|
@ -609,23 +612,25 @@ class FilesDB {
|
|||
|
||||
Future<FileLoadResult> getAllLocalAndUploadedFiles(
|
||||
int startTime,
|
||||
int endTime,
|
||||
int ownerID, {
|
||||
int endTime, {
|
||||
int? limit,
|
||||
bool? asc,
|
||||
required DBFilterOptions filterOptions,
|
||||
}) async {
|
||||
final db = await instance.database;
|
||||
final db = await instance.sqliteAsyncDB;
|
||||
final order = (asc ?? false ? 'ASC' : 'DESC');
|
||||
final results = await db.query(
|
||||
filesTable,
|
||||
where:
|
||||
'$columnCreationTime >= ? AND $columnCreationTime <= ? AND ($columnMMdVisibility IS NULL OR $columnMMdVisibility = ?)'
|
||||
' AND ($columnLocalID IS NOT NULL OR ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1))',
|
||||
whereArgs: [startTime, endTime, visibleVisibility],
|
||||
orderBy:
|
||||
'$columnCreationTime ' + order + ', $columnModificationTime ' + order,
|
||||
limit: limit,
|
||||
final args = [startTime, endTime, visibleVisibility];
|
||||
String query =
|
||||
'SELECT * FROM $filesTable WHERE $columnCreationTime >= ? AND $columnCreationTime <= ? AND ($columnMMdVisibility IS NULL OR $columnMMdVisibility = ?)'
|
||||
' AND ($columnLocalID IS NOT NULL OR ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1))'
|
||||
' ORDER BY $columnCreationTime $order, $columnModificationTime $order';
|
||||
if (limit != null) {
|
||||
query += ' LIMIT ?';
|
||||
args.add(limit);
|
||||
}
|
||||
final results = await db.getAll(
|
||||
query,
|
||||
args,
|
||||
);
|
||||
final files = convertToFiles(results);
|
||||
final List<EnteFile> filteredFiles =
|
||||
|
@ -658,19 +663,18 @@ class FilesDB {
|
|||
bool? asc,
|
||||
int visibility = visibleVisibility,
|
||||
}) async {
|
||||
final db = await instance.database;
|
||||
final db = await instance.sqliteAsyncDB;
|
||||
final order = (asc ?? false ? 'ASC' : 'DESC');
|
||||
const String whereClause =
|
||||
'$columnCollectionID = ? AND $columnCreationTime >= ? AND $columnCreationTime <= ?';
|
||||
final List<Object> whereArgs = [collectionID, startTime, endTime];
|
||||
|
||||
final results = await db.query(
|
||||
filesTable,
|
||||
where: whereClause,
|
||||
whereArgs: whereArgs,
|
||||
orderBy:
|
||||
'$columnCreationTime ' + order + ', $columnModificationTime ' + order,
|
||||
limit: limit,
|
||||
String query =
|
||||
'SELECT * FROM $filesTable WHERE $columnCollectionID = ? AND $columnCreationTime >= ? AND $columnCreationTime <= ? ORDER BY $columnCreationTime $order, $columnModificationTime $order';
|
||||
final List<Object> args = [collectionID, startTime, endTime];
|
||||
if (limit != null) {
|
||||
query += ' LIMIT ?';
|
||||
args.add(limit);
|
||||
}
|
||||
final results = await db.getAll(
|
||||
query,
|
||||
args,
|
||||
);
|
||||
final files = convertToFiles(results);
|
||||
return FileLoadResult(files, files.length == limit);
|
||||
|
@ -1601,7 +1605,6 @@ class FilesDB {
|
|||
bool dedupeByUploadId = true,
|
||||
}) async {
|
||||
final db = await instance.sqliteAsyncDB;
|
||||
|
||||
final result = await db.getAll(
|
||||
'SELECT * FROM $filesTable ORDER BY $columnCreationTime DESC',
|
||||
);
|
||||
|
|
|
@ -46,7 +46,6 @@ class HomeGalleryWidget extends StatelessWidget {
|
|||
result = await FilesDB.instance.getAllLocalAndUploadedFiles(
|
||||
creationStartTime,
|
||||
creationEndTime,
|
||||
ownerID!,
|
||||
limit: limit,
|
||||
asc: asc,
|
||||
filterOptions: filterOptions,
|
||||
|
|
|
@ -108,6 +108,7 @@ class GalleryState extends State<Gallery> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_logTag =
|
||||
"Gallery_${widget.tagPrefix}${kDebugMode ? "_" + widget.albumName! : ""}";
|
||||
_logger = Logger(_logTag);
|
||||
|
@ -172,7 +173,6 @@ class GalleryState extends State<Gallery> {
|
|||
_setFilesAndReload(result.files);
|
||||
}
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void _setFilesAndReload(List<EnteFile> files) {
|
||||
|
|
|
@ -2,6 +2,7 @@ import "dart:math";
|
|||
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_animate/flutter_animate.dart";
|
||||
import "package:modal_bottom_sheet/modal_bottom_sheet.dart";
|
||||
import "package:photos/core/configuration.dart";
|
||||
import "package:photos/db/files_db.dart";
|
||||
|
@ -15,6 +16,7 @@ import "package:photos/theme/colors.dart";
|
|||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/actions/collection/collection_file_actions.dart";
|
||||
import "package:photos/ui/actions/collection/collection_sharing_actions.dart";
|
||||
import "package:photos/ui/common/loading_widget.dart";
|
||||
import "package:photos/ui/components/bottom_of_title_bar_widget.dart";
|
||||
import "package:photos/ui/components/buttons/button_widget.dart";
|
||||
import "package:photos/ui/components/models/button_type.dart";
|
||||
|
@ -91,33 +93,9 @@ class AddPhotosPhotoWidget extends StatelessWidget {
|
|||
showCloseButton: true,
|
||||
),
|
||||
Expanded(
|
||||
child: Gallery(
|
||||
inSelectionMode: true,
|
||||
asyncLoader: (
|
||||
creationStartTime,
|
||||
creationEndTime, {
|
||||
limit,
|
||||
asc,
|
||||
}) {
|
||||
return FilesDB.instance
|
||||
.getAllPendingOrUploadedFiles(
|
||||
creationStartTime,
|
||||
creationEndTime,
|
||||
Configuration.instance.getUserID()!,
|
||||
limit: limit,
|
||||
asc: asc,
|
||||
filterOptions: DBFilterOptions(
|
||||
hideIgnoredForUpload: true,
|
||||
dedupeUploadID: true,
|
||||
ignoredCollectionIDs: hiddenCollectionIDs,
|
||||
),
|
||||
applyOwnerCheck: true,
|
||||
);
|
||||
},
|
||||
tagPrefix: "pick_add_photos_gallery",
|
||||
child: DelayedGallery(
|
||||
hiddenCollectionIDs: hiddenCollectionIDs,
|
||||
selectedFiles: selectedFiles,
|
||||
showSelectAllByDefault: true,
|
||||
sortAsyncFn: () => false,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -227,3 +205,71 @@ class AddPhotosPhotoWidget extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DelayedGallery extends StatefulWidget {
|
||||
const DelayedGallery({
|
||||
super.key,
|
||||
required this.hiddenCollectionIDs,
|
||||
required this.selectedFiles,
|
||||
});
|
||||
|
||||
final Set<int> hiddenCollectionIDs;
|
||||
final SelectedFiles selectedFiles;
|
||||
|
||||
@override
|
||||
State<DelayedGallery> createState() => _DelayedGalleryState();
|
||||
}
|
||||
|
||||
class _DelayedGalleryState extends State<DelayedGallery> {
|
||||
bool _showGallery = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_showGallery = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_showGallery) {
|
||||
return Gallery(
|
||||
inSelectionMode: true,
|
||||
asyncLoader: (
|
||||
creationStartTime,
|
||||
creationEndTime, {
|
||||
limit,
|
||||
asc,
|
||||
}) {
|
||||
return FilesDB.instance.getAllPendingOrUploadedFiles(
|
||||
creationStartTime,
|
||||
creationEndTime,
|
||||
Configuration.instance.getUserID()!,
|
||||
limit: limit,
|
||||
asc: asc,
|
||||
filterOptions: DBFilterOptions(
|
||||
hideIgnoredForUpload: true,
|
||||
dedupeUploadID: true,
|
||||
ignoredCollectionIDs: widget.hiddenCollectionIDs,
|
||||
),
|
||||
applyOwnerCheck: true,
|
||||
);
|
||||
},
|
||||
tagPrefix: "pick_add_photos_gallery",
|
||||
selectedFiles: widget.selectedFiles,
|
||||
showSelectAllByDefault: true,
|
||||
sortAsyncFn: () => false,
|
||||
).animate().fadeIn(
|
||||
duration: const Duration(milliseconds: 175),
|
||||
curve: Curves.easeOutCirc,
|
||||
);
|
||||
} else {
|
||||
return const EnteLoadingWidget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue