import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:mini_tias/providers/gallery_provider.dart';
import 'package:mini_tias/widgets/image_grid.dart';
/// 一覧画面.撮影済み画像のサムネイルグリッドを表示する.
class GalleryScreen extends StatefulWidget {
const GalleryScreen({super.key});
@override
State<GalleryScreen> createState() => _GalleryScreenState();
}
class _GalleryScreenState extends State<GalleryScreen> {
File? _selectedFile;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<GalleryProvider>().loadImages();
});
}
@override
Widget build(BuildContext context) {
final galleryProvider = context.watch<GalleryProvider>();
if (galleryProvider.isLoading) {
return const Center(child: CircularProgressIndicator());
}
if (galleryProvider.images.isEmpty) {
return const Center(child: Text('撮影した画像がありません'));
}
return Stack(
children: [
ImageGrid(
images: galleryProvider.images,
onImageTap: (file) => setState(() => _selectedFile = file),
),
// 画像詳細表示(この領域内に収まる)
if (_selectedFile != null)
Positioned.fill(
child: Stack(
children: [
// 画像(全面・上下クロップ)
InteractiveViewer(
minScale: 1.0,
maxScale: 5.0,
child: SizedBox.expand(
child: Image.file(
_selectedFile!,
fit: BoxFit.cover,
),
),
),
// ヘッダー(ファイル名 + 閉じるボタン)
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
color: Colors.black54,
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
),
child: Row(
children: [
Expanded(
child: Text(
_selectedFile!.path.split('/').last,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
overflow: TextOverflow.ellipsis,
),
),
IconButton(
icon: const Icon(
Icons.close,
color: Colors.white,
),
onPressed: () =>
setState(() => _selectedFile = null),
),
],
),
),
),
// 削除ボタン
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
color: Colors.black54,
padding: const EdgeInsets.all(8),
child: Center(
child: TextButton.icon(
onPressed: () => _confirmDelete(galleryProvider),
icon: const Icon(Icons.delete, color: Colors.red),
label: const Text(
'削除',
style: TextStyle(color: Colors.red),
),
),
),
),
),
],
),
),
],
);
}
void _confirmDelete(GalleryProvider galleryProvider) {
final file = _selectedFile;
if (file == null) return;
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('画像を削除'),
content: const Text('この画像を削除しますか?'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('キャンセル'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
setState(() => _selectedFile = null);
galleryProvider.deleteImage(file);
},
child: const Text('削除', style: TextStyle(color: Colors.red)),
),
],
),
);
}
}