import 'dart:io'; import 'package:flutter/foundation.dart'; /// 画像一覧の取得・キャッシュ・削除操作を管理する. class GalleryProvider extends ChangeNotifier { static const _basePath = '/storage/emulated/0/Pictures/MiniTIAS'; List _images = []; bool _isLoading = false; List get images => _images; bool get isLoading => _isLoading; /// Pictures/MiniTIAS/ 内の PNG ファイルと QM プレビュー JPEG を取得し,新しい順に並べる. Future loadImages() async { _isLoading = true; notifyListeners(); try { final directory = Directory(_basePath); if (!await directory.exists()) { _images = []; } else { final files = await directory .list() .where((entity) { final lower = entity.path.toLowerCase(); return entity is File && (lower.endsWith('.png') || lower.endsWith('.preview.jpg')); }) .cast() .toList(); // 更新日時の新しい順にソート files.sort((a, b) { final aStat = a.statSync(); final bStat = b.statSync(); return bStat.modified.compareTo(aStat.modified); }); _images = files; } } catch (e) { debugPrint('画像一覧の取得に失敗: $e'); _images = []; } _isLoading = false; notifyListeners(); } /// 指定したファイルを削除し,一覧から除去する. /// /// QM プレビュー (*.preview.jpg) を削除する場合,同じ baseName の /// .dng ファイルと .meta.json ファイルも連動して削除する. /// .png ファイルは単独削除(後方互換). Future deleteImage(File file) async { final path = file.path; final lower = path.toLowerCase(); // 削除対象ファイル一覧を確定 final filesToDelete = [file]; if (lower.endsWith('.preview.jpg')) { final base = path.substring(0, path.length - '.preview.jpg'.length); filesToDelete.add(File('$base.dng')); filesToDelete.add(File('$base.meta.json')); } try { for (final f in filesToDelete) { if (await f.exists()) { await f.delete(); } } // 元ファイルが消えたら成功とみなす if (!await file.exists()) { _images.removeWhere((f) => f.path == file.path); notifyListeners(); return true; } return false; } catch (e) { debugPrint('画像の削除に失敗: $e'); return false; } } }