import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/app_db.dart'; import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album/cover_provider.dart'; import 'package:nc_photos/entity/album/provider.dart'; import 'package:nc_photos/entity/album/sort_provider.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/use_case/create_album.dart'; import 'package:nc_photos/widget/album_dir_picker.dart'; /// Dialog to create a new album /// /// The created album will be popped to the previous route, or null if user /// cancelled class NewAlbumDialog extends StatefulWidget { const NewAlbumDialog({ Key? key, required this.account, this.isAllowDynamic = true, }) : super(key: key); @override createState() => _NewAlbumDialogState(); final Account account; final bool isAllowDynamic; } class _NewAlbumDialogState extends State { @override initState() { super.initState(); } @override build(BuildContext context) { return Visibility( visible: _isVisible, child: AlertDialog( title: Text(L10n.global().createAlbumTooltip), content: Form( key: _formKey, child: Container( constraints: const BoxConstraints.tightFor(width: 280), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( decoration: InputDecoration( hintText: L10n.global().nameInputHint, ), validator: (value) { if (value!.isEmpty) { return L10n.global().albumNameInputInvalidEmpty; } return null; }, onSaved: (value) { _formValue.name = value!; }, ), if (widget.isAllowDynamic) ...[ DropdownButtonHideUnderline( child: DropdownButtonFormField<_Provider>( value: _provider, items: [_Provider.static, _Provider.dir] .map((e) => DropdownMenuItem<_Provider>( value: e, child: Text(e.toValueString(context)), )) .toList(), onChanged: (newValue) { setState(() { _provider = newValue!; }); }, onSaved: (value) { _formValue.provider = value; }, ), ), const SizedBox(height: 8), Text( _provider.toDescription(context), style: Theme.of(context).textTheme.bodyText2, ), ], ], ), ), ), actions: [ TextButton( onPressed: () => _onOkPressed(context), child: Text(MaterialLocalizations.of(context).okButtonLabel), ), ], ), ); } void _onOkPressed(BuildContext context) { if (_formKey.currentState?.validate() == true) { _formKey.currentState!.save(); if (_formValue.provider == _Provider.static || _formValue.provider == null) { _onConfirmStaticAlbum(); } else { _onConfirmDirAlbum(); } } } void _onConfirmStaticAlbum() { final album = Album( name: _formValue.name, provider: AlbumStaticProvider( items: const [], ), coverProvider: AlbumAutoCoverProvider(), sortProvider: const AlbumTimeSortProvider(isAscending: false), ); _log.info("[_onOkPressed] Creating static album: $album"); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb())); final newAlbum = CreateAlbum(albumRepo)(widget.account, album); // let previous route to handle this future Navigator.of(context).pop(newAlbum); } void _onConfirmDirAlbum() { setState(() { _isVisible = false; }); Navigator.of(context) .pushNamed>(AlbumDirPicker.routeName, arguments: AlbumDirPickerArguments(widget.account)) .then((value) { if (value == null) { Navigator.of(context).pop(); return; } final album = Album( name: _formValue.name, provider: AlbumDirProvider( dirs: value, ), coverProvider: AlbumAutoCoverProvider(), sortProvider: const AlbumTimeSortProvider(isAscending: false), ); _log.info("[_onOkPressed] Creating dir album: $album"); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb())); final newAlbum = CreateAlbum(albumRepo)(widget.account, album); // let previous route to handle this future Navigator.of(context).pop(newAlbum); }).catchError((e, stacktrace) { _log.shout("[_onOkPressed] Failed while pushNamed", e, stacktrace); Navigator.of(context).pop(); }); } final _formKey = GlobalKey(); var _provider = _Provider.static; final _formValue = _FormValue(); var _isVisible = true; static final _log = Logger("widget.new_album_dialog._NewAlbumDialogState"); } class _FormValue { late String name; _Provider? provider; } enum _Provider { static, dir, } extension on _Provider { String toValueString(BuildContext context) { switch (this) { case _Provider.static: return L10n.global().createAlbumDialogBasicLabel; case _Provider.dir: return L10n.global().createAlbumDialogFolderBasedLabel; default: throw StateError("Unknown value: $this"); } } String toDescription(BuildContext context) { switch (this) { case _Provider.static: return L10n.global().createAlbumDialogBasicDescription; case _Provider.dir: return L10n.global().createAlbumDialogFolderBasedDescription; default: throw StateError("Unknown value: $this"); } } }