attachment_engine

pub package license platform

A comprehensive federated Flutter engine for handling attachment workflows across mobile, desktop, and web applications:

  • πŸ“„ Multi-Format Rendering: Native PDF viewer (Android/iOS/macOS), HTML5/SCORM player, rich text, images, and Office documents.
  • 🎡 Audio & Video Playback: Full-screen viewer, inline player, background audio, and HLS streaming support.
  • πŸ’Ύ Resilient Cache Engine: LRU eviction cap, SHA-256 key hashing, background download resume, and network deduplication.
  • πŸ“± Multi-Platform Support: Production-ready on Android, iOS, macOS, and Web; Development Preview on Windows and Linux.
  • 🎨 Ready-to-Use UI Widgets: AttachmentViewer, AttachmentPreview, AttachmentTile, AttachmentList, and AttachmentGrid.
  • πŸ›‘οΈ Zero-Crash Resilience: Zip-slip protection, mime-type sniffing, corrupted file detection, and user-friendly error mapping.

πŸ“± Platform Support Matrix

Feature Android iOS macOS Windows (Preview) Linux (Preview) Web
PDF Viewing βœ… Native PDF Surface βœ… Native PDFKit βœ… Native PDFKit ❌ Unimplemented ❌ Unimplemented ❌ Unimplemented
Video Playback βœ… MediaPlayer / Surface βœ… AVPlayer βœ… AVPlayer ⚠️ Media Foundation (Preview) ⚠️ GStreamer (Preview) βœ… HTML5 Video
Audio Playback βœ… MediaPlayer βœ… AVAudioPlayer βœ… AVAudioPlayer ⚠️ Media Foundation (Preview) ⚠️ GStreamer (Preview) βœ… HTML5 Audio
Office Documents βœ… External Open Fallback βœ… Native QuickLook βœ… Native QuickLook βœ… Native Open βœ… Native Open βœ… In-Browser
HTML / SCORM / H5P βœ… WebView βœ… WKWebView βœ… WKWebView βœ… WebView βœ… Web Surface βœ… iframe / DOM
File Download βœ… Native / Resumable βœ… NSURLSession βœ… NSURLSession βœ… Background IO (dart:io) βœ… Background IO (dart:io) βœ… Fetch + OPFS
System Share βœ… Android Sharesheet βœ… UIActivityViewController βœ… NSSharingService ⚠️ Share Interop (Preview) ❌ Unimplemented βœ… Web Share API

πŸš€ Quick Start

1. Installation

Add attachment_engine to your pubspec.yaml:

dependencies:
  attachment_engine: ^0.0.1-dev.1

2. Initialize the Engine

Initialize AttachmentManager in your app's main() entrypoint:

import 'package:flutter/material.dart';
import 'package:attachment_engine/attachment_engine.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await AttachmentManager.initializeDefault();
  runApp(const MyApp());
}

3. Display an Attachment (Viewer & Preview)

import 'package:flutter/material.dart';
import 'package:attachment_engine/attachment_engine.dart';

class AttachmentScreen extends StatelessWidget {
  const AttachmentScreen({super.key, required this.attachment});

  final Attachment attachment;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(attachment.name)),
      body: Center(
        // Full Interactive Viewer:
        child: AttachmentViewer(attachment: attachment),
      ),
    );
  }
}

🧩 UI Components

attachment_engine provides plug-and-play UI widgets that adapt to every attachment type:

AttachmentViewer

Full interactive viewer with zoom, swipe, full-screen playback, and action controls.

AttachmentViewer(
  attachment: attachment,
)

AttachmentPreview

Lightweight thumbnail/card preview without initializing heavy platform controllers.

SizedBox(
  width: 120,
  height: 120,
  child: ClipRRect(
    borderRadius: BorderRadius.circular(8),
    child: AttachmentPreview(attachment: attachment),
  ),
)

AttachmentTile & AttachmentList

Ready-made list tiles with progress indicator, capability action buttons, and retry states.

AttachmentList(
  attachments: attachmentList,
  onTapAttachment: (attachment) => AttachmentManager.instance.open(attachment),
)

⚑ Programmatic Management API

final manager = AttachmentManager.instance;

// 1. Resolve and open an attachment for viewing
final resolved = await manager.open(attachment);

// 2. Share resolved attachment via OS native share sheet
await manager.share(resolved.attachment);

// 3. Open in an external OS-provided application
await manager.openExternally(resolved.attachment);

// 4. Invalidate / delete local cache
await manager.deleteCache(attachment);

βš™οΈ Custom Configuration

Customize caching limits, retry backoff, and renderers via AttachmentEngineConfig:

final customConfig = AttachmentEngineConfig(
  cache: const CacheConfig(
    maxTotalSizeBytes: 1024 * 1024 * 500, // 500 MB
    retention: Duration(days: 14),
  ),
  download: const DownloadConfig(
    maxConcurrentDownloads: 4,
    maxRetries: 3,
  ),
);

await AttachmentManager.initializeDefault(config: customConfig);

πŸ”’ Security & Resilience

  • Zip-Slip Safe Extraction: SCORM and ZIP extractors enforce strict path validation to prevent path traversal attacks.
  • Safe Cache Hashing: File keys are hashed using SHA-256, protecting against invalid characters and directory injections.
  • Content Validation: Verifies magic bytes to confirm the actual payload matches the declared file extension before execution.

πŸ“„ License

This project is licensed under the MIT License. See the LICENSE file for details.

Libraries

attachment_engine
Universal Attachment Management Engine.