mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:39:37 -05:00 
			
		
		
		
	Get rid of home page state provider
This commit is contained in:
		
							parent
							
								
									a117e897ca
								
							
						
					
					
						commit
						6b84534632
					
				@ -1,47 +0,0 @@
 | 
				
			|||||||
import 'package:collection/collection.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:openapi/api.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class HomePageState {
 | 
					 | 
				
			||||||
  final bool isMultiSelectEnable;
 | 
					 | 
				
			||||||
  final Set<AssetResponseDto> selectedItems;
 | 
					 | 
				
			||||||
  final Set<String> selectedDateGroup;
 | 
					 | 
				
			||||||
  HomePageState({
 | 
					 | 
				
			||||||
    required this.isMultiSelectEnable,
 | 
					 | 
				
			||||||
    required this.selectedItems,
 | 
					 | 
				
			||||||
    required this.selectedDateGroup,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  HomePageState copyWith({
 | 
					 | 
				
			||||||
    bool? isMultiSelectEnable,
 | 
					 | 
				
			||||||
    Set<AssetResponseDto>? selectedItems,
 | 
					 | 
				
			||||||
    Set<String>? selectedDateGroup,
 | 
					 | 
				
			||||||
  }) {
 | 
					 | 
				
			||||||
    return HomePageState(
 | 
					 | 
				
			||||||
      isMultiSelectEnable: isMultiSelectEnable ?? this.isMultiSelectEnable,
 | 
					 | 
				
			||||||
      selectedItems: selectedItems ?? this.selectedItems,
 | 
					 | 
				
			||||||
      selectedDateGroup: selectedDateGroup ?? this.selectedDateGroup,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  String toString() =>
 | 
					 | 
				
			||||||
      'HomePageState(isMultiSelectEnable: $isMultiSelectEnable, selectedItems: $selectedItems, selectedDateGroup: $selectedDateGroup)';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  bool operator ==(Object other) {
 | 
					 | 
				
			||||||
    if (identical(this, other)) return true;
 | 
					 | 
				
			||||||
    final setEquals = const DeepCollectionEquality().equals;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return other is HomePageState &&
 | 
					 | 
				
			||||||
        other.isMultiSelectEnable == isMultiSelectEnable &&
 | 
					 | 
				
			||||||
        setEquals(other.selectedItems, selectedItems) &&
 | 
					 | 
				
			||||||
        setEquals(other.selectedDateGroup, selectedDateGroup);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  int get hashCode =>
 | 
					 | 
				
			||||||
      isMultiSelectEnable.hashCode ^
 | 
					 | 
				
			||||||
      selectedItems.hashCode ^
 | 
					 | 
				
			||||||
      selectedDateGroup.hashCode;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,91 +0,0 @@
 | 
				
			|||||||
import 'package:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					 | 
				
			||||||
import 'package:immich_mobile/modules/home/models/home_page_state.model.dart';
 | 
					 | 
				
			||||||
import 'package:immich_mobile/shared/services/share.service.dart';
 | 
					 | 
				
			||||||
import 'package:immich_mobile/shared/ui/share_dialog.dart';
 | 
					 | 
				
			||||||
import 'package:openapi/api.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class HomePageStateNotifier extends StateNotifier<HomePageState> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final ShareService _shareService;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  HomePageStateNotifier(this._shareService)
 | 
					 | 
				
			||||||
      : super(
 | 
					 | 
				
			||||||
          HomePageState(
 | 
					 | 
				
			||||||
            isMultiSelectEnable: false,
 | 
					 | 
				
			||||||
            selectedItems: {},
 | 
					 | 
				
			||||||
            selectedDateGroup: {},
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void addSelectedDateGroup(String dateGroupTitle) {
 | 
					 | 
				
			||||||
    state = state.copyWith(
 | 
					 | 
				
			||||||
      selectedDateGroup: {...state.selectedDateGroup, dateGroupTitle},
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void removeSelectedDateGroup(String dateGroupTitle) {
 | 
					 | 
				
			||||||
    var currentDateGroup = state.selectedDateGroup;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    currentDateGroup.removeWhere((e) => e == dateGroupTitle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    state = state.copyWith(selectedDateGroup: currentDateGroup);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void enableMultiSelect(Set<AssetResponseDto> selectedItems) {
 | 
					 | 
				
			||||||
    state =
 | 
					 | 
				
			||||||
        state.copyWith(isMultiSelectEnable: true, selectedItems: selectedItems);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void disableMultiSelect() {
 | 
					 | 
				
			||||||
    state = state.copyWith(
 | 
					 | 
				
			||||||
      isMultiSelectEnable: false,
 | 
					 | 
				
			||||||
      selectedItems: {},
 | 
					 | 
				
			||||||
      selectedDateGroup: {},
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void addSingleSelectedItem(AssetResponseDto asset) {
 | 
					 | 
				
			||||||
    state = state.copyWith(selectedItems: {...state.selectedItems, asset});
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void addMultipleSelectedItems(List<AssetResponseDto> assets) {
 | 
					 | 
				
			||||||
    state = state.copyWith(selectedItems: {...state.selectedItems, ...assets});
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void removeSingleSelectedItem(AssetResponseDto asset) {
 | 
					 | 
				
			||||||
    Set<AssetResponseDto> currentList = state.selectedItems;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    currentList.removeWhere((e) => e.id == asset.id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    state = state.copyWith(selectedItems: currentList);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void removeMultipleSelectedItem(List<AssetResponseDto> assets) {
 | 
					 | 
				
			||||||
    Set<AssetResponseDto> currentList = state.selectedItems;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (AssetResponseDto asset in assets) {
 | 
					 | 
				
			||||||
      currentList.removeWhere((e) => e.id == asset.id);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    state = state.copyWith(selectedItems: currentList);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void shareAssets(List<AssetResponseDto> assets, BuildContext context) {
 | 
					 | 
				
			||||||
    showDialog(
 | 
					 | 
				
			||||||
      context: context,
 | 
					 | 
				
			||||||
      builder: (BuildContext buildContext) {
 | 
					 | 
				
			||||||
        _shareService
 | 
					 | 
				
			||||||
            .shareAssets(assets)
 | 
					 | 
				
			||||||
            .then((_) => Navigator.of(buildContext).pop());
 | 
					 | 
				
			||||||
        return const ShareDialog();
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      barrierDismissible: false,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
final homePageStateProvider =
 | 
					 | 
				
			||||||
    StateNotifierProvider<HomePageStateNotifier, HomePageState>(
 | 
					 | 
				
			||||||
  ((ref) => HomePageStateNotifier(ref.watch(shareServiceProvider))),
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
@ -1,8 +1,6 @@
 | 
				
			|||||||
import 'package:easy_localization/easy_localization.dart';
 | 
					import 'package:easy_localization/easy_localization.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart';
 | 
					 | 
				
			||||||
import 'package:openapi/api.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DailyTitleText extends ConsumerWidget {
 | 
					class DailyTitleText extends ConsumerWidget {
 | 
				
			||||||
  const DailyTitleText({
 | 
					  const DailyTitleText({
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,8 @@ import 'daily_title_text.dart';
 | 
				
			|||||||
import 'disable_multi_select_button.dart';
 | 
					import 'disable_multi_select_button.dart';
 | 
				
			||||||
import 'draggable_scrollbar_custom.dart';
 | 
					import 'draggable_scrollbar_custom.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef ImmichAssetGridSelectionListener = void Function(bool);
 | 
					typedef ImmichAssetGridSelectionListener = void Function(
 | 
				
			||||||
 | 
					    bool, Set<AssetResponseDto>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ImmichAssetGridState extends State<ImmichAssetGrid> {
 | 
					class ImmichAssetGridState extends State<ImmichAssetGrid> {
 | 
				
			||||||
  final ItemScrollController _itemScrollController = ItemScrollController();
 | 
					  final ItemScrollController _itemScrollController = ItemScrollController();
 | 
				
			||||||
@ -38,17 +39,25 @@ class ImmichAssetGridState extends State<ImmichAssetGrid> {
 | 
				
			|||||||
        .toList();
 | 
					        .toList();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void _selectAssets(List<AssetResponseDto> assets) {
 | 
					  Set<AssetResponseDto> _getSelectedAssets() {
 | 
				
			||||||
    setState(() {
 | 
					    return _selectedAssets
 | 
				
			||||||
 | 
					        .map((e) => _assets.firstWhereOrNull((a) => a.id == e))
 | 
				
			||||||
      if (!_multiselect) {
 | 
					        .whereNotNull()
 | 
				
			||||||
        _multiselect = true;
 | 
					        .toSet();
 | 
				
			||||||
        widget.listener?.call(true);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _callSelectionListener() {
 | 
				
			||||||
 | 
					    widget.listener?.call(_multiselect, _getSelectedAssets());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _selectAssets(List<AssetResponseDto> assets) {
 | 
				
			||||||
 | 
					    setState(() {
 | 
				
			||||||
      for (var e in assets) {
 | 
					      for (var e in assets) {
 | 
				
			||||||
        _selectedAssets.add(e.id);
 | 
					        _selectedAssets.add(e.id);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      _multiselect = true;
 | 
				
			||||||
 | 
					      _callSelectionListener();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,8 +69,9 @@ class ImmichAssetGridState extends State<ImmichAssetGrid> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      if (_selectedAssets.isEmpty) {
 | 
					      if (_selectedAssets.isEmpty) {
 | 
				
			||||||
        _multiselect = false;
 | 
					        _multiselect = false;
 | 
				
			||||||
        widget.listener?.call(false);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      _callSelectionListener();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -70,11 +80,13 @@ class ImmichAssetGridState extends State<ImmichAssetGrid> {
 | 
				
			|||||||
      _multiselect = false;
 | 
					      _multiselect = false;
 | 
				
			||||||
      _selectedAssets.clear();
 | 
					      _selectedAssets.clear();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    widget.listener?.call(false);
 | 
					
 | 
				
			||||||
 | 
					    _callSelectionListener();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool _allAssetsSelected(List<AssetResponseDto> assets) {
 | 
					  bool _allAssetsSelected(List<AssetResponseDto> assets) {
 | 
				
			||||||
    return _multiselect && assets.firstWhereOrNull((e) => !_selectedAssets.contains(e.id)) == null;
 | 
					    return _multiselect &&
 | 
				
			||||||
 | 
					        assets.firstWhereOrNull((e) => !_selectedAssets.contains(e.id)) == null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  double _getItemSize(BuildContext context) {
 | 
					  double _getItemSize(BuildContext context) {
 | 
				
			||||||
@ -113,7 +125,8 @@ class ImmichAssetGridState extends State<ImmichAssetGrid> {
 | 
				
			|||||||
          key: Key("asset-${asset.id}"),
 | 
					          key: Key("asset-${asset.id}"),
 | 
				
			||||||
          width: size,
 | 
					          width: size,
 | 
				
			||||||
          height: size,
 | 
					          height: size,
 | 
				
			||||||
          margin: EdgeInsets.only(top: widget.margin, right: last ? 0.0 : widget.margin),
 | 
					          margin: EdgeInsets.only(
 | 
				
			||||||
 | 
					              top: widget.margin, right: last ? 0.0 : widget.margin),
 | 
				
			||||||
          child: _buildThumbnailOrPlaceholder(asset, scrolling),
 | 
					          child: _buildThumbnailOrPlaceholder(asset, scrolling),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      }).toList(),
 | 
					      }).toList(),
 | 
				
			||||||
@ -165,7 +178,8 @@ class ImmichAssetGridState extends State<ImmichAssetGrid> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Text _labelBuilder(int pos) {
 | 
					  Text _labelBuilder(int pos) {
 | 
				
			||||||
    final date = widget.renderList[pos].date;
 | 
					    final date = widget.renderList[pos].date;
 | 
				
			||||||
    return Text(DateFormat.yMMMd().format(date),
 | 
					    return Text(
 | 
				
			||||||
 | 
					      DateFormat.yMMMd().format(date),
 | 
				
			||||||
      style: const TextStyle(
 | 
					      style: const TextStyle(
 | 
				
			||||||
        color: Colors.white,
 | 
					        color: Colors.white,
 | 
				
			||||||
        fontWeight: FontWeight.bold,
 | 
					        fontWeight: FontWeight.bold,
 | 
				
			||||||
@ -231,7 +245,6 @@ class ImmichAssetGrid extends StatefulWidget {
 | 
				
			|||||||
  final bool showStorageIndicator;
 | 
					  final bool showStorageIndicator;
 | 
				
			||||||
  final ImmichAssetGridSelectionListener? listener;
 | 
					  final ImmichAssetGridSelectionListener? listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  ImmichAssetGrid({
 | 
					  ImmichAssetGrid({
 | 
				
			||||||
    super.key,
 | 
					    super.key,
 | 
				
			||||||
    required this.renderList,
 | 
					    required this.renderList,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,10 @@
 | 
				
			|||||||
import 'package:auto_route/auto_route.dart';
 | 
					import 'package:auto_route/auto_route.dart';
 | 
				
			||||||
import 'package:cached_network_image/cached_network_image.dart';
 | 
					import 'package:cached_network_image/cached_network_image.dart';
 | 
				
			||||||
import 'package:collection/collection.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:flutter/services.dart';
 | 
					import 'package:flutter/services.dart';
 | 
				
			||||||
import 'package:hive_flutter/hive_flutter.dart';
 | 
					import 'package:hive_flutter/hive_flutter.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:immich_mobile/constants/hive_box.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/modules/login/providers/authentication.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/routing/router.dart';
 | 
					import 'package:immich_mobile/routing/router.dart';
 | 
				
			||||||
import 'package:immich_mobile/utils/image_url_builder.dart';
 | 
					import 'package:immich_mobile/utils/image_url_builder.dart';
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,15 @@
 | 
				
			|||||||
import 'package:easy_localization/easy_localization.dart';
 | 
					import 'package:easy_localization/easy_localization.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart';
 | 
					 | 
				
			||||||
import 'package:immich_mobile/modules/home/ui/delete_diaglog.dart';
 | 
					import 'package:immich_mobile/modules/home/ui/delete_diaglog.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ControlBottomAppBar extends ConsumerWidget {
 | 
					class ControlBottomAppBar extends ConsumerWidget {
 | 
				
			||||||
  const ControlBottomAppBar({Key? key}) : super(key: key);
 | 
					  final Function onShare;
 | 
				
			||||||
 | 
					  final Function onDelete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const ControlBottomAppBar(
 | 
				
			||||||
 | 
					      {Key? key, required this.onShare, required this.onDelete})
 | 
				
			||||||
 | 
					      : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					  Widget build(BuildContext context, WidgetRef ref) {
 | 
				
			||||||
@ -36,7 +40,9 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
				
			|||||||
                      showDialog(
 | 
					                      showDialog(
 | 
				
			||||||
                        context: context,
 | 
					                        context: context,
 | 
				
			||||||
                        builder: (BuildContext context) {
 | 
					                        builder: (BuildContext context) {
 | 
				
			||||||
                          return const DeleteDialog();
 | 
					                          return DeleteDialog(
 | 
				
			||||||
 | 
					                            onDelete: onDelete,
 | 
				
			||||||
 | 
					                          );
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                      );
 | 
					                      );
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
@ -45,14 +51,7 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
				
			|||||||
                    iconData: Icons.share,
 | 
					                    iconData: Icons.share,
 | 
				
			||||||
                    label: "control_bottom_app_bar_share".tr(),
 | 
					                    label: "control_bottom_app_bar_share".tr(),
 | 
				
			||||||
                    onPressed: () {
 | 
					                    onPressed: () {
 | 
				
			||||||
                      final homePageState = ref.watch(homePageStateProvider);
 | 
					                      onShare();
 | 
				
			||||||
                      ref.watch(homePageStateProvider.notifier).shareAssets(
 | 
					 | 
				
			||||||
                            homePageState.selectedItems.toList(),
 | 
					 | 
				
			||||||
                            context,
 | 
					 | 
				
			||||||
                          );
 | 
					 | 
				
			||||||
                      ref
 | 
					 | 
				
			||||||
                          .watch(homePageStateProvider.notifier)
 | 
					 | 
				
			||||||
                          .disableMultiSelect();
 | 
					 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                  ),
 | 
					                  ),
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
 | 
				
			|||||||
@ -1,109 +0,0 @@
 | 
				
			|||||||
import 'package:easy_localization/easy_localization.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					 | 
				
			||||||
import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart';
 | 
					 | 
				
			||||||
import 'package:openapi/api.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DailyTitleText extends ConsumerWidget {
 | 
					 | 
				
			||||||
  const DailyTitleText({
 | 
					 | 
				
			||||||
    Key? key,
 | 
					 | 
				
			||||||
    required this.isoDate,
 | 
					 | 
				
			||||||
    required this.assetGroup,
 | 
					 | 
				
			||||||
  }) : super(key: key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final String isoDate;
 | 
					 | 
				
			||||||
  final List<AssetResponseDto> assetGroup;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					 | 
				
			||||||
    var currentYear = DateTime.now().year;
 | 
					 | 
				
			||||||
    var groupYear = DateTime.parse(isoDate).year;
 | 
					 | 
				
			||||||
    var formatDateTemplate = currentYear == groupYear
 | 
					 | 
				
			||||||
        ? "daily_title_text_date".tr()
 | 
					 | 
				
			||||||
        : "daily_title_text_date_year".tr();
 | 
					 | 
				
			||||||
    var dateText = DateFormat(formatDateTemplate)
 | 
					 | 
				
			||||||
        .format(DateTime.parse(isoDate).toLocal());
 | 
					 | 
				
			||||||
    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);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        ref
 | 
					 | 
				
			||||||
            .watch(homePageStateProvider.notifier)
 | 
					 | 
				
			||||||
            .enableMultiSelect(assetGroup.toSet());
 | 
					 | 
				
			||||||
        ref
 | 
					 | 
				
			||||||
            .watch(homePageStateProvider.notifier)
 | 
					 | 
				
			||||||
            .addSelectedDateGroup(dateText);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return SliverToBoxAdapter(
 | 
					 | 
				
			||||||
      child: Padding(
 | 
					 | 
				
			||||||
        padding: const EdgeInsets.only(
 | 
					 | 
				
			||||||
          top: 29.0,
 | 
					 | 
				
			||||||
          bottom: 29.0,
 | 
					 | 
				
			||||||
          left: 12.0,
 | 
					 | 
				
			||||||
          right: 12.0,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        child: Row(
 | 
					 | 
				
			||||||
          children: [
 | 
					 | 
				
			||||||
            Text(
 | 
					 | 
				
			||||||
              dateText,
 | 
					 | 
				
			||||||
              style: const TextStyle(
 | 
					 | 
				
			||||||
                fontSize: 14,
 | 
					 | 
				
			||||||
                fontWeight: FontWeight.bold,
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            const Spacer(),
 | 
					 | 
				
			||||||
            GestureDetector(
 | 
					 | 
				
			||||||
              onTap: _handleTitleIconClick,
 | 
					 | 
				
			||||||
              child: isMultiSelectEnable && selectedDateGroup.contains(dateText)
 | 
					 | 
				
			||||||
                  ? Icon(
 | 
					 | 
				
			||||||
                      Icons.check_circle_rounded,
 | 
					 | 
				
			||||||
                      color: Theme.of(context).primaryColor,
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                  : const Icon(
 | 
					 | 
				
			||||||
                      Icons.check_circle_outline_rounded,
 | 
					 | 
				
			||||||
                      color: Colors.grey,
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,15 +1,14 @@
 | 
				
			|||||||
import 'package:easy_localization/easy_localization.dart';
 | 
					import 'package:easy_localization/easy_localization.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:immich_mobile/shared/providers/asset.provider.dart';
 | 
					 | 
				
			||||||
import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DeleteDialog extends ConsumerWidget {
 | 
					class DeleteDialog extends ConsumerWidget {
 | 
				
			||||||
  const DeleteDialog({Key? key}) : super(key: key);
 | 
					  final Function onDelete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const DeleteDialog({Key? key, required this.onDelete}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					  Widget build(BuildContext context, WidgetRef ref) {
 | 
				
			||||||
    final homePageState = ref.watch(homePageStateProvider);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return AlertDialog(
 | 
					    return AlertDialog(
 | 
				
			||||||
      backgroundColor: Colors.grey[200],
 | 
					      backgroundColor: Colors.grey[200],
 | 
				
			||||||
@ -28,11 +27,7 @@ class DeleteDialog extends ConsumerWidget {
 | 
				
			|||||||
        ),
 | 
					        ),
 | 
				
			||||||
        TextButton(
 | 
					        TextButton(
 | 
				
			||||||
          onPressed: () {
 | 
					          onPressed: () {
 | 
				
			||||||
            ref
 | 
					            onDelete();
 | 
				
			||||||
                .watch(assetProvider.notifier)
 | 
					 | 
				
			||||||
                .deleteAssets(homePageState.selectedItems);
 | 
					 | 
				
			||||||
            ref.watch(homePageStateProvider.notifier).disableMultiSelect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Navigator.of(context).pop();
 | 
					            Navigator.of(context).pop();
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          child: Text(
 | 
					          child: Text(
 | 
				
			||||||
 | 
				
			|||||||
@ -1,47 +0,0 @@
 | 
				
			|||||||
import 'package:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					 | 
				
			||||||
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart';
 | 
					 | 
				
			||||||
import 'package:openapi/api.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ignore: must_be_immutable
 | 
					 | 
				
			||||||
class ImageGrid extends ConsumerWidget {
 | 
					 | 
				
			||||||
  final List<AssetResponseDto> assetGroup;
 | 
					 | 
				
			||||||
  final List<AssetResponseDto> sortedAssetGroup;
 | 
					 | 
				
			||||||
  final int tilesPerRow;
 | 
					 | 
				
			||||||
  final bool showStorageIndicator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ImageGrid({
 | 
					 | 
				
			||||||
    Key? key,
 | 
					 | 
				
			||||||
    required this.assetGroup,
 | 
					 | 
				
			||||||
    required this.sortedAssetGroup,
 | 
					 | 
				
			||||||
    this.tilesPerRow = 4,
 | 
					 | 
				
			||||||
    this.showStorageIndicator = true,
 | 
					 | 
				
			||||||
  }) : super(key: key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  List<AssetResponseDto> imageSortedList = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					 | 
				
			||||||
    return SliverGrid(
 | 
					 | 
				
			||||||
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
 | 
					 | 
				
			||||||
        crossAxisCount: tilesPerRow,
 | 
					 | 
				
			||||||
        crossAxisSpacing: 5.0,
 | 
					 | 
				
			||||||
        mainAxisSpacing: 5,
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
      delegate: SliverChildBuilderDelegate(
 | 
					 | 
				
			||||||
        (BuildContext context, int index) {
 | 
					 | 
				
			||||||
          var assetType = assetGroup[index].type;
 | 
					 | 
				
			||||||
          return GestureDetector(
 | 
					 | 
				
			||||||
            onTap: () {},
 | 
					 | 
				
			||||||
            child: ThumbnailImage(
 | 
					 | 
				
			||||||
              asset: assetGroup[index],
 | 
					 | 
				
			||||||
              assetList: sortedAssetGroup,
 | 
					 | 
				
			||||||
              showStorageIndicator: showStorageIndicator,
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        childCount: assetGroup.length,
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
 | 
					import 'package:flutter_hooks/flutter_hooks.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/home/providers/home_page_render_list_provider.dart';
 | 
					import 'package:immich_mobile/modules/home/providers/home_page_render_list_provider.dart';
 | 
				
			||||||
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/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/control_bottom_app_bar.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/home/ui/immich_sliver_appbar.dart';
 | 
					import 'package:immich_mobile/modules/home/ui/immich_sliver_appbar.dart';
 | 
				
			||||||
@ -12,6 +11,8 @@ import 'package:immich_mobile/modules/settings/services/app_settings.service.dar
 | 
				
			|||||||
import 'package:immich_mobile/shared/providers/asset.provider.dart';
 | 
					import 'package:immich_mobile/shared/providers/asset.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
 | 
					import 'package:immich_mobile/shared/providers/server_info.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
 | 
					import 'package:immich_mobile/shared/providers/websocket.provider.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/shared/services/share.service.dart';
 | 
				
			||||||
 | 
					import 'package:openapi/api.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HomePage extends HookConsumerWidget {
 | 
					class HomePage extends HookConsumerWidget {
 | 
				
			||||||
  const HomePage({Key? key}) : super(key: key);
 | 
					  const HomePage({Key? key}) : super(key: key);
 | 
				
			||||||
@ -22,6 +23,7 @@ class HomePage extends HookConsumerWidget {
 | 
				
			|||||||
    var renderList = ref.watch(renderListProvider);
 | 
					    var renderList = ref.watch(renderListProvider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final multiselectEnabled = useState(false);
 | 
					    final multiselectEnabled = useState(false);
 | 
				
			||||||
 | 
					    final selection = useState(<AssetResponseDto>{});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    useEffect(
 | 
					    useEffect(
 | 
				
			||||||
      () {
 | 
					      () {
 | 
				
			||||||
@ -38,21 +40,18 @@ class HomePage extends HookConsumerWidget {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Widget buildBody() {
 | 
					    Widget buildBody() {
 | 
				
			||||||
      buildSliverAppBar() {
 | 
					      void selectionListener(
 | 
				
			||||||
        return multiselectEnabled.value
 | 
					          bool multiselect, Set<AssetResponseDto> selectedAssets) {
 | 
				
			||||||
            ? const SliverToBoxAdapter(
 | 
					        multiselectEnabled.value = multiselect;
 | 
				
			||||||
                child: SizedBox(
 | 
					        selection.value = selectedAssets;
 | 
				
			||||||
                  height: 70,
 | 
					 | 
				
			||||||
                  child: null,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            : ImmichSliverAppBar(
 | 
					 | 
				
			||||||
                onPopBack: reloadAllAsset,
 | 
					 | 
				
			||||||
              );
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      void selectionListener(bool multiselect) {
 | 
					      void onShareAssets() {
 | 
				
			||||||
        multiselectEnabled.value = multiselect;
 | 
					        ref.watch(shareServiceProvider).shareAssets(selection.value.toList());
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      void onDelete() {
 | 
				
			||||||
 | 
					        ref.watch(assetProvider.notifier).deleteAssets(selection.value);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return SafeArea(
 | 
					      return SafeArea(
 | 
				
			||||||
@ -62,7 +61,16 @@ class HomePage extends HookConsumerWidget {
 | 
				
			|||||||
          children: [
 | 
					          children: [
 | 
				
			||||||
            CustomScrollView(
 | 
					            CustomScrollView(
 | 
				
			||||||
              slivers: [
 | 
					              slivers: [
 | 
				
			||||||
                buildSliverAppBar(),
 | 
					                multiselectEnabled.value
 | 
				
			||||||
 | 
					                    ? const SliverToBoxAdapter(
 | 
				
			||||||
 | 
					                        child: SizedBox(
 | 
				
			||||||
 | 
					                          height: 70,
 | 
				
			||||||
 | 
					                          child: null,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                      )
 | 
				
			||||||
 | 
					                    : ImmichSliverAppBar(
 | 
				
			||||||
 | 
					                        onPopBack: reloadAllAsset,
 | 
				
			||||||
 | 
					                      ),
 | 
				
			||||||
              ],
 | 
					              ],
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            Padding(
 | 
					            Padding(
 | 
				
			||||||
@ -77,7 +85,10 @@ class HomePage extends HookConsumerWidget {
 | 
				
			|||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            if (multiselectEnabled.value) ...[
 | 
					            if (multiselectEnabled.value) ...[
 | 
				
			||||||
              const ControlBottomAppBar(),
 | 
					              ControlBottomAppBar(
 | 
				
			||||||
 | 
					                onShare: onShareAssets,
 | 
				
			||||||
 | 
					                onDelete: onDelete,
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
import 'package:auto_route/auto_route.dart';
 | 
					import 'package:auto_route/auto_route.dart';
 | 
				
			||||||
import 'package:easy_localization/easy_localization.dart';
 | 
					import 'package:easy_localization/easy_localization.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_hooks/flutter_hooks.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart';
 | 
					 | 
				
			||||||
import 'package:immich_mobile/routing/router.dart';
 | 
					import 'package:immich_mobile/routing/router.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TabControllerPage extends ConsumerWidget {
 | 
					class TabControllerPage extends ConsumerWidget {
 | 
				
			||||||
@ -10,8 +10,6 @@ class TabControllerPage extends ConsumerWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					  Widget build(BuildContext context, WidgetRef ref) {
 | 
				
			||||||
    var isMultiSelectEnable =
 | 
					 | 
				
			||||||
        ref.watch(homePageStateProvider).isMultiSelectEnable;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return AutoTabsRouter(
 | 
					    return AutoTabsRouter(
 | 
				
			||||||
      routes: [
 | 
					      routes: [
 | 
				
			||||||
@ -32,7 +30,7 @@ class TabControllerPage extends ConsumerWidget {
 | 
				
			|||||||
              opacity: animation,
 | 
					              opacity: animation,
 | 
				
			||||||
              child: child,
 | 
					              child: child,
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            bottomNavigationBar: isMultiSelectEnable
 | 
					            bottomNavigationBar: false
 | 
				
			||||||
                ? null
 | 
					                ? null
 | 
				
			||||||
                : BottomNavigationBar(
 | 
					                : BottomNavigationBar(
 | 
				
			||||||
                    selectedLabelStyle: const TextStyle(
 | 
					                    selectedLabelStyle: const TextStyle(
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user