import 'dart:async'; import 'package:flutter/material.dart'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/selection.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/widgets/collection/actions/entry_actions.dart'; import 'package:aves/widgets/collection/actions/entry_action_dialogs.dart'; import 'package:aves/widgets/collection/actions/entry_action_edit.dart'; import 'package:aves/widgets/collection/actions/entry_action_cast.dart'; import 'package:aves/widgets/collection/actions/entry_action_utils.dart'; import 'package:aves/widgets/dialogs/aves_confirmation_dialog.dart'; import 'package:aves/widgets/dialogs/convert_entry_dialog.dart'; import 'package:aves/widgets/map/map_page.dart'; import 'package:aves/widgets/common/search/route.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; /// Gestore principale delle azioni sugli entry. /// Versione ultra‑ottimizzata, senza album, senza filter_grids. class EntryActionHandlers { final BuildContext context; final CollectionLens collection; final AvesSelection selection; EntryActionHandlers({ required this.context, required this.collection, required this.selection, }); /// Esegue l’azione richiesta. Future run(EntryAction action) async { final entries = selection.selectedEntries.toList(); if (entries.isEmpty && !_actionAllowsEmptySelection(action)) { return; } switch (action) { // Navigazione case EntryAction.configureView: return _configureView(); case EntryAction.searchCollection: return _search(); case EntryAction.map: return _openMap(entries); case EntryAction.slideshow: return _slideshow(entries); case EntryAction.stats: return _stats(entries); case EntryAction.rescan: return _rescan(); // Selezione case EntryAction.select: return selection.toggle(entries.first); case EntryAction.selectAll: return selection.selectAll(); case EntryAction.selectNone: return selection.clear(); // Cast case EntryAction.cast: return EntryActionCast(context, entries).startCast(); // File operations case EntryAction.share: return _share(entries); case EntryAction.delete: return _delete(entries); case EntryAction.copy: return _copy(entries); case EntryAction.move: return _move(entries); case EntryAction.rename: return _rename(entries); case EntryAction.convert: return _convert(entries); // Metadata case EntryAction.toggleFavourite: return _toggleFavourite(entries); case EntryAction.rotateCW: return EntryActionEdit.rotateCW(context, entries); case EntryAction.rotateCCW: return EntryActionEdit.rotateCCW(context, entries); case EntryAction.flip: return EntryActionEdit.flip(context, entries); case EntryAction.editDate: return _editDate(entries); case EntryAction.editLocation: return _editLocation(entries); case EntryAction.editTitleDescription: return _editTitleDescription(entries); case EntryAction.editRating: return _editRating(entries); case EntryAction.editTags: return _editTags(entries); case EntryAction.removeMetadata: return _removeMetadata(entries); } } // ------------------------------------------------------------ // NAVIGAZIONE // ------------------------------------------------------------ Future _configureView() async { settings.configureView = !settings.configureView; } Future _search() async { Navigator.push( context, SearchPageRoute( collection: collection, ), ); } Future _openMap(List entries) async { if (entries.isEmpty) return; Navigator.push( context, MaterialPageRoute( builder: (_) => MapPage(entries: entries), ), ); } Future _slideshow(List entries) async { await showDialog( context: context, builder: (_) => SlideshowDialog(entries: entries), ); } Future _stats(List entries) async { await showDialog( context: context, builder: (_) => StatsDialog(entries: entries), ); } Future _rescan() async { await collection.source.reload(); } // ------------------------------------------------------------ // FILE OPERATIONS // ------------------------------------------------------------ Future _share(List entries) async { await appService.share(entries); } Future _delete(List entries) async { final confirmed = await showDialog( context: context, builder: (_) => AvesConfirmationDialog( title: 'Elimina', message: 'Vuoi eliminare ${entries.length} elementi?', ), ); if (confirmed != true) return; await appService.delete(entries); selection.clear(); } Future _copy(List entries) async { await EntryActionUtils.copyEntries(context, entries); } Future _move(List entries) async { await EntryActionUtils.moveEntries(context, entries); } Future _rename(List entries) async { if (entries.length != 1) return; await Navigator.push( context, MaterialPageRoute( builder: (_) => RenameEntrySetPage(entries: entries), ), ); } Future _convert(List entries) async { if (entries.length != 1) return; await showDialog( context: context, builder: (_) => ConvertEntryDialog(entry: entries.first), ); } // ------------------------------------------------------------ // METADATA // ------------------------------------------------------------ Future _toggleFavourite(List entries) async { for (final entry in entries) { entry.toggleFavourite(); } } Future _editDate(List entries) async { await showDialog( context: context, builder: (_) => EditDateDialog(entries: entries), ); } Future _editLocation(List entries) async { await showDialog( context: context, builder: (_) => EditLocationDialog(entries: entries), ); } Future _editTitleDescription(List entries) async { await showDialog( context: context, builder: (_) => EditTitleDescriptionDialog(entries: entries), ); } Future _editRating(List entries) async { await showDialog( context: context, builder: (_) => EditRatingDialog(entries: entries), ); } Future _editTags(List entries) async { await showDialog( context: context, builder: (_) => EditTagsDialog(entries: entries), ); } Future _removeMetadata(List entries) async { await showDialog( context: context, builder: (_) => RemoveMetadataDialog(entries: entries), ); } // ------------------------------------------------------------ // UTILS // ------------------------------------------------------------ bool _actionAllowsEmptySelection(EntryAction action) { return { EntryAction.configureView, EntryAction.searchCollection, EntryAction.rescan, }.contains(action); } }