import 'dart:io'; import 'package:aves/services/services.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:flutter/material.dart'; class RenameAlbumDialog extends StatefulWidget { final String album; const RenameAlbumDialog({ Key? key, required this.album, }) : super(key: key); @override _RenameAlbumDialogState createState() => _RenameAlbumDialogState(); } class _RenameAlbumDialogState extends State { final TextEditingController _nameController = TextEditingController(); final ValueNotifier _existsNotifier = ValueNotifier(false); final ValueNotifier _isValidNotifier = ValueNotifier(false); String get album => widget.album; String get initialValue => pContext.basename(album); @override void initState() { super.initState(); _nameController.text = initialValue; _validate(); } @override void dispose() { _nameController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AvesDialog( context: context, content: ValueListenableBuilder( valueListenable: _existsNotifier, builder: (context, exists, child) { return TextField( controller: _nameController, decoration: InputDecoration( labelText: context.l10n.renameAlbumDialogLabel, helperText: exists ? context.l10n.renameAlbumDialogLabelAlreadyExistsHelper : '', ), autofocus: true, onChanged: (_) => _validate(), onSubmitted: (_) => _submit(context), ); }), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text(MaterialLocalizations.of(context).cancelButtonLabel), ), ValueListenableBuilder( valueListenable: _isValidNotifier, builder: (context, isValid, child) { return TextButton( onPressed: isValid ? () => _submit(context) : null, child: Text(context.l10n.applyButtonLabel), ); }, ) ], ); } String _buildAlbumPath(String name) { if (name.isEmpty) return ''; return pContext.join(pContext.dirname(album), name); } Future _validate() async { final newName = _nameController.text; final path = _buildAlbumPath(newName); final exists = newName.isNotEmpty && await FileSystemEntity.type(path) != FileSystemEntityType.notFound; _existsNotifier.value = exists && newName != initialValue; _isValidNotifier.value = newName.isNotEmpty && !exists; } void _submit(BuildContext context) => Navigator.pop(context, _nameController.text); }