|
@@ -33,7 +33,6 @@ class LazyLoadingGallery extends StatefulWidget {
|
|
|
final String tag;
|
|
|
final String logTag;
|
|
|
final Stream<int> currentIndexStream;
|
|
|
- final bool smallerTodayFont;
|
|
|
|
|
|
LazyLoadingGallery(
|
|
|
this.files,
|
|
@@ -44,7 +43,6 @@ class LazyLoadingGallery extends StatefulWidget {
|
|
|
this.selectedFiles,
|
|
|
this.tag,
|
|
|
this.currentIndexStream, {
|
|
|
- this.smallerTodayFont,
|
|
|
this.logTag = "",
|
|
|
Key key,
|
|
|
}) : super(key: key ?? UniqueKey());
|
|
@@ -64,8 +62,9 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
|
|
|
StreamSubscription<FilesUpdatedEvent> _reloadEventSubscription;
|
|
|
StreamSubscription<int> _currentIndexSubscription;
|
|
|
bool _shouldRender;
|
|
|
- final ValueNotifier<bool> _shouldSelectAll = ValueNotifier(false);
|
|
|
+ final ValueNotifier<bool> _toggleSelectAllFromDay = ValueNotifier(false);
|
|
|
final ValueNotifier<bool> _showSelectAllButton = ValueNotifier(false);
|
|
|
+ final ValueNotifier<bool> _areAllFromDaySelected = ValueNotifier(false);
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
@@ -163,6 +162,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
|
|
|
_reloadEventSubscription.cancel();
|
|
|
_currentIndexSubscription.cancel();
|
|
|
widget.selectedFiles.removeListener(_selectedFilesListener);
|
|
|
+
|
|
|
super.dispose();
|
|
|
}
|
|
|
|
|
@@ -182,24 +182,28 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
|
|
|
}
|
|
|
return Column(
|
|
|
children: [
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.fromLTRB(4, 14, 12, 8),
|
|
|
- child: Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
- children: [
|
|
|
- getDayWidget(
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: [
|
|
|
+ Padding(
|
|
|
+ padding: const EdgeInsets.all(12),
|
|
|
+ child: getDayWidget(
|
|
|
context,
|
|
|
_files[0].creationTime,
|
|
|
- widget.smallerTodayFont,
|
|
|
),
|
|
|
- ValueListenableBuilder(
|
|
|
- valueListenable: _showSelectAllButton,
|
|
|
- builder: (context, value, _) {
|
|
|
- return widget.selectedFiles.files.isEmpty
|
|
|
- ? const SizedBox.shrink()
|
|
|
- : GestureDetector(
|
|
|
+ ),
|
|
|
+ ValueListenableBuilder(
|
|
|
+ valueListenable: _showSelectAllButton,
|
|
|
+ builder: (context, value, _) {
|
|
|
+ return !value
|
|
|
+ ? const SizedBox.shrink()
|
|
|
+ : GestureDetector(
|
|
|
+ behavior: HitTestBehavior.translucent,
|
|
|
+ child: SizedBox(
|
|
|
+ width: 48,
|
|
|
+ height: 44,
|
|
|
child: ValueListenableBuilder(
|
|
|
- valueListenable: _shouldSelectAll,
|
|
|
+ valueListenable: _areAllFromDaySelected,
|
|
|
builder: (context, value, _) {
|
|
|
return value
|
|
|
? const Icon(
|
|
@@ -214,14 +218,17 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
|
|
|
);
|
|
|
},
|
|
|
),
|
|
|
- onTap: () {
|
|
|
- _shouldSelectAll.value = !_shouldSelectAll.value;
|
|
|
- },
|
|
|
- );
|
|
|
- },
|
|
|
- )
|
|
|
- ],
|
|
|
- ),
|
|
|
+ ),
|
|
|
+ onTap: () {
|
|
|
+ //this value has no significance
|
|
|
+ //changing only to notify the listeners
|
|
|
+ _toggleSelectAllFromDay.value =
|
|
|
+ !_toggleSelectAllFromDay.value;
|
|
|
+ },
|
|
|
+ );
|
|
|
+ },
|
|
|
+ )
|
|
|
+ ],
|
|
|
),
|
|
|
_shouldRender ? _getGallery() : PlaceHolderWidget(_files.length),
|
|
|
],
|
|
@@ -242,7 +249,8 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
|
|
|
widget.selectedFiles,
|
|
|
index == 0,
|
|
|
_files.length > kRecycleLimit,
|
|
|
- _shouldSelectAll,
|
|
|
+ _toggleSelectAllFromDay,
|
|
|
+ _areAllFromDaySelected,
|
|
|
),
|
|
|
);
|
|
|
}
|
|
@@ -253,13 +261,6 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
|
|
|
}
|
|
|
|
|
|
void _selectedFilesListener() {
|
|
|
- final filesOfGirdAsSet = widget.files.toSet();
|
|
|
- //to disable the 'all selected' state of the icon when every file is
|
|
|
- //unselected one by one after selecting all using the icon
|
|
|
- if (!widget.selectedFiles.files
|
|
|
- .any((element) => filesOfGirdAsSet.contains(element))) {
|
|
|
- _shouldSelectAll.value = false;
|
|
|
- }
|
|
|
if (widget.selectedFiles.files.isEmpty) {
|
|
|
_showSelectAllButton.value = false;
|
|
|
} else {
|
|
@@ -270,21 +271,23 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
|
|
|
|
|
|
class LazyLoadingGridView extends StatefulWidget {
|
|
|
final String tag;
|
|
|
- final List<File> files;
|
|
|
+ final List<File> filesInDay;
|
|
|
final GalleryLoader asyncLoader;
|
|
|
final SelectedFiles selectedFiles;
|
|
|
final bool shouldRender;
|
|
|
final bool shouldRecycle;
|
|
|
- final ValueNotifier shouldSelectAll;
|
|
|
+ final ValueNotifier toggleSelectAllFromDay;
|
|
|
+ final ValueNotifier areAllFilesSelected;
|
|
|
|
|
|
LazyLoadingGridView(
|
|
|
this.tag,
|
|
|
- this.files,
|
|
|
+ this.filesInDay,
|
|
|
this.asyncLoader,
|
|
|
this.selectedFiles,
|
|
|
this.shouldRender,
|
|
|
this.shouldRecycle,
|
|
|
- this.shouldSelectAll, {
|
|
|
+ this.toggleSelectAllFromDay,
|
|
|
+ this.areAllFilesSelected, {
|
|
|
Key key,
|
|
|
}) : super(key: key ?? UniqueKey());
|
|
|
|
|
@@ -299,7 +302,6 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
@override
|
|
|
void initState() {
|
|
|
_shouldRender = widget.shouldRender;
|
|
|
- widget.shouldSelectAll.addListener(_shouldSelectAllListener);
|
|
|
widget.selectedFiles.addListener(_selectedFilesListener);
|
|
|
_clearSelectionsEvent =
|
|
|
Bus.instance.on<ClearSelectionsEvent>().listen((event) {
|
|
@@ -307,21 +309,23 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
setState(() {});
|
|
|
}
|
|
|
});
|
|
|
+ widget.toggleSelectAllFromDay.addListener(_toggleSelectAllFromDayListener);
|
|
|
super.initState();
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
void dispose() {
|
|
|
widget.selectedFiles.removeListener(_selectedFilesListener);
|
|
|
- widget.shouldSelectAll.removeListener(_shouldSelectAllListener);
|
|
|
_clearSelectionsEvent.cancel();
|
|
|
+ widget.toggleSelectAllFromDay
|
|
|
+ .removeListener(_toggleSelectAllFromDayListener);
|
|
|
super.dispose();
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
void didUpdateWidget(LazyLoadingGridView oldWidget) {
|
|
|
super.didUpdateWidget(oldWidget);
|
|
|
- if (!listEquals(widget.files, oldWidget.files)) {
|
|
|
+ if (!listEquals(widget.filesInDay, oldWidget.filesInDay)) {
|
|
|
_shouldRender = widget.shouldRender;
|
|
|
}
|
|
|
}
|
|
@@ -348,7 +352,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
},
|
|
|
child: _shouldRender
|
|
|
? _getGridView()
|
|
|
- : PlaceHolderWidget(widget.files.length),
|
|
|
+ : PlaceHolderWidget(widget.filesInDay.length),
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -363,7 +367,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
- child: PlaceHolderWidget(widget.files.length),
|
|
|
+ child: PlaceHolderWidget(widget.filesInDay.length),
|
|
|
);
|
|
|
} else {
|
|
|
return _getGridView();
|
|
@@ -376,10 +380,12 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
physics:
|
|
|
const NeverScrollableScrollPhysics(), // to disable GridView's scrolling
|
|
|
itemBuilder: (context, index) {
|
|
|
- return _buildFile(context, widget.files[index]);
|
|
|
+ return _buildFile(context, widget.filesInDay[index]);
|
|
|
},
|
|
|
- itemCount: widget.files.length,
|
|
|
+ itemCount: widget.filesInDay.length,
|
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
|
+ crossAxisSpacing: 2,
|
|
|
+ mainAxisSpacing: 2,
|
|
|
crossAxisCount: 4,
|
|
|
),
|
|
|
padding: const EdgeInsets.all(0),
|
|
@@ -399,47 +405,41 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
HapticFeedback.lightImpact();
|
|
|
_selectFile(file);
|
|
|
},
|
|
|
- child: Container(
|
|
|
- margin: const EdgeInsets.all(1.5),
|
|
|
- decoration: BoxDecoration(
|
|
|
- borderRadius: BorderRadius.circular(3),
|
|
|
- ),
|
|
|
- child: ClipRRect(
|
|
|
- borderRadius: BorderRadius.circular(3),
|
|
|
- child: Stack(
|
|
|
- children: [
|
|
|
- Hero(
|
|
|
- tag: widget.tag + file.tag,
|
|
|
- child: ColorFiltered(
|
|
|
- colorFilter: ColorFilter.mode(
|
|
|
- Colors.black.withOpacity(
|
|
|
- widget.selectedFiles.isFileSelected(file) ? 0.4 : 0,
|
|
|
- ),
|
|
|
- BlendMode.darken,
|
|
|
- ),
|
|
|
- child: ThumbnailWidget(
|
|
|
- file,
|
|
|
- diskLoadDeferDuration: thumbnailDiskLoadDeferDuration,
|
|
|
- serverLoadDeferDuration: thumbnailServerLoadDeferDuration,
|
|
|
- shouldShowLivePhotoOverlay: true,
|
|
|
- key: Key(widget.tag + file.tag),
|
|
|
+ child: ClipRRect(
|
|
|
+ borderRadius: BorderRadius.circular(1),
|
|
|
+ child: Stack(
|
|
|
+ children: [
|
|
|
+ Hero(
|
|
|
+ tag: widget.tag + file.tag,
|
|
|
+ child: ColorFiltered(
|
|
|
+ colorFilter: ColorFilter.mode(
|
|
|
+ Colors.black.withOpacity(
|
|
|
+ widget.selectedFiles.isFileSelected(file) ? 0.4 : 0,
|
|
|
),
|
|
|
+ BlendMode.darken,
|
|
|
+ ),
|
|
|
+ child: ThumbnailWidget(
|
|
|
+ file,
|
|
|
+ diskLoadDeferDuration: thumbnailDiskLoadDeferDuration,
|
|
|
+ serverLoadDeferDuration: thumbnailServerLoadDeferDuration,
|
|
|
+ shouldShowLivePhotoOverlay: true,
|
|
|
+ key: Key(widget.tag + file.tag),
|
|
|
),
|
|
|
),
|
|
|
- Visibility(
|
|
|
- visible: widget.selectedFiles.isFileSelected(file),
|
|
|
- child: const Positioned(
|
|
|
- right: 4,
|
|
|
- top: 4,
|
|
|
- child: Icon(
|
|
|
- Icons.check_circle_rounded,
|
|
|
- size: 20,
|
|
|
- color: Colors.white, //same for both themes
|
|
|
- ),
|
|
|
+ ),
|
|
|
+ Visibility(
|
|
|
+ visible: widget.selectedFiles.isFileSelected(file),
|
|
|
+ child: const Positioned(
|
|
|
+ right: 4,
|
|
|
+ top: 4,
|
|
|
+ child: Icon(
|
|
|
+ Icons.check_circle_rounded,
|
|
|
+ size: 20,
|
|
|
+ color: Colors.white, //same for both themes
|
|
|
),
|
|
|
- )
|
|
|
- ],
|
|
|
- ),
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ ],
|
|
|
),
|
|
|
),
|
|
|
);
|
|
@@ -452,9 +452,9 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
void _routeToDetailPage(File file, BuildContext context) {
|
|
|
final page = DetailPage(
|
|
|
DetailPageConfiguration(
|
|
|
- List.unmodifiable(widget.files),
|
|
|
+ List.unmodifiable(widget.filesInDay),
|
|
|
widget.asyncLoader,
|
|
|
- widget.files.indexOf(file),
|
|
|
+ widget.filesInDay.indexOf(file),
|
|
|
widget.tag,
|
|
|
),
|
|
|
);
|
|
@@ -462,8 +462,13 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
}
|
|
|
|
|
|
void _selectedFilesListener() {
|
|
|
+ if (widget.selectedFiles.files.containsAll(widget.filesInDay.toSet())) {
|
|
|
+ widget.areAllFilesSelected.value = true;
|
|
|
+ } else {
|
|
|
+ widget.areAllFilesSelected.value = false;
|
|
|
+ }
|
|
|
bool shouldRefresh = false;
|
|
|
- for (final file in widget.files) {
|
|
|
+ for (final file in widget.filesInDay) {
|
|
|
if (widget.selectedFiles.isPartOfLastSelected(file)) {
|
|
|
shouldRefresh = true;
|
|
|
}
|
|
@@ -473,17 +478,13 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- void _shouldSelectAllListener() {
|
|
|
- if (widget.shouldSelectAll.value && mounted) {
|
|
|
+ void _toggleSelectAllFromDayListener() {
|
|
|
+ if (widget.selectedFiles.files.containsAll(widget.filesInDay.toSet())) {
|
|
|
setState(() {
|
|
|
- widget.selectedFiles.selectAll(widget.files.toSet());
|
|
|
+ widget.selectedFiles.unSelectAll(widget.filesInDay.toSet());
|
|
|
});
|
|
|
} else {
|
|
|
- if (mounted) {
|
|
|
- setState(() {
|
|
|
- widget.selectedFiles.unSelectAll(widget.files.toSet());
|
|
|
- });
|
|
|
- }
|
|
|
+ widget.selectedFiles.selectAll(widget.filesInDay.toSet());
|
|
|
}
|
|
|
}
|
|
|
}
|