mirror of
https://github.com/immich-app/immich.git
synced 2025-12-17 17:23:20 +03:00
feat(mobile): create new album from add to modal (#24431)
* feat(mobile): create new album from add to modal * refactor: use statefulwidget instead of hook * chore: rename createalbumbutton
This commit is contained in:
@@ -109,7 +109,10 @@ class _AddActionButtonState extends ConsumerState<AddActionButton> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Widget> slivers = [AlbumSelector(onAlbumSelected: (album) => _addCurrentAssetToAlbum(album))];
|
final List<Widget> slivers = [
|
||||||
|
const CreateAlbumButton(),
|
||||||
|
AlbumSelector(onAlbumSelected: (album) => _addCurrentAssetToAlbum(album)),
|
||||||
|
];
|
||||||
|
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ import 'package:immich_mobile/extensions/theme_extensions.dart';
|
|||||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
import 'package:immich_mobile/models/albums/album_search.model.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/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/presentation/widgets/images/thumbnail.widget.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/album.provider.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/timeline/multiselect.provider.dart';
|
||||||
import 'package:immich_mobile/providers/user.provider.dart';
|
import 'package:immich_mobile/providers/user.provider.dart';
|
||||||
import 'package:immich_mobile/providers/album/album_sort_by_options.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<void> onCreateAlbum() async {
|
||||||
|
var albumName = await showDialog<String?>(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(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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<NewAlbumNameModal> createState() => _NewAlbumNameModalState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NewAlbumNameModalState extends State<NewAlbumNameModal> {
|
||||||
|
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(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user