@ -21,12 +21,34 @@ import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_shee
enum AddToMenuItem { album , archive , unarchive , lockedFolder }
class AddActionButton extends Consumer Widget {
class AddActionButton extends Consumer Stateful Widget {
const AddActionButton ( { super . key } ) ;
Future < void > _showAddOptions ( BuildContext context , WidgetRef ref ) async {
@ override
ConsumerState < AddActionButton > createState ( ) = > _AddActionButtonState ( ) ;
}
class _AddActionButtonState extends ConsumerState < AddActionButton > {
void _handleMenuSelection ( AddToMenuItem selected ) {
switch ( selected ) {
case AddToMenuItem . album:
_openAlbumSelector ( ) ;
break ;
case AddToMenuItem . archive:
performArchiveAction ( context , ref , source : ActionSource . viewer ) ;
break ;
case AddToMenuItem . unarchive:
performUnArchiveAction ( context , ref , source : ActionSource . viewer ) ;
break ;
case AddToMenuItem . lockedFolder:
performMoveToLockFolderAction ( context , ref , source : ActionSource . viewer ) ;
break ;
}
}
List < Widget > _buildMenuChildren ( ) {
final asset = ref . read ( currentAssetNotifier ) ;
if ( asset = = null ) return ;
if ( asset = = null ) return [ ] ;
final user = ref . read ( currentUserProvider ) ;
final isOwner = asset is RemoteAsset & & asset . ownerId = = user ? . id ;
@ -35,93 +57,57 @@ class AddActionButton extends ConsumerWidget {
final hasRemote = asset is RemoteAsset ;
final showArchive = isOwner & & ! isInLockedView & & hasRemote & & ! isArchived ;
final showUnarchive = isOwner & & ! isInLockedView & & hasRemote & & isArchived ;
final menuItemHeight = 30.0 ;
final List < PopupMenuEntry < AddToMenuItem > > items = [
PopupMenuItem (
enabled: false ,
textStyle: context . textTheme . labelMedium ,
height: 40 ,
child: Text ( " add_to_bottom_bar " . tr ( ) ) ,
return [
Padding (
padding: const EdgeInsets . symmetric ( horizontal: 16 , vertical: 8 ) ,
child: Text ( " add_to_bottom_bar " . tr ( ) , style: context . textTheme . labelMedium ) ,
) ,
PopupMenuItem (
height: menuItemHeight ,
value: AddToMenuItem . album ,
child: ListTile ( leading: const Icon ( Icons . photo_album_outlined ) , title: Text ( " album " . tr ( ) ) ) ,
BaseActionButton (
iconData: Icons . photo_album_outlined ,
label: " album " . tr ( ) ,
menuItem: true ,
onPressed: ( ) = > _handleMenuSelection ( AddToMenuItem . album ) ,
) ,
const PopupMenuDivider ( ) ,
PopupMenuItem ( enabled: false , textStyle: context . textTheme . labelMedium , height: 40 , child: Text ( " move_to " . tr ( ) ) ) ,
if ( isOwner ) . . . [
const PopupMenuDivider ( ) ,
Padding (
padding: const EdgeInsets . symmetric ( horizontal: 16 , vertical: 8 ) ,
child: Text ( " move_to " . tr ( ) , style: context . textTheme . labelMedium ) ,
) ,
if ( showArchive )
PopupMenuItem (
height: menuItemHeight ,
value: AddToMenuItem . archive ,
child: ListTile ( leading: const Icon ( Icons . archive_outlined ) , title: Text ( " archive " . tr ( ) ) ) ,
BaseActionButton (
iconData: Icons . archive_outlined ,
label: " archive " . tr ( ) ,
menuItem: true ,
onPressed: ( ) = > _handleMenuSelection ( AddToMenuItem . archive ) ,
) ,
if ( showUnarchive )
PopupMenuItem (
height: menuItemHeight ,
value: AddToMenuItem . unarchive ,
child: ListTile ( leading: const Icon ( Icons . unarchive_outlined ) , title: Text ( " unarchive " . tr ( ) ) ) ,
BaseActionButton (
iconData: Icons . unarchive_outlined ,
label: " unarchive " . tr ( ) ,
menuItem: true ,
onPressed: ( ) = > _handleMenuSelection ( AddToMenuItem . unarchive ) ,
) ,
PopupMenuItem (
height: menuItemHeight ,
value: AddToMenuItem . lockedFolder ,
child: ListTile ( leading: const Icon ( Icons . lock_outline ) , title: Text ( " locked_folder " . tr ( ) ) ) ,
BaseActionButton (
iconData: Icons . lock_outline ,
label: " locked_folder " . tr ( ) ,
menuItem: true ,
onPressed: ( ) = > _handleMenuSelection ( AddToMenuItem . lockedFolder ) ,
) ,
] ,
] ;
final AddToMenuItem ? selected = await showMenu < AddToMenuItem > (
context: context ,
color: context . themeData . scaffoldBackgroundColor ,
position: _menuPosition ( context ) ,
items: items ,
popUpAnimationStyle: AnimationStyle . noAnimation ,
) ;
if ( selected = = null ) {
return ;
}
switch ( selected ) {
case AddToMenuItem . album:
_openAlbumSelector ( context , ref ) ;
break ;
case AddToMenuItem . archive:
await performArchiveAction ( context , ref , source : ActionSource . viewer ) ;
break ;
case AddToMenuItem . unarchive:
await performUnArchiveAction ( context , ref , source : ActionSource . viewer ) ;
break ;
case AddToMenuItem . lockedFolder:
await performMoveToLockFolderAction ( context , ref , source : ActionSource . viewer ) ;
break ;
}
}
RelativeRect _menuPosition ( BuildContext context ) {
final renderObject = context . findRenderObject ( ) ;
if ( renderObject is ! RenderBox ) {
return RelativeRect . fill ;
}
final size = renderObject . size ;
final position = renderObject . localToGlobal ( Offset . zero ) ;
return RelativeRect . fromLTRB ( position . dx , position . dy - size . height - 200 , position . dx + size . width , position . dy ) ;
}
void _openAlbumSelector ( BuildContext context , WidgetRef ref ) {
void _openAlbumSelector ( ) {
final currentAsset = ref . read ( currentAssetNotifier ) ;
if ( currentAsset = = null ) {
ImmichToast . show ( context: context , msg: " Cannot load asset information. " , toastType: ToastType . error ) ;
return ;
}
final List < Widget > slivers = [
AlbumSelector ( onAlbumSelected: ( album ) = > _addCurrentAssetToAlbum ( context , ref , album ) ) ,
] ;
final List < Widget > slivers = [ AlbumSelector ( onAlbumSelected: ( album ) = > _addCurrentAssetToAlbum ( album ) ) ] ;
showModalBottomSheet (
context: context ,
@ -141,7 +127,7 @@ class AddActionButton extends ConsumerWidget {
) ;
}
Future < void > _addCurrentAssetToAlbum ( BuildContext context , WidgetRef ref , RemoteAlbum album ) async {
Future < void > _addCurrentAssetToAlbum ( RemoteAlbum album ) async {
final latest = ref . read ( currentAssetNotifier ) ;
if ( latest = = null ) {
@ -174,17 +160,27 @@ class AddActionButton extends ConsumerWidget {
}
@ override
Widget build ( BuildContext context , WidgetRef ref ) {
Widget build ( BuildContext context ) {
final asset = ref . watch ( currentAssetNotifier ) ;
if ( asset = = null ) {
return const SizedBox . shrink ( ) ;
}
return Builder (
builder: ( buttonContext ) {
return MenuAnchor (
consumeOutsideTap: true ,
style: MenuStyle (
backgroundColor: WidgetStatePropertyAll ( context . themeData . scaffoldBackgroundColor ) ,
elevation: const WidgetStatePropertyAll ( 4 ) ,
shape: const WidgetStatePropertyAll (
RoundedRectangleBorder ( borderRadius: BorderRadius . all ( Radius . circular ( 12 ) ) ) ,
) ,
) ,
menuChildren: _buildMenuChildren ( ) ,
builder: ( context , controller , child ) {
return BaseActionButton (
iconData: Icons . add ,
label: " add_to_bottom_bar " . tr ( ) ,
onPressed: ( ) = > _showAddOptions ( buttonContext , ref ) ,
onPressed: ( ) = > controller. isOpen ? controller . close ( ) : controller . open ( ) ,
) ;
} ,
) ;