Merge pull request #389 from ente-io/ios_view_all
Add view all device photos option for iOS
This commit is contained in:
commit
34748f950b
|
@ -489,6 +489,20 @@ class FilesDB {
|
||||||
return FileLoadResult(deduplicatedFiles, files.length == limit);
|
return FileLoadResult(deduplicatedFiles, files.length == limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<File> _deduplicateByLocalID(List<File> files) {
|
||||||
|
final localIDs = <String>{};
|
||||||
|
final List<File> deduplicatedFiles = [];
|
||||||
|
for (final file in files) {
|
||||||
|
final id = file.localID;
|
||||||
|
if (id != null && localIDs.contains(id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
localIDs.add(id);
|
||||||
|
deduplicatedFiles.add(file);
|
||||||
|
}
|
||||||
|
return deduplicatedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
List<File> _deduplicatedAndFilterIgnoredFiles(
|
List<File> _deduplicatedAndFilterIgnoredFiles(
|
||||||
List<File> files,
|
List<File> files,
|
||||||
Set<int> ignoredCollectionIDs,
|
Set<int> ignoredCollectionIDs,
|
||||||
|
@ -556,6 +570,28 @@ class FilesDB {
|
||||||
return FileLoadResult(files, files.length == limit);
|
return FileLoadResult(files, files.length == limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<FileLoadResult> getLocalDeviceFiles(
|
||||||
|
int startTime,
|
||||||
|
int endTime, {
|
||||||
|
int limit,
|
||||||
|
bool asc,
|
||||||
|
}) async {
|
||||||
|
final db = await instance.database;
|
||||||
|
final order = (asc ?? false ? 'ASC' : 'DESC');
|
||||||
|
final results = await db.query(
|
||||||
|
table,
|
||||||
|
where:
|
||||||
|
'$columnCreationTime >= ? AND $columnCreationTime <= ? AND $columnLocalID IS NOT NULL',
|
||||||
|
whereArgs: [startTime, endTime],
|
||||||
|
orderBy:
|
||||||
|
'$columnCreationTime ' + order + ', $columnModificationTime ' + order,
|
||||||
|
limit: limit,
|
||||||
|
);
|
||||||
|
final files = _convertToFiles(results);
|
||||||
|
final result = _deduplicateByLocalID(files);
|
||||||
|
return FileLoadResult(result, files.length == limit);
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<File>> getAllVideos() async {
|
Future<List<File>> getAllVideos() async {
|
||||||
final db = await instance.database;
|
final db = await instance.database;
|
||||||
final results = await db.query(
|
final results = await db.query(
|
||||||
|
|
|
@ -3,6 +3,7 @@ enum GalleryType {
|
||||||
archive,
|
archive,
|
||||||
trash,
|
trash,
|
||||||
localFolder,
|
localFolder,
|
||||||
|
localAll, // used for gallery view displaying all local photos on the device
|
||||||
// indicator for gallery view of collections shared with the user
|
// indicator for gallery view of collections shared with the user
|
||||||
sharedCollection,
|
sharedCollection,
|
||||||
ownedCollection,
|
ownedCollection,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -22,6 +23,7 @@ import 'package:photos/ui/common/loading_widget.dart';
|
||||||
import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
|
import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
|
||||||
import 'package:photos/ui/viewer/gallery/archive_page.dart';
|
import 'package:photos/ui/viewer/gallery/archive_page.dart';
|
||||||
import 'package:photos/ui/viewer/gallery/collection_page.dart';
|
import 'package:photos/ui/viewer/gallery/collection_page.dart';
|
||||||
|
import 'package:photos/ui/viewer/gallery/device_all_page.dart';
|
||||||
import 'package:photos/ui/viewer/gallery/device_folder_page.dart';
|
import 'package:photos/ui/viewer/gallery/device_folder_page.dart';
|
||||||
import 'package:photos/ui/viewer/gallery/empte_state.dart';
|
import 'package:photos/ui/viewer/gallery/empte_state.dart';
|
||||||
import 'package:photos/ui/viewer/gallery/trash_page.dart';
|
import 'package:photos/ui/viewer/gallery/trash_page.dart';
|
||||||
|
@ -150,7 +152,22 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
const SectionTitle("On device"),
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
const SectionTitle("On device"),
|
||||||
|
Platform.isAndroid
|
||||||
|
? const SizedBox.shrink()
|
||||||
|
: GestureDetector(
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.only(right: 12.0),
|
||||||
|
child: Text("View all"),
|
||||||
|
),
|
||||||
|
onTap: () => routeToPage(context, DeviceAllPage()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
items.folders.isEmpty
|
items.folders.isEmpty
|
||||||
? const Padding(
|
? const Padding(
|
||||||
|
|
60
lib/ui/viewer/gallery/device_all_page.dart
Normal file
60
lib/ui/viewer/gallery/device_all_page.dart
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:photos/core/event_bus.dart';
|
||||||
|
import 'package:photos/db/files_db.dart';
|
||||||
|
import 'package:photos/events/files_updated_event.dart';
|
||||||
|
import 'package:photos/events/local_photos_updated_event.dart';
|
||||||
|
import 'package:photos/models/gallery_type.dart';
|
||||||
|
import 'package:photos/models/selected_files.dart';
|
||||||
|
import 'package:photos/ui/viewer/gallery/gallery.dart';
|
||||||
|
import 'package:photos/ui/viewer/gallery/gallery_app_bar_widget.dart';
|
||||||
|
import 'package:photos/ui/viewer/gallery/gallery_overlay_widget.dart';
|
||||||
|
|
||||||
|
// This page is used to display all photos which are present on the local device
|
||||||
|
class DeviceAllPage extends StatelessWidget {
|
||||||
|
final _selectedFiles = SelectedFiles();
|
||||||
|
|
||||||
|
DeviceAllPage({Key key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(Object context) {
|
||||||
|
final gallery = Gallery(
|
||||||
|
asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) {
|
||||||
|
return FilesDB.instance.getLocalDeviceFiles(
|
||||||
|
creationStartTime,
|
||||||
|
creationEndTime,
|
||||||
|
limit: limit,
|
||||||
|
asc: asc,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
|
||||||
|
removalEventTypes: const {
|
||||||
|
EventType.deletedFromDevice,
|
||||||
|
EventType.deletedFromEverywhere,
|
||||||
|
},
|
||||||
|
tagPrefix: "device_all",
|
||||||
|
selectedFiles: _selectedFiles,
|
||||||
|
initialFiles: null,
|
||||||
|
footer: const SizedBox(height: 32),
|
||||||
|
);
|
||||||
|
return Scaffold(
|
||||||
|
appBar: PreferredSize(
|
||||||
|
preferredSize: const Size.fromHeight(50.0),
|
||||||
|
child: GalleryAppBarWidget(
|
||||||
|
GalleryType.localAll,
|
||||||
|
"On device",
|
||||||
|
_selectedFiles,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
children: [
|
||||||
|
gallery,
|
||||||
|
GalleryOverlayWidget(
|
||||||
|
GalleryType.localFolder,
|
||||||
|
_selectedFiles,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -265,7 +265,8 @@ class _OverlayWidgetState extends State<OverlayWidget> {
|
||||||
String msg = "Add";
|
String msg = "Add";
|
||||||
IconData iconData = Platform.isAndroid ? Icons.add : CupertinoIcons.add;
|
IconData iconData = Platform.isAndroid ? Icons.add : CupertinoIcons.add;
|
||||||
// show upload icon instead of add for files selected in local gallery
|
// show upload icon instead of add for files selected in local gallery
|
||||||
if (widget.type == GalleryType.localFolder) {
|
if (widget.type == GalleryType.localFolder ||
|
||||||
|
widget.type == GalleryType.localAll) {
|
||||||
msg = "Upload";
|
msg = "Upload";
|
||||||
iconData = Platform.isAndroid
|
iconData = Platform.isAndroid
|
||||||
? Icons.cloud_upload
|
? Icons.cloud_upload
|
||||||
|
@ -319,7 +320,8 @@ class _OverlayWidgetState extends State<OverlayWidget> {
|
||||||
);
|
);
|
||||||
if (widget.type == GalleryType.homepage ||
|
if (widget.type == GalleryType.homepage ||
|
||||||
widget.type == GalleryType.archive ||
|
widget.type == GalleryType.archive ||
|
||||||
widget.type == GalleryType.localFolder) {
|
widget.type == GalleryType.localFolder ||
|
||||||
|
widget.type == GalleryType.localAll) {
|
||||||
actions.add(
|
actions.add(
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: "Delete",
|
message: "Delete",
|
||||||
|
|
Loading…
Reference in a new issue