diff --git a/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart index 054f058739390..bfd8c134155e1 100644 --- a/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart @@ -107,7 +107,10 @@ class _AddActionButtonState extends ConsumerState { return; } - final List slivers = [AlbumSelector(onAlbumSelected: (album) => _addCurrentAssetToAlbum(album))]; + final List slivers = [ + const CreateAlbumButton(), + AlbumSelector(onAlbumSelected: (album) => _addCurrentAssetToAlbum(album)), + ]; showModalBottomSheet( context: context, diff --git a/mobile/lib/presentation/widgets/album/album_selector.widget.dart b/mobile/lib/presentation/widgets/album/album_selector.widget.dart index 4110966e57d84..8a3de2509c53e 100644 --- a/mobile/lib/presentation/widgets/album/album_selector.widget.dart +++ b/mobile/lib/presentation/widgets/album/album_selector.widget.dart @@ -12,8 +12,10 @@ import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/models/albums/album_search.model.dart'; import 'package:immich_mobile/presentation/widgets/album/album_tile.dart'; +import 'package:immich_mobile/presentation/widgets/album/new_album_name_modal.widget.dart'; import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; @@ -766,3 +768,61 @@ class AddToAlbumHeader extends ConsumerWidget { ); } } + +class CreateAlbumButton extends ConsumerWidget { + const CreateAlbumButton({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + Future onCreateAlbum() async { + var albumName = await showDialog(context: context, builder: (context) => const NewAlbumNameModal()); + if (albumName == null) return; + final asset = ref.read(currentAssetNotifier); + + if (asset == null) { + ImmichToast.show(context: context, msg: "Cannot load asset information.", toastType: ToastType.error); + return; + } + + final album = await ref + .read(remoteAlbumProvider.notifier) + .createAlbum(title: albumName, assetIds: [asset.remoteId!]); + + if (album == null) { + ImmichToast.show(context: context, toastType: ToastType.error, msg: 'errors.failed_to_create_album'.tr()); + return; + } + + ImmichToast.show( + context: context, + msg: 'add_to_album_bottom_sheet_added'.tr(namedArgs: {'album': album.name}), + ); + context.pop(); + } + + return SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 16), + sliver: SliverToBoxAdapter( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("add_to_album", style: context.textTheme.titleSmall).tr(), + TextButton.icon( + style: TextButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + minimumSize: const Size(0, 0), + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + onPressed: onCreateAlbum, + icon: Icon(Icons.add, color: context.primaryColor), + label: Text( + "common_create_new_album", + style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.bold, fontSize: 14), + ).tr(), + ), + ], + ), + ), + ); + } +} diff --git a/mobile/lib/presentation/widgets/album/new_album_name_modal.widget.dart b/mobile/lib/presentation/widgets/album/new_album_name_modal.widget.dart new file mode 100644 index 0000000000000..a5e21af48915e --- /dev/null +++ b/mobile/lib/presentation/widgets/album/new_album_name_modal.widget.dart @@ -0,0 +1,53 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:immich_mobile/extensions/build_context_extensions.dart'; + +class NewAlbumNameModal extends StatefulWidget { + const NewAlbumNameModal({super.key}); + + @override + State createState() => _NewAlbumNameModalState(); +} + +class _NewAlbumNameModalState extends State { + TextEditingController nameController = TextEditingController(); + + @override + void dispose() { + nameController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text("album_name", style: TextStyle(fontWeight: FontWeight.bold)).tr(), + content: SingleChildScrollView( + child: TextFormField( + controller: nameController, + textCapitalization: TextCapitalization.words, + autofocus: true, + decoration: InputDecoration(hintText: 'name'.tr(), border: const OutlineInputBorder()), + ), + ), + actions: [ + TextButton( + onPressed: () => context.pop(null), + child: Text( + "cancel", + style: TextStyle(color: Colors.red[300], fontWeight: FontWeight.bold), + ).tr(), + ), + TextButton( + onPressed: () { + context.pop(nameController.text.trim()); + }, + child: Text( + "create_album", + style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.bold), + ).tr(), + ), + ], + ); + } +}