diff --git a/mobile/lib/modules/home/ui/asset_grid/daily_title_text.dart b/mobile/lib/modules/home/ui/asset_grid/daily_title_text.dart index e16bea2b30..6814cccb34 100644 --- a/mobile/lib/modules/home/ui/asset_grid/daily_title_text.dart +++ b/mobile/lib/modules/home/ui/asset_grid/daily_title_text.dart @@ -8,11 +8,17 @@ class DailyTitleText extends ConsumerWidget { const DailyTitleText({ Key? key, required this.isoDate, - required this.assetGroup, + required this.multiselectEnabled, + required this.onSelect, + required this.onDeselect, + required this.selected, }) : super(key: key); final String isoDate; - final List assetGroup; + final bool multiselectEnabled; + final Function onSelect; + final Function onDeselect; + final bool selected; @override Widget build(BuildContext context, WidgetRef ref) { @@ -23,51 +29,12 @@ class DailyTitleText extends ConsumerWidget { : "daily_title_text_date_year".tr(); var dateText = DateFormat(formatDateTemplate).format(DateTime.parse(isoDate)); - var isMultiSelectEnable = - ref.watch(homePageStateProvider).isMultiSelectEnable; - var selectedDateGroup = ref.watch(homePageStateProvider).selectedDateGroup; - var selectedItems = ref.watch(homePageStateProvider).selectedItems; - void _handleTitleIconClick() { - if (isMultiSelectEnable && - selectedDateGroup.contains(dateText) && - selectedDateGroup.length == 1 && - selectedItems.length <= assetGroup.length) { - // Multi select is active - click again on the icon while it is the only active group -> disable multi select - ref.watch(homePageStateProvider.notifier).disableMultiSelect(); - } else if (isMultiSelectEnable && - selectedDateGroup.contains(dateText) && - selectedItems.length != assetGroup.length) { - // Multi select is active - click again on the icon while it is not the only active group -> remove that group from selected group/items - ref - .watch(homePageStateProvider.notifier) - .removeSelectedDateGroup(dateText); - ref - .watch(homePageStateProvider.notifier) - .removeMultipleSelectedItem(assetGroup); - } else if (isMultiSelectEnable && - selectedDateGroup.contains(dateText) && - selectedDateGroup.length > 1) { - ref - .watch(homePageStateProvider.notifier) - .removeSelectedDateGroup(dateText); - ref - .watch(homePageStateProvider.notifier) - .removeMultipleSelectedItem(assetGroup); - } else if (isMultiSelectEnable && !selectedDateGroup.contains(dateText)) { - ref - .watch(homePageStateProvider.notifier) - .addSelectedDateGroup(dateText); - ref - .watch(homePageStateProvider.notifier) - .addMultipleSelectedItems(assetGroup); + void handleTitleIconClick() { + if (selected) { + onDeselect(); } else { - ref - .watch(homePageStateProvider.notifier) - .enableMultiSelect(assetGroup.toSet()); - ref - .watch(homePageStateProvider.notifier) - .addSelectedDateGroup(dateText); + onSelect(); } } @@ -89,8 +56,8 @@ class DailyTitleText extends ConsumerWidget { ), const Spacer(), GestureDetector( - onTap: _handleTitleIconClick, - child: isMultiSelectEnable && selectedDateGroup.contains(dateText) + onTap: handleTitleIconClick, + child: multiselectEnabled && selected ? Icon( Icons.check_circle_rounded, color: Theme.of(context).primaryColor, diff --git a/mobile/lib/modules/home/ui/disable_multi_select_button.dart b/mobile/lib/modules/home/ui/asset_grid/disable_multi_select_button.dart similarity index 83% rename from mobile/lib/modules/home/ui/disable_multi_select_button.dart rename to mobile/lib/modules/home/ui/asset_grid/disable_multi_select_button.dart index 2d450832eb..cca2e0b201 100644 --- a/mobile/lib/modules/home/ui/disable_multi_select_button.dart +++ b/mobile/lib/modules/home/ui/asset_grid/disable_multi_select_button.dart @@ -1,40 +1,36 @@ -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -class DisableMultiSelectButton extends ConsumerWidget { - const DisableMultiSelectButton({ - Key? key, - required this.onPressed, - required this.selectedItemCount, - }) : super(key: key); - - final Function onPressed; - final int selectedItemCount; - - @override - Widget build(BuildContext context, WidgetRef ref) { - return Positioned( - top: 10, - left: 0, - child: Padding( - padding: const EdgeInsets.only(left: 16.0, top: 46), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 4.0), - child: ElevatedButton.icon( - onPressed: () { - onPressed(); - }, - icon: const Icon(Icons.close_rounded), - label: Text( - '$selectedItemCount', - style: const TextStyle( - fontWeight: FontWeight.w600, - fontSize: 18, - ), - ), - ), - ), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; + +class DisableMultiSelectButton extends ConsumerWidget { + const DisableMultiSelectButton({ + Key? key, + required this.onPressed, + required this.selectedItemCount, + }) : super(key: key); + + final Function onPressed; + final int selectedItemCount; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Padding( + padding: const EdgeInsets.only(left: 16.0, top: 15), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 4.0), + child: ElevatedButton.icon( + onPressed: () { + onPressed(); + }, + icon: const Icon(Icons.close_rounded), + label: Text( + '$selectedItemCount', + style: const TextStyle( + fontWeight: FontWeight.w600, + fontSize: 18, + ), + ), + ), + ), + ); + } +} diff --git a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid.dart b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid.dart index 7ff4a78905..568f7ee57f 100644 --- a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid.dart +++ b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid.dart @@ -1,3 +1,4 @@ +import 'dart:collection'; import 'dart:math'; import 'package:collection/collection.dart'; @@ -5,35 +6,27 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/framework.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/home/ui/thumbnail_image.dart'; +import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart'; import 'package:openapi/api.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'asset_grid_data_structure.dart'; import 'daily_title_text.dart'; +import 'disable_multi_select_button.dart'; import 'draggable_scrollbar_custom.dart'; -class ImmichAssetGrid extends HookConsumerWidget { +typedef ImmichAssetGridSelectionListener = void Function(bool); + +class ImmichAssetGridState extends State { final ItemScrollController _itemScrollController = ItemScrollController(); final ItemPositionsListener _itemPositionsListener = - ItemPositionsListener.create(); + ItemPositionsListener.create(); - final List renderList; - final int assetsPerRow; - final double margin; - final bool showStorageIndicator; - - ImmichAssetGrid({ - super.key, - required this.renderList, - required this.assetsPerRow, - required this.showStorageIndicator, - this.margin = 5.0, - }); + bool _scrolling = false; + bool _multiselect = false; + Set _selectedAssets = HashSet(); List get _assets { - return renderList + return widget.renderList .map((e) { if (e.type == RenderAssetGridElementType.assetRow) { return e.assetRow!.assets; @@ -44,10 +37,49 @@ class ImmichAssetGrid extends HookConsumerWidget { .flattened .toList(); } + + void _selectAssets(List assets) { + setState(() { + + if (!_multiselect) { + _multiselect = true; + widget.listener?.call(true); + } + + for (var e in assets) { + _selectedAssets.add(e.id); + } + }); + } + + void _deselectAssets(List assets) { + setState(() { + for (var e in assets) { + _selectedAssets.remove(e.id); + } + + if (_selectedAssets.isEmpty) { + _multiselect = false; + widget.listener?.call(false); + } + }); + } + + void _deselectAll() { + setState(() { + _multiselect = false; + _selectedAssets.clear(); + }); + widget.listener?.call(false); + } + + bool _allAssetsSelected(List assets) { + return _multiselect && assets.firstWhereOrNull((e) => !_selectedAssets.contains(e.id)) == null; + } double _getItemSize(BuildContext context) { - return MediaQuery.of(context).size.width / assetsPerRow - - margin * (assetsPerRow - 1) / assetsPerRow; + return MediaQuery.of(context).size.width / widget.assetsPerRow - + widget.margin * (widget.assetsPerRow - 1) / widget.assetsPerRow; } Widget _buildThumbnailOrPlaceholder( @@ -60,7 +92,10 @@ class ImmichAssetGrid extends HookConsumerWidget { return ThumbnailImage( asset: asset, assetList: _assets, - showStorageIndicator: showStorageIndicator, + multiselectEnabled: _multiselect, + isSelected: _selectedAssets.contains(asset.id), + onSelect: () => _selectAssets([asset]), + onDeselect: () => _deselectAssets([asset]), useGrayBoxPlaceholder: true, ); } @@ -78,7 +113,7 @@ class ImmichAssetGrid extends HookConsumerWidget { key: Key("asset-${asset.id}"), width: size, height: size, - margin: EdgeInsets.only(top: margin, right: last ? 0.0 : margin), + margin: EdgeInsets.only(top: widget.margin, right: last ? 0.0 : widget.margin), child: _buildThumbnailOrPlaceholder(asset, scrolling), ); }).toList(), @@ -89,7 +124,10 @@ class ImmichAssetGrid extends HookConsumerWidget { BuildContext context, String title, List assets) { return DailyTitleText( isoDate: title, - assetGroup: assets, + multiselectEnabled: _multiselect, + onSelect: () => _selectAssets(assets), + onDeselect: () => _deselectAssets(assets), + selected: _allAssetsSelected(assets), ); } @@ -111,22 +149,22 @@ class ImmichAssetGrid extends HookConsumerWidget { ); } - Widget _itemBuilder(BuildContext c, int position, bool scrolling) { - final item = renderList[position]; + Widget _itemBuilder(BuildContext c, int position) { + final item = widget.renderList[position]; if (item.type == RenderAssetGridElementType.dayTitle) { return _buildTitle(c, item.title!, item.relatedAssetList!); } else if (item.type == RenderAssetGridElementType.monthTitle) { return _buildMonthTitle(c, item.title!); } else if (item.type == RenderAssetGridElementType.assetRow) { - return _buildAssetRow(c, item.assetRow!, scrolling); + return _buildAssetRow(c, item.assetRow!, _scrolling); } return const Text("Invalid widget type!"); } Text _labelBuilder(int pos) { - final date = renderList[pos].date; + final date = widget.renderList[pos].date; return Text(DateFormat.yMMMd().format(date), style: const TextStyle( color: Colors.white, @@ -135,26 +173,27 @@ class ImmichAssetGrid extends HookConsumerWidget { ); } + Widget _buildMultiSelectIndicator() { + return DisableMultiSelectButton( + onPressed: () => _deselectAll(), + selectedItemCount: _selectedAssets.length, + ); + } - @override - Widget build(BuildContext context, WidgetRef ref) { - final scrolling = useState(false); - + Widget _buildAssetGrid() { final useDragScrolling = _assets.length > 100; void dragScrolling(bool active) { - scrolling.value = active; - } - - Widget itemBuilder(BuildContext c, int position) { - return _itemBuilder(c, position, scrolling.value); + setState(() { + _scrolling = active; + }); } final listWidget = ScrollablePositionedList.builder( - itemBuilder: itemBuilder, + itemBuilder: _itemBuilder, itemPositionsListener: _itemPositionsListener, itemScrollController: _itemScrollController, - itemCount: renderList.length, + itemCount: widget.renderList.length, ); if (!useDragScrolling) { @@ -162,15 +201,48 @@ class ImmichAssetGrid extends HookConsumerWidget { } return DraggableScrollbar.semicircle( - scrollStateListener: dragScrolling, - itemPositionsListener: _itemPositionsListener, - controller: _itemScrollController, - backgroundColor: Theme.of(context).hintColor, - labelTextBuilder: _labelBuilder, - labelConstraints: const BoxConstraints(maxHeight: 28), - scrollbarAnimationDuration: const Duration(seconds: 1), - scrollbarTimeToFade: const Duration(seconds: 4), - child: listWidget, + scrollStateListener: dragScrolling, + itemPositionsListener: _itemPositionsListener, + controller: _itemScrollController, + backgroundColor: Theme.of(context).hintColor, + labelTextBuilder: _labelBuilder, + labelConstraints: const BoxConstraints(maxHeight: 28), + scrollbarAnimationDuration: const Duration(seconds: 1), + scrollbarTimeToFade: const Duration(seconds: 4), + child: listWidget, + ); + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + _buildAssetGrid(), + if (_multiselect) _buildMultiSelectIndicator(), + ], ); } } + +class ImmichAssetGrid extends StatefulWidget { + final List renderList; + final int assetsPerRow; + final double margin; + final bool showStorageIndicator; + final ImmichAssetGridSelectionListener? listener; + + + ImmichAssetGrid({ + super.key, + required this.renderList, + required this.assetsPerRow, + required this.showStorageIndicator, + this.listener, + this.margin = 5.0, + }); + + @override + State createState() { + return ImmichAssetGridState(); + } +} \ No newline at end of file diff --git a/mobile/lib/modules/home/ui/thumbnail_image.dart b/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart similarity index 80% rename from mobile/lib/modules/home/ui/thumbnail_image.dart rename to mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart index 1eb165f62f..13533942d2 100644 --- a/mobile/lib/modules/home/ui/thumbnail_image.dart +++ b/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart @@ -1,176 +1,174 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:hive_flutter/hive_flutter.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart'; -import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; -import 'package:immich_mobile/routing/router.dart'; -import 'package:immich_mobile/utils/image_url_builder.dart'; -import 'package:openapi/api.dart'; - -class ThumbnailImage extends HookConsumerWidget { - final AssetResponseDto asset; - final List assetList; - final bool showStorageIndicator; - final bool useGrayBoxPlaceholder; - - const ThumbnailImage({ - Key? key, - required this.asset, - required this.assetList, - this.showStorageIndicator = true, - this.useGrayBoxPlaceholder = false, - }) : super(key: key); - - @override - Widget build(BuildContext context, WidgetRef ref) { - var box = Hive.box(userInfoBox); - var thumbnailRequestUrl = getThumbnailUrl(asset); - var selectedAsset = ref.watch(homePageStateProvider).selectedItems; - var isMultiSelectEnable = - ref.watch(homePageStateProvider).isMultiSelectEnable; - var deviceId = ref.watch(authenticationProvider).deviceId; - - Widget buildSelectionIcon(AssetResponseDto asset) { - if (selectedAsset.contains(asset)) { - return Icon( - Icons.check_circle, - color: Theme.of(context).primaryColor, - ); - } else { - return const Icon( - Icons.circle_outlined, - color: Colors.white, - ); - } - } - - return GestureDetector( - onTap: () { - if (isMultiSelectEnable && - selectedAsset.contains(asset) && - selectedAsset.length == 1) { - ref.watch(homePageStateProvider.notifier).disableMultiSelect(); - } else if (isMultiSelectEnable && - selectedAsset.contains(asset) && - selectedAsset.length > 1) { - ref - .watch(homePageStateProvider.notifier) - .removeSingleSelectedItem(asset); - } else if (isMultiSelectEnable && !selectedAsset.contains(asset)) { - ref - .watch(homePageStateProvider.notifier) - .addSingleSelectedItem(asset); - } else { - AutoRouter.of(context).push( - GalleryViewerRoute( - assetList: assetList, - asset: asset, - ), - ); - } - }, - onLongPress: () { - // Enable multi select function - ref.watch(homePageStateProvider.notifier).enableMultiSelect({asset}); - HapticFeedback.heavyImpact(); - }, - child: Hero( - tag: asset.id, - child: Stack( - children: [ - Container( - decoration: BoxDecoration( - border: isMultiSelectEnable && selectedAsset.contains(asset) - ? Border.all( - color: Theme.of(context).primaryColorLight, - width: 10, - ) - : const Border(), - ), - child: CachedNetworkImage( - cacheKey: 'thumbnail-image-${asset.id}', - width: 300, - height: 300, - memCacheHeight: 200, - maxWidthDiskCache: 200, - maxHeightDiskCache: 200, - fit: BoxFit.cover, - imageUrl: thumbnailRequestUrl, - httpHeaders: { - "Authorization": "Bearer ${box.get(accessTokenKey)}" - }, - fadeInDuration: const Duration(milliseconds: 250), - progressIndicatorBuilder: (context, url, downloadProgress) { - if (useGrayBoxPlaceholder) { - return const DecoratedBox( - decoration: BoxDecoration(color: Colors.grey), - ); - } - return Transform.scale( - scale: 0.2, - child: CircularProgressIndicator( - value: downloadProgress.progress, - ), - ); - }, - errorWidget: (context, url, error) { - debugPrint("Error getting thumbnail $url = $error"); - CachedNetworkImage.evictFromCache(thumbnailRequestUrl); - - return Icon( - Icons.image_not_supported_outlined, - color: Theme.of(context).primaryColor, - ); - }, - ), - ), - if (isMultiSelectEnable) - Padding( - padding: const EdgeInsets.all(3.0), - child: Align( - alignment: Alignment.topLeft, - child: buildSelectionIcon(asset), - ), - ), - if (showStorageIndicator) - Positioned( - right: 10, - bottom: 5, - child: Icon( - (deviceId != asset.deviceId) - ? Icons.cloud_done_outlined - : Icons.photo_library_rounded, - color: Colors.white, - size: 18, - ), - ), - if (asset.type != AssetTypeEnum.IMAGE) - Positioned( - top: 5, - right: 5, - child: Row( - children: [ - Text( - asset.duration.toString().substring(0, 7), - style: const TextStyle( - color: Colors.white, - fontSize: 10, - ), - ), - const Icon( - Icons.play_circle_outline_rounded, - color: Colors.white, - ), - ], - ), - ), - ], - ), - ), - ); - } -} +import 'package:auto_route/auto_route.dart'; +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/constants/hive_box.dart'; +import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart'; +import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; +import 'package:immich_mobile/routing/router.dart'; +import 'package:immich_mobile/utils/image_url_builder.dart'; +import 'package:openapi/api.dart'; + +class ThumbnailImage extends HookConsumerWidget { + final AssetResponseDto asset; + final List assetList; + final bool showStorageIndicator; + final bool useGrayBoxPlaceholder; + final bool isSelected; + final bool multiselectEnabled; + final Function? onSelect; + final Function? onDeselect; + + const ThumbnailImage({ + Key? key, + required this.asset, + required this.assetList, + this.showStorageIndicator = true, + this.useGrayBoxPlaceholder = false, + this.isSelected = false, + this.multiselectEnabled = false, + this.onDeselect, + this.onSelect, + }) : super(key: key); + + @override + Widget build(BuildContext context, WidgetRef ref) { + var box = Hive.box(userInfoBox); + var thumbnailRequestUrl = getThumbnailUrl(asset); + var deviceId = ref.watch(authenticationProvider).deviceId; + + + Widget buildSelectionIcon(AssetResponseDto asset) { + if (isSelected) { + return Icon( + Icons.check_circle, + color: Theme.of(context).primaryColor, + ); + } else { + return const Icon( + Icons.circle_outlined, + color: Colors.white, + ); + } + } + + return GestureDetector( + onTap: () { + if (multiselectEnabled) { + if (isSelected) { + onDeselect?.call(); + } else { + onSelect?.call(); + } + } else { + AutoRouter.of(context).push( + GalleryViewerRoute( + assetList: assetList, + asset: asset, + ), + ); + } + }, + onLongPress: () { + onSelect?.call(); + HapticFeedback.heavyImpact(); + }, + child: Hero( + tag: asset.id, + child: Stack( + children: [ + Container( + decoration: BoxDecoration( + border: multiselectEnabled && isSelected + ? Border.all( + color: Theme.of(context).primaryColorLight, + width: 10, + ) + : const Border(), + ), + child: CachedNetworkImage( + cacheKey: 'thumbnail-image-${asset.id}', + width: 300, + height: 300, + memCacheHeight: 200, + maxWidthDiskCache: 200, + maxHeightDiskCache: 200, + fit: BoxFit.cover, + imageUrl: thumbnailRequestUrl, + httpHeaders: { + "Authorization": "Bearer ${box.get(accessTokenKey)}" + }, + fadeInDuration: const Duration(milliseconds: 250), + progressIndicatorBuilder: (context, url, downloadProgress) { + if (useGrayBoxPlaceholder) { + return const DecoratedBox( + decoration: BoxDecoration(color: Colors.grey), + ); + } + return Transform.scale( + scale: 0.2, + child: CircularProgressIndicator( + value: downloadProgress.progress, + ), + ); + }, + errorWidget: (context, url, error) { + debugPrint("Error getting thumbnail $url = $error"); + CachedNetworkImage.evictFromCache(thumbnailRequestUrl); + + return Icon( + Icons.image_not_supported_outlined, + color: Theme.of(context).primaryColor, + ); + }, + ), + ), + if (multiselectEnabled) + Padding( + padding: const EdgeInsets.all(3.0), + child: Align( + alignment: Alignment.topLeft, + child: buildSelectionIcon(asset), + ), + ), + if (showStorageIndicator) + Positioned( + right: 10, + bottom: 5, + child: Icon( + (deviceId != asset.deviceId) + ? Icons.cloud_done_outlined + : Icons.photo_library_rounded, + color: Colors.white, + size: 18, + ), + ), + if (asset.type != AssetTypeEnum.IMAGE) + Positioned( + top: 5, + right: 5, + child: Row( + children: [ + Text( + asset.duration.toString().substring(0, 7), + style: const TextStyle( + color: Colors.white, + fontSize: 10, + ), + ), + const Icon( + Icons.play_circle_outline_rounded, + color: Colors.white, + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/mobile/lib/modules/home/ui/image_grid.dart b/mobile/lib/modules/home/ui/image_grid.dart index f7efe613d2..7f0c6304ed 100644 --- a/mobile/lib/modules/home/ui/image_grid.dart +++ b/mobile/lib/modules/home/ui/image_grid.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/home/ui/thumbnail_image.dart'; +import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart'; import 'package:openapi/api.dart'; // ignore: must_be_immutable diff --git a/mobile/lib/modules/home/views/home_page.dart b/mobile/lib/modules/home/views/home_page.dart index ebfc55680f..500e30b08d 100644 --- a/mobile/lib/modules/home/views/home_page.dart +++ b/mobile/lib/modules/home/views/home_page.dart @@ -5,7 +5,6 @@ import 'package:immich_mobile/modules/home/providers/home_page_render_list_provi import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart'; import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart'; import 'package:immich_mobile/modules/home/ui/control_bottom_app_bar.dart'; -import 'package:immich_mobile/modules/home/ui/disable_multi_select_button.dart'; import 'package:immich_mobile/modules/home/ui/immich_sliver_appbar.dart'; import 'package:immich_mobile/modules/home/ui/profile_drawer/profile_drawer.dart'; import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; @@ -20,12 +19,9 @@ class HomePage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final appSettingService = ref.watch(appSettingsServiceProvider); - var renderList = ref.watch(renderListProvider); - var isMultiSelectEnable = - ref.watch(homePageStateProvider).isMultiSelectEnable; - var homePageState = ref.watch(homePageStateProvider); + final multiselectEnabled = useState(false); useEffect( () { @@ -41,16 +37,9 @@ class HomePage extends HookConsumerWidget { ref.read(assetProvider.notifier).getAllAsset(); } - buildSelectedItemCountIndicator() { - return DisableMultiSelectButton( - onPressed: ref.watch(homePageStateProvider.notifier).disableMultiSelect, - selectedItemCount: homePageState.selectedItems.length, - ); - } - Widget buildBody() { buildSliverAppBar() { - return isMultiSelectEnable + return multiselectEnabled.value ? const SliverToBoxAdapter( child: SizedBox( height: 70, @@ -62,9 +51,13 @@ class HomePage extends HookConsumerWidget { ); } + void selectionListener(bool multiselect) { + multiselectEnabled.value = multiselect; + } + return SafeArea( - bottom: !isMultiSelectEnable, - top: !isMultiSelectEnable, + bottom: !multiselectEnabled.value, + top: !multiselectEnabled.value, child: Stack( children: [ CustomScrollView( @@ -80,10 +73,10 @@ class HomePage extends HookConsumerWidget { appSettingService.getSetting(AppSettingsEnum.tilesPerRow), showStorageIndicator: appSettingService .getSetting(AppSettingsEnum.storageIndicator), + listener: selectionListener, ), ), - if (isMultiSelectEnable) ...[ - buildSelectedItemCountIndicator(), + if (multiselectEnabled.value) ...[ const ControlBottomAppBar(), ], ],