From ae22a25a1341689b38d1f71b5af9dcd5b8c623c4 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Tue, 29 Oct 2024 02:02:42 +0100 Subject: [PATCH] #1248 fixed new album name resolution to allow same name as existing empty directory --- CHANGELOG.md | 1 + .../filter_editors/create_album_dialog.dart | 36 ++++++++++++++----- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 977f18f52..f3f18c483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - crash when loading large collection - Viewer: copying content URI item +- Albums: creating album with same name as existing empty directory ## [v1.11.16] - 2024-10-10 diff --git a/lib/widgets/dialogs/filter_editors/create_album_dialog.dart b/lib/widgets/dialogs/filter_editors/create_album_dialog.dart index 9943eab7c..9af1c8ef5 100644 --- a/lib/widgets/dialogs/filter_editors/create_album_dialog.dart +++ b/lib/widgets/dialogs/filter_editors/create_album_dialog.dart @@ -147,23 +147,43 @@ class _CreateAlbumDialogState extends State { ); } - String _buildAlbumPath(String name) { + String _sanitize(String input) => input.trim(); + + String? _buildAlbumPath(String name) { final selectedVolume = _selectedVolume; - if (selectedVolume == null || name.isEmpty) return ''; + if (selectedVolume == null || name.isEmpty) return null; return pContext.join(selectedVolume.path, 'Pictures', name); } Future _validate() async { - final newName = _nameController.text; + final newName = _sanitize(_nameController.text); final path = _buildAlbumPath(newName); - final exists = newName.isNotEmpty && await Directory(path).exists(); + // this check ignores case + final exists = path != null && await Directory(path).exists(); _existsNotifier.value = exists; - _isValidNotifier.value = newName.isNotEmpty && !exists; + _isValidNotifier.value = path != null && newName.isNotEmpty; } - void _submit(BuildContext context) { - if (_isValidNotifier.value) { - Navigator.maybeOf(context)?.pop(_buildAlbumPath(_nameController.text)); + Future _submit(BuildContext context) async { + if (!_isValidNotifier.value) return; + + final newName = _sanitize(_nameController.text); + final albumPath = _buildAlbumPath(newName); + final volumePath = _selectedVolume?.path; + if (albumPath == null || volumePath == null) return; + + // uses resolved directory name case if it exists + var resolvedPath = volumePath; + final relativePathSegments = pContext.split(pContext.relative(albumPath, from: volumePath)); + for (final targetSegment in relativePathSegments) { + String? resolvedSegment; + final directory = Directory(resolvedPath); + if (await directory.exists()) { + final lowerTargetSegment = targetSegment.toLowerCase(); + resolvedSegment = directory.listSync().map((v) => pContext.basename(v.path)).firstWhereOrNull((v) => v.toLowerCase() == lowerTargetSegment); + } + resolvedPath = pContext.join(resolvedPath, resolvedSegment ?? targetSegment); } + Navigator.maybeOf(context)?.pop(resolvedPath); } }