mirror of
https://github.com/immich-app/immich.git
synced 2025-01-19 18:26:46 +01:00
Get rid of home page state provider
This commit is contained in:
parent
a117e897ca
commit
6b84534632
12 changed files with 72 additions and 354 deletions
|
@ -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,12 +14,13 @@ 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();
|
||||||
final ItemPositionsListener _itemPositionsListener =
|
final ItemPositionsListener _itemPositionsListener =
|
||||||
ItemPositionsListener.create();
|
ItemPositionsListener.create();
|
||||||
|
|
||||||
bool _scrolling = false;
|
bool _scrolling = false;
|
||||||
bool _multiselect = false;
|
bool _multiselect = false;
|
||||||
|
@ -37,18 +38,26 @@ class ImmichAssetGridState extends State<ImmichAssetGrid> {
|
||||||
.flattened
|
.flattened
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<AssetResponseDto> _getSelectedAssets() {
|
||||||
|
return _selectedAssets
|
||||||
|
.map((e) => _assets.firstWhereOrNull((a) => a.id == e))
|
||||||
|
.whereNotNull()
|
||||||
|
.toSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _callSelectionListener() {
|
||||||
|
widget.listener?.call(_multiselect, _getSelectedAssets());
|
||||||
|
}
|
||||||
|
|
||||||
void _selectAssets(List<AssetResponseDto> assets) {
|
void _selectAssets(List<AssetResponseDto> assets) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
||||||
if (!_multiselect) {
|
|
||||||
_multiselect = true;
|
|
||||||
widget.listener?.call(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
||||||
|
@ -245,4 +258,4 @@ class ImmichAssetGrid extends StatefulWidget {
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
return ImmichAssetGridState();
|
return ImmichAssetGridState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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…
Reference in a new issue