feat(mobile): unify asset grid multiselect actions (#5407)

* feat(mobile): unify asset grid multiselect actions

* add favorite & archive page

* show edit date&place on main photos screen

* Reposition exit button

* Sort favorite with the same order as other view

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
Fynn Petersen-Frey
2023-12-07 16:38:22 +01:00
committed by GitHub
parent b9a9a3956c
commit c25556bb08
26 changed files with 768 additions and 968 deletions

View File

@@ -1,34 +1,19 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/archive/providers/archive_asset_provider.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
import 'package:immich_mobile/utils/selection_handlers.dart';
import 'package:immich_mobile/modules/home/providers/multiselect.provider.dart';
import 'package:immich_mobile/shared/ui/asset_grid/multiselect_grid.dart';
class ArchivePage extends HookConsumerWidget {
const ArchivePage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final archivedAssets = ref.watch(archiveProvider);
final selectionEnabledHook = useState(false);
final selection = useState(<Asset>{});
final processing = useState(false);
void selectionListener(
bool multiselect,
Set<Asset> selectedAssets,
) {
selectionEnabledHook.value = multiselect;
selection.value = selectedAssets;
}
AppBar buildAppBar(String count) {
AppBar buildAppBar() {
final archivedAssets = ref.watch(archiveProvider);
final count = archivedAssets.value?.totalAssets.toString() ?? "?";
return AppBar(
leading: IconButton(
onPressed: () => context.autoPop(),
@@ -42,69 +27,14 @@ class ArchivePage extends HookConsumerWidget {
);
}
Widget buildBottomBar() {
return SafeArea(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 64,
child: Card(
child: ListTile(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
leading: const Icon(
Icons.unarchive_rounded,
),
title: Text(
'control_bottom_app_bar_unarchive'.tr(),
style: const TextStyle(fontSize: 14),
),
onTap: processing.value
? null
: () async {
processing.value = true;
try {
await handleArchiveAssets(
ref,
context,
selection.value.toList(),
shouldArchive: false,
);
} finally {
processing.value = false;
selectionEnabledHook.value = false;
}
},
),
),
),
),
);
}
return Scaffold(
appBar: archivedAssets.maybeWhen(
data: (data) => buildAppBar(data.totalAssets.toString()),
orElse: () => buildAppBar("?"),
),
body: archivedAssets.widgetWhen(
onData: (data) => data.isEmpty
? Center(
child: Text('archive_page_no_archived_assets'.tr()),
)
: Stack(
children: [
ImmichAssetGrid(
renderList: data,
listener: selectionListener,
selectionActive: selectionEnabledHook.value,
),
if (selectionEnabledHook.value) buildBottomBar(),
if (processing.value)
const Center(child: ImmichLoadingIndicator()),
],
),
appBar: ref.watch(multiselectProvider) ? null : buildAppBar(),
body: MultiselectGrid(
renderListProvider: archiveProvider,
unarchive: true,
archiveEnabled: true,
deleteEnabled: true,
editEnabled: true,
),
);
}