feat(mobile): Archive feature on mobile (#2258)

* update asset to include isArchive property

* Not display archived assets on timeline

* replace share button to archive button

* Added archive page

* Add bottom nav bar

* clean up homepage

* remove deadcode

* improve on sync is archive

* show archive asset correctly

* better merge condition

* Added back renderList to re-rendering don't jump around

* Better way to handle showing archive assets

* complete ArchiveSelectionNotifier

* toggle archive

* remove deadcode

* fix unit tests

* update assets in DB when changing assets

* update asset state to reflect archived status

* allow to archive assets via multi-select from timeline

* fixed logic

* Add options to bulk unarchive

* regenerate api

* Change position of toast message

---------

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
This commit is contained in:
Alex
2023-04-17 00:02:07 -05:00
committed by GitHub
parent 635eee9e5e
commit 2e5cd986dd
27 changed files with 523 additions and 114 deletions

View File

@@ -109,7 +109,7 @@ class RenderList {
final groups = _groupAssets(allAssets, groupBy);
groups.entries.sortedBy((e) =>e.key).reversed.forEach((entry) {
groups.entries.sortedBy((e) => e.key).reversed.forEach((entry) {
final date = entry.key;
final assets = entry.value;

View File

@@ -50,10 +50,9 @@ class ImmichAssetGrid extends HookConsumerWidget {
// Unfortunately, using the transition animation itself didn't
// seem to work reliably. So instead, wait until the duration of the
// animation has elapsed to re-enable the hero animations
Future.delayed(transitionDuration)
.then((_) {
enableHeroAnimations.value = true;
});
Future.delayed(transitionDuration).then((_) {
enableHeroAnimations.value = true;
});
}
return null;
},

View File

@@ -9,6 +9,7 @@ import 'package:immich_mobile/shared/models/album.dart';
class ControlBottomAppBar extends ConsumerWidget {
final Function onShare;
final Function onFavorite;
final Function onArchive;
final Function onDelete;
final Function(Album album) onAddToAlbum;
final void Function() onCreateNewAlbum;
@@ -20,6 +21,7 @@ class ControlBottomAppBar extends ConsumerWidget {
Key? key,
required this.onShare,
required this.onFavorite,
required this.onArchive,
required this.onDelete,
required this.sharedAlbums,
required this.albums,
@@ -62,6 +64,11 @@ class ControlBottomAppBar extends ConsumerWidget {
);
},
),
ControlBoxButton(
iconData: Icons.archive,
label: "control_bottom_app_bar_archive".tr(),
onPressed: () => onArchive(),
),
],
);
}

View File

@@ -94,7 +94,6 @@ class HomePage extends HookConsumerWidget {
barrierDismissible: false,
);
// ref.watch(shareServiceProvider).shareAssets(selection.value.toList());
selectionEnabledHook.value = false;
}
@@ -132,6 +131,24 @@ class HomePage extends HookConsumerWidget {
selectionEnabledHook.value = false;
}
void onArchiveAsset() {
final remoteAssets = remoteOnlySelection(
localErrorMessage: 'home_page_archive_err_local'.tr(),
);
if (remoteAssets.isNotEmpty) {
ref.watch(assetProvider.notifier).toggleArchive(remoteAssets, true);
final assetOrAssets = remoteAssets.length > 1 ? 'assets' : 'asset';
ImmichToast.show(
context: context,
msg: 'Moved ${remoteAssets.length} $assetOrAssets to archive',
gravity: ToastGravity.CENTER,
);
}
selectionEnabledHook.value = false;
}
void onDelete() {
ref.watch(assetProvider.notifier).deleteAssets(selection.value);
selectionEnabledHook.value = false;
@@ -265,7 +282,7 @@ class HomePage extends HookConsumerWidget {
? buildLoadingIndicator()
: ImmichAssetGrid(
renderList: ref.watch(assetProvider).renderList!,
assets: ref.watch(assetProvider).allAssets,
assets: ref.read(assetProvider).allAssets,
assetsPerRow: appSettingService
.getSetting(AppSettingsEnum.tilesPerRow),
showStorageIndicator: appSettingService
@@ -278,6 +295,7 @@ class HomePage extends HookConsumerWidget {
ControlBottomAppBar(
onShare: onShareAssets,
onFavorite: onFavoriteAssets,
onArchive: onArchiveAsset,
onDelete: onDelete,
onAddToAlbum: onAddToAlbum,
albums: albums,
@@ -291,9 +309,7 @@ class HomePage extends HookConsumerWidget {
return Scaffold(
appBar: !selectionEnabledHook.value
? HomePageAppBar(
onPopBack: reloadAllAsset,
)
? HomePageAppBar(onPopBack: reloadAllAsset)
: null,
drawer: const ProfileDrawer(),
body: buildBody(),