archive_page.dart 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import 'package:auto_route/auto_route.dart';
  2. import 'package:easy_localization/easy_localization.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_hooks/flutter_hooks.dart';
  5. import 'package:hooks_riverpod/hooks_riverpod.dart';
  6. import 'package:immich_mobile/modules/archive/providers/archive_asset_provider.dart';
  7. import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
  8. import 'package:immich_mobile/shared/models/asset.dart';
  9. import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
  10. import 'package:immich_mobile/utils/selection_handlers.dart';
  11. class ArchivePage extends HookConsumerWidget {
  12. const ArchivePage({super.key});
  13. @override
  14. Widget build(BuildContext context, WidgetRef ref) {
  15. final archivedAssets = ref.watch(archiveProvider);
  16. final selectionEnabledHook = useState(false);
  17. final selection = useState(<Asset>{});
  18. final processing = useState(false);
  19. void selectionListener(
  20. bool multiselect,
  21. Set<Asset> selectedAssets,
  22. ) {
  23. selectionEnabledHook.value = multiselect;
  24. selection.value = selectedAssets;
  25. }
  26. AppBar buildAppBar(String count) {
  27. return AppBar(
  28. leading: IconButton(
  29. onPressed: () => AutoRouter.of(context).pop(),
  30. icon: const Icon(Icons.arrow_back_ios_rounded),
  31. ),
  32. centerTitle: true,
  33. automaticallyImplyLeading: false,
  34. title: const Text(
  35. 'archive_page_title',
  36. ).tr(args: [count]),
  37. );
  38. }
  39. Widget buildBottomBar() {
  40. return SafeArea(
  41. child: Align(
  42. alignment: Alignment.bottomCenter,
  43. child: SizedBox(
  44. height: 64,
  45. child: Card(
  46. child: Column(
  47. children: [
  48. ListTile(
  49. shape: RoundedRectangleBorder(
  50. borderRadius: BorderRadius.circular(10),
  51. ),
  52. leading: const Icon(
  53. Icons.unarchive_rounded,
  54. ),
  55. title: Text(
  56. 'control_bottom_app_bar_unarchive'.tr(),
  57. style: const TextStyle(fontSize: 14),
  58. ),
  59. onTap: processing.value
  60. ? null
  61. : () async {
  62. processing.value = true;
  63. try {
  64. await handleArchiveAssets(
  65. ref,
  66. context,
  67. selection.value.toList(),
  68. shouldArchive: false,
  69. );
  70. } finally {
  71. processing.value = false;
  72. selectionEnabledHook.value = false;
  73. }
  74. },
  75. ),
  76. ],
  77. ),
  78. ),
  79. ),
  80. ),
  81. );
  82. }
  83. return archivedAssets.when(
  84. loading: () => Scaffold(
  85. appBar: buildAppBar("?"),
  86. body: const Center(child: CircularProgressIndicator()),
  87. ),
  88. error: (error, stackTrace) => Scaffold(
  89. appBar: buildAppBar("Error"),
  90. body: Center(child: Text(error.toString())),
  91. ),
  92. data: (data) => Scaffold(
  93. appBar: buildAppBar(data.totalAssets.toString()),
  94. body: data.isEmpty
  95. ? Center(
  96. child: Text('archive_page_no_archived_assets'.tr()),
  97. )
  98. : Stack(
  99. children: [
  100. ImmichAssetGrid(
  101. renderList: data,
  102. listener: selectionListener,
  103. selectionActive: selectionEnabledHook.value,
  104. ),
  105. if (selectionEnabledHook.value) buildBottomBar(),
  106. if (processing.value)
  107. const Center(child: ImmichLoadingIndicator()),
  108. ],
  109. ),
  110. ),
  111. );
  112. }
  113. }