ente/lib/ui/viewer/gallery/component/multiple_groups_gallery_view.dart

150 lines
4.9 KiB
Dart
Raw Normal View History

import "package:flutter/material.dart";
import "package:intl/intl.dart";
import "package:logging/logging.dart";
import "package:photos/core/event_bus.dart";
import "package:photos/ente_theme_data.dart";
import "package:photos/events/files_updated_event.dart";
import "package:photos/models/file.dart";
import "package:photos/models/selected_files.dart";
import "package:photos/ui/common/loading_widget.dart";
import "package:photos/ui/huge_listview/huge_listview.dart";
2023-05-31 19:34:19 +00:00
import 'package:photos/ui/viewer/gallery/component/group/lazy_group_gallery.dart';
import "package:photos/ui/viewer/gallery/gallery.dart";
import "package:photos/utils/local_settings.dart";
import "package:scrollable_positioned_list/scrollable_positioned_list.dart";
2023-05-31 19:34:19 +00:00
/*
2023-05-31 19:55:57 +00:00
MultipleGroupsGalleryView is a widget that displays a list of grouped/collated
2023-05-31 19:34:19 +00:00
files when grouping is enabled.
For each group, it displays a header and use LazyGroupGallery to display a
particular group of files.
If a group has more than 400 files, LazyGroupGallery internally divides the
group into multiple grid views during rendering.
*/
2023-05-31 19:55:57 +00:00
class MultipleGroupsGalleryView extends StatelessWidget {
final ItemScrollController itemScroller;
2023-06-01 06:35:30 +00:00
final List<List<File>> groupedFiles;
final bool disableScroll;
final Widget? header;
final Widget? footer;
final Widget emptyState;
final GalleryLoader asyncLoader;
final Stream<FilesUpdatedEvent>? reloadEvent;
final Set<EventType> removalEventTypes;
final String tagPrefix;
final double scrollBottomSafeArea;
final bool limitSelectionToOne;
final SelectedFiles? selectedFiles;
2023-05-31 19:08:10 +00:00
final bool enableFileGrouping;
final String logTag;
final Logger logger;
final bool showSelectAllByDefault;
final bool isScrollablePositionedList;
2023-05-31 19:55:57 +00:00
const MultipleGroupsGalleryView({
required this.itemScroller,
2023-06-01 06:35:30 +00:00
required this.groupedFiles,
required this.disableScroll,
this.header,
this.footer,
required this.emptyState,
required this.asyncLoader,
this.reloadEvent,
required this.removalEventTypes,
required this.tagPrefix,
required this.scrollBottomSafeArea,
required this.limitSelectionToOne,
this.selectedFiles,
2023-05-31 19:08:10 +00:00
required this.enableFileGrouping,
required this.logTag,
required this.logger,
required this.showSelectAllByDefault,
required this.isScrollablePositionedList,
super.key,
});
@override
Widget build(BuildContext context) {
return HugeListView<List<File>>(
controller: itemScroller,
startIndex: 0,
2023-06-01 06:35:30 +00:00
totalCount: groupedFiles.length,
isDraggableScrollbarEnabled: groupedFiles.length > 10,
disableScroll: disableScroll,
isScrollablePositionedList: isScrollablePositionedList,
waitBuilder: (_) {
return const EnteLoadingWidget();
},
emptyResultBuilder: (_) {
final List<Widget> children = [];
if (header != null) {
children.add(header!);
}
children.add(
Expanded(
child: emptyState,
),
);
if (footer != null) {
children.add(footer!);
}
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: children,
);
},
itemBuilder: (context, index) {
Widget gallery;
2023-05-31 19:34:19 +00:00
gallery = LazyGroupGallery(
2023-06-01 06:35:30 +00:00
groupedFiles[index],
index,
reloadEvent,
removalEventTypes,
asyncLoader,
selectedFiles,
tagPrefix,
Bus.instance
.on<GalleryIndexUpdatedEvent>()
.where((event) => event.tag == tagPrefix)
.map((event) => event.index),
2023-05-31 19:08:10 +00:00
enableFileGrouping,
showSelectAllByDefault,
logTag: logTag,
photoGridSize: LocalSettings.instance.getPhotoGridSize(),
limitSelectionToOne: limitSelectionToOne,
);
if (header != null && index == 0) {
gallery = Column(children: [header!, gallery]);
}
2023-06-01 06:35:30 +00:00
if (footer != null && index == groupedFiles.length - 1) {
gallery = Column(children: [gallery, footer!]);
}
return gallery;
},
labelTextBuilder: (int index) {
try {
return DateFormat.yMMM(Localizations.localeOf(context).languageCode)
.format(
DateTime.fromMicrosecondsSinceEpoch(
2023-06-01 06:35:30 +00:00
groupedFiles[index][0].creationTime!,
),
);
} catch (e) {
logger.severe("label text builder failed", e);
return "";
}
},
thumbBackgroundColor:
Theme.of(context).colorScheme.galleryThumbBackgroundColor,
thumbDrawColor: Theme.of(context).colorScheme.galleryThumbDrawColor,
thumbPadding: header != null
? const EdgeInsets.only(top: 60)
: const EdgeInsets.all(0),
bottomSafeArea: scrollBottomSafeArea,
firstShown: (int firstIndex) {
Bus.instance.fire(GalleryIndexUpdatedEvent(tagPrefix, firstIndex));
},
);
}
}