# NetCache Image

A Flutter package for loading network images with **offline support** and **smart caching**.

[![pub.dev](https://img.shields.io/pub/v/netcache_image)](https://pub.dev/packages/netcache_image)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Flutter](https://img.shields.io/badge/Flutter-3.0+-blue.svg)](https://flutter.dev)

## Features

- **Smart Caching**: Automatically caches images after the first load
- **Offline Support**: Loads images from cache when no internet connection
- **Preloading**: Preload multiple image URLs in advance
- **Auto Retry**: Automatic retry for failed or timed-out requests
- **Customizable UI**: Placeholder and error widgets
- **Cache Management**: Configurable cache expiration policy
- **Performance Optimized**: Designed for ListView, GridView, and other scrollables

## Getting Started

### Installation

Add `netcache_image` to your `pubspec.yaml`:

```yaml
dependencies:
  netcache_image: ^1.0.0
```

Run `flutter pub get` to install the package.

### Basic Usage

```dart
import 'package:netcache_image/netcache_image.dart';

NetCacheImage(
  url: 'https://example.com/image.jpg',
  placeholder: Icon(Icons.image),
  errorWidget: Icon(Icons.broken_image),
)
```

## Usage

### Simple Image Loading

```dart
NetCacheImage(
  url: 'https://example.com/image.jpg',
)
```

### With Custom Placeholder and Error Widgets

```dart
NetCacheImage(
  url: 'https://example.com/image.jpg',
  placeholder: Container(
    color: Colors.grey[300],
    child: Center(
      child: CircularProgressIndicator(),
    ),
  ),
  errorWidget: Container(
    color: Colors.red[100],
    child: Center(
      child: Icon(Icons.error, color: Colors.red),
    ),
  ),
)
```

### With Custom Configuration

```dart
NetCacheImage(
  url: 'https://example.com/image.jpg',
  cacheExpiration: Duration(days: 7),
  maxRetries: 3,
  retryDelay: Duration(seconds: 2),
  placeholder: Icon(Icons.image),
  errorWidget: Icon(Icons.broken_image),
)
```

## Preloading

Preload multiple images in advance for better user experience:

```dart
// Preload images
await NetCacheImage.preload([
  'https://example.com/img1.jpg',
  'https://example.com/img2.jpg',
  'https://example.com/img3.jpg',
]);

// Images will be cached and available offline
```

### Preload with Configuration

```dart
await NetCacheImage.preload(
  [
    'https://example.com/img1.jpg',
    'https://example.com/img2.jpg',
  ],
  cacheExpiration: Duration(days: 30),
  maxRetries: 5,
);
```

## Retry & Error Handling

The package automatically handles network failures and retries:

- **Automatic Retry**: Failed requests are retried automatically
- **Configurable Retry Count**: Set maximum number of retry attempts
- **Retry Delay**: Configure delay between retry attempts
- **Error Widgets**: Custom error widgets for failed loads

### Configuration Options

```dart
NetCacheImage(
  url: 'https://example.com/image.jpg',
  maxRetries: 3,           // Maximum retry attempts
  retryDelay: Duration(seconds: 2),  // Delay between retries
  cacheExpiration: Duration(days: 7), // Cache expiration time
)
```

## Advanced Features

### Cache Management

```dart
// Clear all cached images
await NetCacheImage.clearCache();

// Clear expired images
await NetCacheImage.clearExpiredCache();

// Get cache size
final size = await NetCacheImage.getCacheSize();
```

### Network Connectivity

The package automatically detects network connectivity and:
- Loads from cache when offline
- Attempts network requests when online
- Falls back to cached images on network failure

## API Reference

### NetCacheImage Widget

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `url` | `String` | required | Image URL to load |
| `placeholder` | `Widget?` | `null` | Widget shown while loading |
| `errorWidget` | `Widget?` | `null` | Widget shown on error |
| `cacheExpiration` | `Duration?` | `7 days` | Cache expiration time |
| `maxRetries` | `int` | `3` | Maximum retry attempts |
| `retryDelay` | `Duration` | `2 seconds` | Delay between retries |

### Static Methods

| Method | Description |
|--------|-------------|
| `NetCacheImage.preload(urls, config)` | Preload multiple images |
| `NetCacheImage.clearCache()` | Clear all cached images |
| `NetCacheImage.clearExpiredCache()` | Clear expired images |
| `NetCacheImage.getCacheSize()` | Get cache size in bytes |

## Performance Tips

1. **Use Preloading**: Preload images that will be displayed soon
2. **Optimize Cache Expiration**: Set appropriate cache expiration based on your use case
3. **Custom Placeholders**: Use lightweight placeholder widgets
4. **Error Handling**: Provide meaningful error widgets for better UX

## Example

See the `example/` directory for a complete working example.

```dart
import 'package:flutter/material.dart';
import 'package:netcache_image/netcache_image.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('NetCache Image Example')),
        body: ListView.builder(
          itemCount: 10,
          itemBuilder: (context, index) {
            return NetCacheImage(
              url: 'https://picsum.photos/300/200?random=$index',
              placeholder: Container(
                height: 200,
                color: Colors.grey[300],
                child: Center(child: CircularProgressIndicator()),
              ),
              errorWidget: Container(
                height: 200,
                color: Colors.red[100],
                child: Center(child: Icon(Icons.error)),
              ),
            );
          },
        ),
      ),
    );
  }
}
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Author

**Nguyen Thanh Bien (Nguyễn Thành Biên)**

- Email: mortarcloud@gmail.com
- Website: https://algonest.io.vn
- GitHub: https://github.com/nguyenthanhbien

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request. 