creek

The AI Image Editor of 2030

lib/ui/widgets/moodboard_image_card.dart (3561B)


  1import 'dart:io';
  2import 'package:flutter/material.dart';
  3import 'package:creekui/data/models/image_model.dart';
  4import 'package:creekui/ui/styles/variables.dart';
  5import 'package:creekui/ui/widgets/image_context_menu.dart';
  6
  7class MoodboardImageCard extends StatelessWidget {
  8  final ImageModel image;
  9  final VoidCallback onTap;
 10  final VoidCallback onDeleted;
 11  final bool showTags;
 12  final double? height;
 13
 14  const MoodboardImageCard({
 15    super.key,
 16    required this.image,
 17    required this.onTap,
 18    required this.onDeleted,
 19    this.showTags = false,
 20    this.height,
 21  });
 22
 23  @override
 24  Widget build(BuildContext context) {
 25    return ImageContextMenu(
 26      image: image,
 27      onImageDeleted: onDeleted,
 28      child: GestureDetector(
 29        onTap: onTap,
 30        child: Container(
 31          height: height,
 32          decoration: BoxDecoration(
 33            borderRadius: BorderRadius.circular(Variables.radiusMedium),
 34            color: Variables.surfaceSubtle,
 35            border: Border.all(color: Variables.borderSubtle),
 36          ),
 37          clipBehavior: Clip.antiAlias,
 38          child: Stack(
 39            fit: StackFit.expand,
 40            children: [
 41              Image.file(
 42                File(image.filePath),
 43                fit: BoxFit.cover,
 44                width: double.infinity,
 45                errorBuilder:
 46                    (_, __, ___) => const Center(
 47                      child: Icon(
 48                        Icons.broken_image,
 49                        color: Variables.textDisabled,
 50                      ),
 51                    ),
 52              ),
 53              if (showTags && image.tags.isNotEmpty)
 54                Positioned(
 55                  bottom: 0,
 56                  left: 0,
 57                  right: 0,
 58                  child: Container(
 59                    padding: const EdgeInsets.all(12),
 60                    decoration: BoxDecoration(
 61                      gradient: LinearGradient(
 62                        begin: Alignment.bottomCenter,
 63                        end: Alignment.topCenter,
 64                        colors: [
 65                          Colors.black.withOpacity(0.8),
 66                          Colors.transparent,
 67                        ],
 68                      ),
 69                    ),
 70                    child: Wrap(
 71                      spacing: 4,
 72                      runSpacing: 4,
 73                      children:
 74                          image.tags.take(3).map((tag) {
 75                            return Container(
 76                              padding: const EdgeInsets.symmetric(
 77                                horizontal: 6,
 78                                vertical: 2,
 79                              ),
 80                              decoration: BoxDecoration(
 81                                color: Colors.white.withOpacity(0.2),
 82                                borderRadius: BorderRadius.circular(4),
 83                              ),
 84                              child: Text(
 85                                tag.toUpperCase(),
 86                                style: const TextStyle(
 87                                  color: Colors.white,
 88                                  fontSize: 9,
 89                                  fontFamily: 'GeneralSans',
 90                                  fontWeight: FontWeight.w600,
 91                                ),
 92                              ),
 93                            );
 94                          }).toList(),
 95                    ),
 96                  ),
 97                ),
 98            ],
 99          ),
100        ),
101      ),
102    );
103  }
104}