Newer
Older
MiniTias / lib / screens / gallery_screen.dart
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)),
          ),
        ],
      ),
    );
  }
}