Add view large file option
This commit is contained in:
3
mobile/lib/generated/intl/messages_en.dart
generated
3
mobile/lib/generated/intl/messages_en.dart
generated
@@ -1533,6 +1533,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"viewAll": MessageLookupByLibrary.simpleMessage("View all"),
|
||||
"viewAllExifData":
|
||||
MessageLookupByLibrary.simpleMessage("View all EXIF data"),
|
||||
"viewLargeFiles": MessageLookupByLibrary.simpleMessage("Large files"),
|
||||
"viewLargeFilesDesc": MessageLookupByLibrary.simpleMessage(
|
||||
"View files that are consuming the most amount of storage"),
|
||||
"viewLogs": MessageLookupByLibrary.simpleMessage("View logs"),
|
||||
"viewRecoveryKey":
|
||||
MessageLookupByLibrary.simpleMessage("View recovery key"),
|
||||
|
||||
20
mobile/lib/generated/l10n.dart
generated
20
mobile/lib/generated/l10n.dart
generated
@@ -3482,6 +3482,26 @@ class S {
|
||||
);
|
||||
}
|
||||
|
||||
/// `Large files`
|
||||
String get viewLargeFiles {
|
||||
return Intl.message(
|
||||
'Large files',
|
||||
name: 'viewLargeFiles',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `View files that are consuming the most amount of storage`
|
||||
String get viewLargeFilesDesc {
|
||||
return Intl.message(
|
||||
'View files that are consuming the most amount of storage',
|
||||
name: 'viewLargeFilesDesc',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `✨ No duplicates`
|
||||
String get noDuplicates {
|
||||
return Intl.message(
|
||||
|
||||
@@ -483,6 +483,8 @@
|
||||
"noDeviceThatCanBeDeleted": "You've no files on this device that can be deleted",
|
||||
"removeDuplicates": "Remove duplicates",
|
||||
"removeDuplicatesDesc": "Review and remove files that are exact duplicates.",
|
||||
"viewLargeFiles": "Large files",
|
||||
"viewLargeFilesDesc": "View files that are consuming the most amount of storage",
|
||||
"noDuplicates": "✨ No duplicates",
|
||||
"youveNoDuplicateFilesThatCanBeCleared": "You've no duplicate files that can be cleared",
|
||||
"success": "Success",
|
||||
|
||||
@@ -20,6 +20,7 @@ import 'package:photos/ui/components/title_bar_title_widget.dart';
|
||||
import 'package:photos/ui/components/title_bar_widget.dart';
|
||||
import "package:photos/ui/tools/deduplicate_page.dart";
|
||||
import "package:photos/ui/tools/free_space_page.dart";
|
||||
import "package:photos/ui/viewer/gallery/large_files_page.dart";
|
||||
import "package:photos/utils/data_util.dart";
|
||||
import "package:photos/utils/dialog_util.dart";
|
||||
import 'package:photos/utils/local_settings.dart';
|
||||
@@ -125,62 +126,90 @@ class _FreeUpSpaceOptionsScreenState extends State<FreeUpSpaceOptionsScreen> {
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
],
|
||||
),
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: S.of(context).removeDuplicates,
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
alignCaptionedTextToLeft: true,
|
||||
trailingIconIsMuted: true,
|
||||
showOnlyLoadingState: true,
|
||||
onTap: () async {
|
||||
List<DuplicateFiles> duplicates;
|
||||
try {
|
||||
duplicates = await DeduplicationService
|
||||
.instance
|
||||
.getDuplicateFiles();
|
||||
} catch (e) {
|
||||
await showGenericErrorDialog(
|
||||
context: context,
|
||||
error: e,
|
||||
);
|
||||
return;
|
||||
}
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: S.of(context).removeDuplicates,
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
alignCaptionedTextToLeft: true,
|
||||
trailingIconIsMuted: true,
|
||||
showOnlyLoadingState: true,
|
||||
onTap: () async {
|
||||
List<DuplicateFiles> duplicates;
|
||||
try {
|
||||
duplicates = await DeduplicationService
|
||||
.instance
|
||||
.getDuplicateFiles();
|
||||
} catch (e) {
|
||||
await showGenericErrorDialog(
|
||||
context: context,
|
||||
error: e,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (duplicates.isEmpty) {
|
||||
unawaited(
|
||||
showErrorDialog(
|
||||
if (duplicates.isEmpty) {
|
||||
unawaited(
|
||||
showErrorDialog(
|
||||
context,
|
||||
S.of(context).noDuplicates,
|
||||
S
|
||||
.of(context)
|
||||
.youveNoDuplicateFilesThatCanBeCleared,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final DeduplicationResult? result =
|
||||
await routeToPage(
|
||||
context,
|
||||
DeduplicatePage(duplicates),
|
||||
);
|
||||
if (result != null) {
|
||||
_showDuplicateFilesDeletedDialog(
|
||||
result,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: MenuSectionDescriptionWidget(
|
||||
content: S.of(context).removeDuplicatesDesc,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: S.of(context).viewLargeFiles,
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
alignCaptionedTextToLeft: true,
|
||||
trailingIconIsMuted: true,
|
||||
showOnlyLoadingState: true,
|
||||
onTap: () async {
|
||||
await routeToPage(
|
||||
context,
|
||||
S.of(context).noDuplicates,
|
||||
S
|
||||
.of(context)
|
||||
.youveNoDuplicateFilesThatCanBeCleared,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final DeduplicationResult? result =
|
||||
await routeToPage(
|
||||
context,
|
||||
DeduplicatePage(duplicates),
|
||||
);
|
||||
if (result != null) {
|
||||
_showDuplicateFilesDeletedDialog(result);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
MenuSectionDescriptionWidget(
|
||||
content: S.of(context).removeDuplicatesDesc,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
LargeFilesPagePage(),
|
||||
);
|
||||
},
|
||||
),
|
||||
MenuSectionDescriptionWidget(
|
||||
content: S.of(context).viewLargeFilesDesc,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
90
mobile/lib/ui/viewer/gallery/large_files_page.dart
Normal file
90
mobile/lib/ui/viewer/gallery/large_files_page.dart
Normal file
@@ -0,0 +1,90 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/core/event_bus.dart';
|
||||
import 'package:photos/events/collection_meta_event.dart';
|
||||
import 'package:photos/events/collection_updated_event.dart';
|
||||
import 'package:photos/events/files_updated_event.dart';
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/models/file/file.dart";
|
||||
import 'package:photos/models/file_load_result.dart';
|
||||
import 'package:photos/models/gallery_type.dart';
|
||||
import 'package:photos/models/selected_files.dart';
|
||||
import "package:photos/services/search_service.dart";
|
||||
import 'package:photos/ui/viewer/actions/file_selection_overlay_bar.dart';
|
||||
import "package:photos/ui/viewer/gallery/component/group/type.dart";
|
||||
import 'package:photos/ui/viewer/gallery/gallery.dart';
|
||||
|
||||
class LargeFilesPagePage extends StatelessWidget {
|
||||
final String tagPrefix;
|
||||
final GalleryType appBarType;
|
||||
final GalleryType overlayType;
|
||||
final _selectedFiles = SelectedFiles();
|
||||
static const int minLargeFileSize = 50 * 1024 * 1024;
|
||||
|
||||
LargeFilesPagePage({
|
||||
this.tagPrefix = "Uncategorized_page",
|
||||
this.appBarType = GalleryType.homepage,
|
||||
this.overlayType = GalleryType.homepage,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final gallery = Gallery(
|
||||
asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) async {
|
||||
final List<EnteFile> allFiles =
|
||||
await SearchService.instance.getAllFiles();
|
||||
final filesWithSize = <EnteFile>[];
|
||||
for (final file in allFiles) {
|
||||
if (file.fileSize != null && file.fileSize! > minLargeFileSize) {
|
||||
filesWithSize.add(file);
|
||||
}
|
||||
}
|
||||
final FileLoadResult result = FileLoadResult(filesWithSize, false);
|
||||
return result;
|
||||
},
|
||||
reloadEvent: Bus.instance.on<CollectionUpdatedEvent>(),
|
||||
removalEventTypes: const {
|
||||
EventType.deletedFromRemote,
|
||||
EventType.deletedFromEverywhere,
|
||||
EventType.hide,
|
||||
},
|
||||
forceReloadEvents: [
|
||||
Bus.instance.on<CollectionMetaEvent>(),
|
||||
],
|
||||
tagPrefix: tagPrefix,
|
||||
selectedFiles: _selectedFiles,
|
||||
sortAsyncFn: () => false,
|
||||
groupType: GroupType.size,
|
||||
initialFiles: null,
|
||||
albumName: S.of(context).viewLargeFiles,
|
||||
);
|
||||
return Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(50.0),
|
||||
child: AppBar(
|
||||
elevation: 0,
|
||||
centerTitle: false,
|
||||
title: Text(
|
||||
S.of(context).viewLargeFiles,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineSmall!
|
||||
.copyWith(fontSize: 16),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
FileSelectionOverlayBar(
|
||||
overlayType,
|
||||
_selectedFiles,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user