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

@@ -9,8 +9,6 @@ class TopControlAppBar extends HookConsumerWidget {
required this.asset,
required this.onMoreInfoPressed,
required this.onDownloadPressed,
required this.onSharePressed,
required this.onDeletePressed,
required this.onAddToAlbumPressed,
required this.onToggleMotionVideo,
required this.isPlayingMotionVideo,
@@ -22,10 +20,8 @@ class TopControlAppBar extends HookConsumerWidget {
final Function onMoreInfoPressed;
final VoidCallback? onDownloadPressed;
final VoidCallback onToggleMotionVideo;
final VoidCallback onDeletePressed;
final VoidCallback onAddToAlbumPressed;
final VoidCallback onFavorite;
final Function onSharePressed;
final bool isPlayingMotionVideo;
final bool isFavorite;
@@ -34,15 +30,15 @@ class TopControlAppBar extends HookConsumerWidget {
const double iconSize = 18.0;
Widget buildFavoriteButton() {
return IconButton(
onPressed: () {
onFavorite();
},
icon: Icon(
isFavorite ? Icons.star : Icons.star_border,
color: Colors.grey[200],
),
);
return IconButton(
onPressed: () {
onFavorite();
},
icon: Icon(
isFavorite ? Icons.star : Icons.star_border,
color: Colors.grey[200],
),
);
}
return AppBar(
@@ -86,15 +82,6 @@ class TopControlAppBar extends HookConsumerWidget {
color: Colors.grey[200],
),
),
IconButton(
onPressed: () {
onSharePressed();
},
icon: Icon(
Icons.ios_share_rounded,
color: Colors.grey[200],
),
),
if (asset.isRemote)
IconButton(
onPressed: () {
@@ -105,15 +92,6 @@ class TopControlAppBar extends HookConsumerWidget {
color: Colors.grey[200],
),
),
IconButton(
onPressed: () {
onDeletePressed();
},
icon: Icon(
Icons.delete_outline_rounded,
color: Colors.grey[200],
),
),
IconButton(
onPressed: () {
onMoreInfoPressed();

View File

@@ -231,11 +231,10 @@ class GalleryViewerPage extends HookConsumerWidget {
void addToAlbum(Asset addToAlbumAsset) {
showModalBottomSheet(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
barrierColor: Colors.transparent,
backgroundColor: Colors.transparent,
context: context,
builder: (BuildContext _) {
return AddToAlbumBottomSheet(
@@ -267,6 +266,19 @@ class GalleryViewerPage extends HookConsumerWidget {
}
}
shareAsset() {
ref
.watch(imageViewerStateProvider.notifier)
.shareAsset(assetList[indexOfAsset.value], context);
}
handleArchive(Asset asset) {
ref
.watch(assetProvider.notifier)
.toggleArchive([asset], !asset.isArchived);
AutoRouter.of(context).pop();
}
buildAppBar() {
final show = (showAppBar.value || // onTap has the final say
(showAppBar.value && !isZoomed.value)) &&
@@ -297,16 +309,9 @@ class GalleryViewerPage extends HookConsumerWidget {
context,
);
},
onSharePressed: () {
ref
.watch(imageViewerStateProvider.notifier)
.shareAsset(assetList[indexOfAsset.value], context);
},
onToggleMotionVideo: (() {
isPlayingMotionVideo.value = !isPlayingMotionVideo.value;
}),
onDeletePressed: () =>
handleDelete((assetList[indexOfAsset.value])),
onAddToAlbumPressed: () =>
addToAlbum(assetList[indexOfAsset.value]),
),
@@ -314,6 +319,59 @@ class GalleryViewerPage extends HookConsumerWidget {
);
}
buildBottomBar() {
final show = (showAppBar.value || // onTap has the final say
(showAppBar.value && !isZoomed.value)) &&
!isPlayingVideo.value;
final currentAsset = assetList[indexOfAsset.value];
return AnimatedOpacity(
duration: const Duration(milliseconds: 100),
opacity: show ? 1.0 : 0.0,
child: BottomNavigationBar(
backgroundColor: Colors.black.withOpacity(0.4),
unselectedIconTheme: const IconThemeData(color: Colors.white),
selectedIconTheme: const IconThemeData(color: Colors.white),
unselectedLabelStyle: const TextStyle(color: Colors.black),
selectedLabelStyle: const TextStyle(color: Colors.black),
showSelectedLabels: false,
showUnselectedLabels: false,
items: [
const BottomNavigationBarItem(
icon: Icon(Icons.ios_share_rounded),
label: 'Share',
tooltip: 'Share',
),
BottomNavigationBarItem(
icon: currentAsset.isArchived
? const Icon(Icons.unarchive_rounded)
: const Icon(Icons.archive_outlined),
label: 'Archive',
tooltip: 'Archive',
),
const BottomNavigationBarItem(
icon: Icon(Icons.delete_outline),
label: 'Delete',
tooltip: 'Delete',
),
],
onTap: (index) {
switch (index) {
case 0:
shareAsset();
break;
case 1:
handleArchive(assetList[indexOfAsset.value]);
break;
case 2:
handleDelete(assetList[indexOfAsset.value]);
break;
}
},
),
);
}
return Scaffold(
backgroundColor: Colors.black,
body: WillPopScope(
@@ -481,6 +539,12 @@ class GalleryViewerPage extends HookConsumerWidget {
right: 0,
child: buildAppBar(),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: buildBottomBar(),
),
],
),
),