flutter_cors_image 0.3.3
flutter_cors_image: ^0.3.3 copied to clipboard
A Flutter package that provides image loading solutions for handling CORS issues and problematic images on web platforms.
Changelog #
0.3.3 Right-Click Context Menu Release #
๐ New Major Features #
Right-Click Context Menu System (Web Only)
- NEW: Native-like right-click context menu for images with browser-style actions
- NEW:
enableContextMenuparameter to enable/disable context menu functionality - NEW:
customContextMenuItemsfor adding custom menu items with icons and callbacks - NEW: Built-in context menu actions:
- Copy image - Copies image to system clipboard for Ctrl+V pasting
- Save image as... - Shows browser save dialog with File System Access API
- Open image in new tab - Opens image URL in new browser tab
- Copy image address - Copies image URL to clipboard
Advanced Context Menu Customization
- NEW:
ContextMenuItemclass for defining custom menu items with icons and actions - NEW:
ContextMenuActionenum for built-in and custom actions - NEW: Context menu styling options:
contextMenuBackgroundColor- Custom background colorcontextMenuTextColor- Custom text colorcontextMenuElevation- Shadow elevationcontextMenuBorderRadius- Corner radiuscontextMenuPadding- Internal padding
- NEW:
onContextMenuActioncallback for handling menu item selections
Smart Context Menu Behavior
- NEW: Automatic browser context menu prevention only when hovering over images
- NEW: Smart positioning to keep menu on screen (auto-adjusts near edges)
- NEW: Overlay-based rendering for proper z-index and click-outside dismissal
- NEW: Works across all image loading states (loading, loaded, error, HTML fallback)
Enhanced Download & Save Experience
- NEW: File System Access API integration for proper save dialogs with location picker
- NEW: Traditional blob download fallback for browser compatibility
- NEW: Success/failure toast notifications with color-coded feedback
- NEW: Proper file permissions and visibility in file system
- NEW: Enhanced error handling with detailed logging for debugging
๐จ Usage Examples #
Basic Context Menu
CustomNetworkImage(
url: 'https://example.com/image.jpg',
width: 300,
height: 200,
// โ
NEW: Enable right-click context menu
enableContextMenu: true,
// โ
NEW: Handle context menu actions
onContextMenuAction: (action) {
print('Context menu action: $action');
},
)
Custom Context Menu Items
CustomNetworkImage(
url: 'https://example.com/image.jpg',
enableContextMenu: true,
// โ
NEW: Custom menu items with icons
customContextMenuItems: [
ContextMenuItem(
title: 'Download Image',
icon: Icons.download,
action: ContextMenuAction.saveImage,
),
ContextMenuItem(
title: 'Copy to Clipboard',
icon: Icons.copy,
action: ContextMenuAction.copyImage,
),
ContextMenuItem(
title: 'Custom Action',
icon: Icons.star,
action: ContextMenuAction.custom,
onTap: () {
// Custom action handler
print('Custom action executed!');
},
),
],
// โ
NEW: Custom styling
contextMenuBackgroundColor: Colors.grey[800],
contextMenuTextColor: Colors.white,
contextMenuElevation: 8.0,
contextMenuBorderRadius: BorderRadius.circular(12),
)
Context Menu with Toast Notifications
CustomNetworkImage(
url: 'https://example.com/image.jpg',
enableContextMenu: true,
onContextMenuAction: (action) {
// Toast notifications automatically shown for:
// โ
Image saved successfully!
// โ Failed to save image
// Image copied to clipboard
// Image URL copied to clipboard
// Opening image in new tab
},
)
๐ ๏ธ Technical Implementation #
New Classes & Enums
// Context menu item definition
class ContextMenuItem {
final String title;
final IconData? icon;
final ContextMenuAction action;
final VoidCallback? onTap;
}
// Available context menu actions
enum ContextMenuAction {
copyImage, // Copy image to clipboard
saveImage, // Save image with file picker
openImageInNewTab, // Open in new browser tab
copyImageUrl, // Copy URL to clipboard
custom, // Custom action with onTap callback
}
Context Menu Parameters
CustomNetworkImage(
// Context menu control
enableContextMenu: true, // Enable/disable context menu
customContextMenuItems: [...], // Custom menu items
onContextMenuAction: (action) => {...}, // Action callback
// Styling options
contextMenuBackgroundColor: Colors.white, // Background color
contextMenuTextColor: Colors.black, // Text color
contextMenuElevation: 8.0, // Shadow elevation
contextMenuBorderRadius: BorderRadius.circular(8), // Corner radius
contextMenuPadding: EdgeInsets.all(8), // Internal padding
)
๐ Platform Support & Behavior #
Web Platform (Primary Target)
- โ Full context menu functionality with native-like behavior
- โ File System Access API for proper save dialogs with location picker
- โ Clipboard API integration for image and URL copying
- โ Browser context menu prevention only when hovering over images
- โ Toast notifications for user feedback
Mobile/Desktop Platforms
- โ ๏ธ Limited support - Context menus are primarily a web/desktop concept
- โ Hover icons remain available as alternative for touch interfaces
- โ Manual download/copy buttons continue to work normally
๐ฏ Smart Context Menu Features #
Intelligent Positioning
- Auto-adjustment: Menu automatically repositions to stay on screen
- Edge detection: Prevents menu from going off screen edges
- Responsive sizing: Adapts to different screen sizes and orientations
State-Aware Behavior
- Loading state: Context menu available during image loading
- Loaded state: Full functionality with image data access
- Error state: Context menu still works with URL-based actions
- HTML fallback: Context menu overlays HTML img elements
Browser Integration
- Selective prevention: Only prevents browser context menu when over images
- Normal browsing: Browser context menu works normally on text, links, etc.
- Download integration: Uses browser's download system for familiar UX
๐ง Enhanced Download System #
File System Access API (Modern Browsers)
- Save dialog: Shows native file picker for choosing save location
- File permissions: Proper file permissions for visibility in file managers
- Progress feedback: Toast notifications for save success/failure
- User control: Full control over save location and filename
Fallback Download Methods
- Blob download: Traditional browser download to Downloads folder
- Direct download: URL-based download as last resort
- Error handling: Graceful degradation with detailed error logging
๐ฑ Example Integration #
Complete Context Menu Demo
class ContextMenuDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomNetworkImage(
url: 'https://picsum.photos/300/200',
width: 300,
height: 200,
// Enable context menu with default items
enableContextMenu: true,
// Custom styling
contextMenuBackgroundColor: Colors.grey[800],
contextMenuTextColor: Colors.white,
contextMenuElevation: 12.0,
contextMenuBorderRadius: BorderRadius.circular(8),
// Handle actions
onContextMenuAction: (action) {
switch (action) {
case ContextMenuAction.copyImage:
// Image copied to clipboard automatically
break;
case ContextMenuAction.saveImage:
// Save dialog shown automatically
break;
case ContextMenuAction.openImageInNewTab:
// Image opened in new tab automatically
break;
case ContextMenuAction.copyImageUrl:
// URL copied to clipboard automatically
break;
}
},
);
}
}
๐ Backward Compatibility #
- 100% backward compatible - existing code continues to work unchanged
- Optional feature - context menu is opt-in via
enableContextMenuparameter - No conflicts - works alongside existing hover icons and callbacks
- Progressive enhancement - add context menu to existing implementations gradually
๐งช Comprehensive Testing #
- Cross-browser testing on Chrome, Firefox, Safari, Edge
- File System Access API testing with save dialog functionality
- Clipboard integration testing with copy/paste operations
- Context menu positioning testing near screen edges
- Toast notification testing for user feedback
- Error handling testing for various failure scenarios
0.3.2 Controller Feature Release #
๐ New Major Features #
External Controller System
- NEW:
CustomNetworkImageControllerfor external image management and control - NEW:
controllerparameter inCustomNetworkImagefor linking external controller - NEW: External methods for image operations:
controller.reload()- Reload image from URLcontroller.downloadImage()- Download image to devicecontroller.copyImageToClipboard()- Copy image to system clipboardcontroller.getCurrentImageData()- Get current image datacontroller.waitForLoad()- Wait for image loading with timeout
Real-time State Management
- NEW: Live state monitoring with
ChangeNotifierintegration:controller.isLoading- Check if image is currently loadingcontroller.isLoaded- Check if image loaded successfullycontroller.isFailed- Check if image failed to loadcontroller.hasImageData- Check if image data is availablecontroller.loadingProgress- Get current loading progresscontroller.errorMessage- Get current error message
Multiple Controller Support
- NEW: Use separate controllers for different images in same widget tree
- NEW: Independent state management for each image instance
- NEW: External control of multiple images simultaneously
๐๏ธ Architecture Improvements #
Code Refactoring & Separation
- NEW:
lib/src/types.dart- Shared types and enums for better organization - NEW:
lib/src/custom_network_image_controller.dart- Dedicated controller implementation - IMPROVED: Removed duplicate type definitions across files
- IMPROVED: Better import structure and dependency management
- IMPROVED: Cleaner codebase with separated concerns
Enhanced Library Exports
- NEW: Export controller and types for external usage
- NEW: Public API access to
CustomNetworkImageController - NEW: Access to
ImageLoadingState,CustomImageProgress,ImageDataInfo - NEW: Public access to
ImageClipboardHelperfor manual operations
๐ฎ Usage Examples #
Basic Controller Usage
final controller = CustomNetworkImageController();
// Listen to state changes
controller.addListener(() {
print('Loading state: ${controller.loadingState}');
if (controller.isLoaded) {
print('Image ready: ${controller.imageData?.width}x${controller.imageData?.height}');
}
});
// Use with widget
CustomNetworkImage(
url: 'https://example.com/image.jpg',
controller: controller,
downloadIcon: Icon(Icons.download),
copyIcon: Icon(Icons.copy),
)
// External control
await controller.downloadImage();
await controller.copyImageToClipboard();
controller.reload();
Multiple Controllers
class MultiImageWidget extends StatefulWidget {
@override
_MultiImageWidgetState createState() => _MultiImageWidgetState();
}
class _MultiImageWidgetState extends State<MultiImageWidget> {
late CustomNetworkImageController controller1;
late CustomNetworkImageController controller2;
@override
void initState() {
super.initState();
controller1 = CustomNetworkImageController();
controller2 = CustomNetworkImageController();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: Column(
children: [
CustomNetworkImage(
url: 'https://example.com/image1.jpg',
controller: controller1,
),
ElevatedButton(
onPressed: () => controller1.reload(),
child: Text('Reload Image 1'),
),
],
),
),
Expanded(
child: Column(
children: [
CustomNetworkImage(
url: 'https://example.com/image2.jpg',
controller: controller2,
),
ElevatedButton(
onPressed: () => controller2.downloadImage(),
child: Text('Download Image 2'),
),
],
),
),
],
);
}
@override
void dispose() {
controller1.dispose();
controller2.dispose();
super.dispose();
}
}
๐ง Technical Implementation #
Controller State Management
class CustomNetworkImageController extends ChangeNotifier {
// State properties
ImageLoadingState get loadingState;
CustomImageProgress? get loadingProgress;
ImageDataInfo? get imageData;
String? get errorMessage;
// Convenience getters
bool get isLoading;
bool get isLoaded;
bool get isFailed;
bool get hasImageData;
// Control methods
void reload();
Future<bool> downloadImage();
Future<bool> copyImageToClipboard();
Future<ImageDataInfo> waitForLoad({Duration timeout});
}
Integration with Existing Features
- Full Compatibility: Controller works alongside all existing hover icons and callbacks
- State Sync: Widget state automatically syncs with controller state
- Error Handling: Controller captures and exposes all error states
- Progress Tracking: Real-time loading progress available through controller
๐ฑ Enhanced Example App #
- NEW: Comprehensive controller demonstration in
example/simple_usage_example.dart - NEW: Live status panel showing controller state in real-time
- NEW: External action buttons for controller methods
- NEW: Multiple controller examples with independent control
- NEW: Status tracking and error handling demonstrations
๐ Backward Compatibility #
- 100% Backward Compatible: All existing code continues to work unchanged
- Optional Enhancement: Controller is optional - existing callback/hover icon patterns still work
- Progressive Adoption: Add controller gradually to existing implementations
- No Breaking Changes: All existing parameters and functionality preserved
๐ ๏ธ Developer Experience #
- Type Safety: Full TypeScript-like type safety with controller state
- IntelliSense: Rich IDE support for controller methods and properties
- Documentation: Comprehensive inline documentation for all new features
- Examples: Multiple usage patterns and best practices demonstrated
0.3.1 Clipboard Fix Release #
๐ Bug Fixes #
- Fixed Clipboard Copying Issue: Resolved critical bug where clipboard copying failed with "DataError: Failed to read or decode ClipboardItemData for type image/png"
- Root Cause: Complex JavaScript object manipulation wasn't reliable across browsers
- Solution: Implemented simplified JavaScript approach using direct script injection
- New Method: Created
_simpleClipboardCopy()with cleaner function definition in global scope - Better Error Handling: Added proper cleanup and graceful fallback to alternative methods
- Multi-Method Fallback: Now tries 3 different approaches if one fails
๐ง Technical Changes #
- Simplified Clipboard API: More reliable ClipboardItem creation using direct JavaScript functions
- Enhanced Fallback System: Canvas-based approach as secondary method, legacy fallback as tertiary
- Improved Error Logging: Better debugging information to identify which copy method succeeds
- Resource Management: Proper cleanup of created script elements to prevent memory leaks
๐งช Validation #
- โ Copy icon click now successfully copies images to clipboard
- โ Ctrl+V pasting works correctly in external applications
- โ Multiple fallback methods ensure compatibility across different browsers
- โ Proper error messages and graceful degradation when clipboard access is restricted
0.3.0 Major Feature Release: Hover Icons & Image Data Access #
๐ New Major Features #
Image Data Callback System
- NEW:
onImageLoadedcallback provides immediate access to image data when loading completes - NEW:
ImageDataInfoclass contains image bytes, dimensions, and URL for copy/download operations - Feature: No waiting required - image data available instantly after load for clipboard/download functionality
Hover Icons with Smart Positioning
- NEW:
downloadIconandcopyIconparameters for custom action icons that appear on hover - NEW: 6 positioning options via
HoverIconPositionenum:topLeft,topRight,bottomLeft,bottomRight,topCenter,bottomCenter
- NEW: 3 layout modes via
HoverIconLayoutenum:auto- Smart layout based on positionrow- Always horizontal arrangementcolumn- Always vertical arrangement
- NEW: Customizable spacing (
hoverIconSpacing) and padding (hoverIconPadding) - NEW:
enableHoverIconstoggle for full control
Advanced Clipboard & Download System
- NEW: Separate
downloadImage()andcopyImageToClipboard()methods with distinct behaviors:- Download: Saves PNG file to computer (web: Downloads folder, mobile: temp directory)
- Copy: Copies image to system clipboard for pasting with Ctrl+V
- NEW: Cross-platform clipboard support using modern Clipboard API on web
- NEW: Custom action callbacks:
onDownloadTapandonCopyTapfor overriding default behaviors
Enhanced User Experience
- NEW: Smart hover detection with smooth icon transitions (web/desktop only)
- NEW: Material design click feedback with
InkWellintegration - NEW: Comprehensive example app showcasing all features with live controls
- NEW: Real-time customization via control panel (position, layout, spacing, padding)
๐จ Usage Examples #
Basic Hover Icons
CustomNetworkImage(
url: 'https://example.com/image.jpg',
// โ
NEW: Hover icons for quick actions
downloadIcon: Icon(Icons.download, color: Colors.white, size: 20),
copyIcon: Icon(Icons.copy, color: Colors.white, size: 20),
hoverIconPosition: HoverIconPosition.topRight,
// โ
NEW: Get image data when loaded
onImageLoaded: (ImageDataInfo imageData) {
print('Image ready! Size: ${imageData.width}x${imageData.height}');
// imageData.imageBytes contains raw PNG data for copying/saving
},
)
Advanced Styled Icons
CustomNetworkImage(
url: imageUrl,
downloadIcon: Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [Colors.blue, Colors.blueAccent]),
borderRadius: BorderRadius.circular(8),
boxShadow: [BoxShadow(color: Colors.black26, blurRadius: 4)],
),
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.download, color: Colors.white, size: 16),
SizedBox(width: 4),
Text('Download', style: TextStyle(color: Colors.white)),
],
),
),
hoverIconPosition: HoverIconPosition.bottomRight,
hoverIconLayout: HoverIconLayout.row,
// โ
Custom action callbacks
onDownloadTap: () => customDownloadHandler(),
onCopyTap: () => customCopyHandler(),
)
Using Image Data for Copy Operations
ImageDataInfo? _imageData;
CustomNetworkImage(
url: imageUrl,
onImageLoaded: (imageData) {
setState(() => _imageData = imageData);
},
)
// Later, copy to clipboard
ElevatedButton(
onPressed: () async {
if (_imageData != null) {
final success = await ImageClipboardHelper.copyImageToClipboard(_imageData!);
// Image is now in clipboard, ready for Ctrl+V pasting!
}
},
child: Text('Copy Image'),
)
๐ ๏ธ Technical Implementation #
New Classes & Enums
// Image data container
class ImageDataInfo {
final Uint8List imageBytes; // Raw PNG data
final int width, height; // Dimensions
final String url; // Original URL
}
// Icon positioning
enum HoverIconPosition {
topLeft, topRight, bottomLeft, bottomRight, topCenter, bottomCenter
}
// Layout direction
enum HoverIconLayout {
auto, row, column
}
New Helper Methods
// Clipboard & Download
ImageClipboardHelper.copyImageToClipboard(imageData) // Clipboard copy
ImageClipboardHelper.downloadImage(imageData) // File download
// Platform-specific implementations
copyImageToClipboardWeb(imageData) // Web Clipboard API
downloadImageWeb(imageData) // Web file download
๐ง Platform Support #
- Web: Full clipboard copying + file downloads using modern Clipboard API and blob downloads
- Mobile: Temp file saving + basic clipboard support (extensible with plugins)
- Desktop: File path copying + temp file saving
๐ฑ Responsive Design #
- Hover icons: Auto-enabled on web/desktop, disabled on mobile (no hover support)
- Touch support: Icons work with touch on platforms that support hover simulation
- Adaptive layouts: Smart icon positioning based on screen real estate
๐งช Comprehensive Testing #
- Interactive example app with live controls for all parameters
- Position examples grid showing all 6 positions
- Layout comparison demonstrating row vs column vs auto layouts
- Real-time customization via sliders and toggles
๐ Backward Compatibility #
- 100% backward compatible - existing code continues to work unchanged
- Optional features - all new parameters have sensible defaults
- Progressive enhancement - add hover icons gradually to existing implementations
0.2.1 Bug Fix Release #
๐ Bug Fixes #
- Alternative to Buggy Flutter loadingBuilder: Implemented custom loading state management to replace Flutter's problematic
loadingBuilder- Replaced
loadingBuilderparameter withcustomLoadingBuilderthat usesCustomImageProgress - Added reliable progress tracking via
ImageStreamandImageStreamListener - Fixed memory leaks and inconsistent progress reporting issues
- Added proper resource cleanup with
_cleanupImageStream()method
- Replaced
๐ New Features #
- Custom Loading Progress Tracking: New
CustomImageProgressclass provides reliable loading progress information - Enhanced Loading State Management: Added
ImageLoadingStateenum for better loading state control - Improved Resource Management: Automatic cleanup of image streams and listeners to prevent memory leaks
๐ Migration Guide #
// OLD (buggy Flutter loadingBuilder)
CustomNetworkImage(
url: imageUrl,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return CircularProgressIndicator(
value: loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!,
);
},
)
// NEW (reliable customLoadingBuilder)
CustomNetworkImage(
url: imageUrl,
customLoadingBuilder: (context, child, progress) {
if (progress == null) return child;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(value: progress.progress),
if (progress.progress != null)
Text('${(progress.progress! * 100).toInt()}%'),
],
);
},
)
๐ ๏ธ Technical Changes #
- Manual image loading progress tracking via
onChunkcallback - Proper state management for loading, loaded, and failed states
- Enhanced error handling integration with existing fallback mechanisms
- Backward compatibility maintained for existing error handling features
0.2.0 BREAKING CHANGES #
๐ New Features #
- Widget-based Error Handling: Introduced new widget parameters for more flexible error UI customization:
errorWidget- Custom widget to show when image fails to loadreloadWidget- Custom widget for retry functionalityopenUrlWidget- Custom widget for opening image URL in new tab
- Flutter-based Error UI: HTML errors now callback to Flutter for consistent error handling across platforms
- Enhanced Error Flow: When HTML image loading fails, errors are now handled in Flutter using the new widget parameters
โ ๏ธ Breaking Changes #
- HTML Error Handling: HTML errors no longer show HTML-based error UI. Instead, they trigger Flutter callbacks for consistent widget-based error handling.
- Deprecated Parameters: The following string-based parameters are now deprecated and will be removed in v1.0.0:
errorTextโ UseerrorWidgetinsteadreloadTextโ UsereloadWidgetinsteadopenUrlTextโ UseopenUrlWidgetinstead
๐ Migration Guide #
// OLD (deprecated but still works)
CustomNetworkImage(
url: imageUrl,
errorText: 'Image failed to load',
reloadText: 'Reload Image',
openUrlText: 'Open in New Tab',
)
// NEW (recommended)
CustomNetworkImage(
url: imageUrl,
errorWidget: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.error, color: Colors.red),
SizedBox(width: 8),
Text('Image failed to load'),
],
),
reloadWidget: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.refresh),
SizedBox(width: 8),
Text('Reload Image'),
],
),
openUrlWidget: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.open_in_new),
SizedBox(width: 8),
Text('Open in New Tab'),
],
),
)
๐ ๏ธ Technical Changes #
- Added HTML error callback mechanism for Flutter integration
- Removed HTML-based error UI generation from
web_image_loader.dart - Enhanced
CustomNetworkImagestate management for error handling - Improved backward compatibility with automatic fallback from deprecated parameters
๐ Documentation #
- Updated examples to demonstrate new widget-based error handling
- Added migration guide in example app
- Updated README with v0.2.0 usage patterns
0.1.9 #
- Fixed: Resolved issue where error placeholder was not being displayed correctly
- Fixed: Resolved issue where error placeholder was not being displayed correctly
0.1.8 #
- Fixed: Resolved issue where error placeholder was not being displayed correctly
- Fixed: Resolved issue where error placeholder was not being displayed correctly
0.1.7 #
- Added: Internationalization support for error handling - supports custom text for error messages and buttons
- Enhanced: Error placeholder now includes reload and "open in new tab" functionality when HTML image loading fails
- Added:
errorText,reloadText, andopenUrlTextparameters to CustomNetworkImage for multilingual support - Improved: Error UI can show only icons when no text is provided (icon-only mode for universal understanding)
- Added: Reload button to retry failed images without page refresh
- Added: "Open in new tab" button to view the problematic image URL directly
0.1.6 #
- Fixed: Resolved tap event conflicts in ListViews with mixed HTML fallback and normal images
- Update README.md
0.1.5 #
- Fixed: Resolved tap event conflicts in ListViews with mixed HTML fallback and normal images
- Added: Per-image tap callback tracking to prevent event confusion
- Added: uniqueId parameter to CustomNetworkImage for better control in lists
- Improved: Event propagation handling with stopPropagation() to isolate tap events
- Added: Proper cleanup of resources when widgets are disposed
0.1.4 #
- Fixed: Dramatically improved smoothness of panning/dragging in InteractiveViewer with HTML fallback images
- Added: Animation controller for continuous transformation updates during gestures
- Improved: Full matrix transformation for more accurate CSS transforms
- Fixed: Pointer events handling for smoother gesture recognition
0.1.3 #
- Fixed: InteractiveViewer zoom functionality now works with HTML fallback images
- Added: TransformationController support for CustomNetworkImage
- Improved: Object-fit set to 'contain' for better zooming behavior
- Fixed: Proper transformation handling for HTML elements
0.1.2 #
- Fixed: GestureDetector tap events now work correctly with problematic images using HTML fallback
- Added: onTap callback property to CustomNetworkImage for easier tap handling
- Improved: Visual feedback with cursor pointer on HTML fallback images
0.1.1 #
- Updated intl dependency to support a wider range of versions (>=0.19.0 <0.21.0)
- Improved compatibility with projects that depend on intl 0.19.0
0.1.0 #
- Initial release with image loading solution:
- CustomNetworkImage: Uses HTML img tag as fallback
- Support for all standard Image.network parameters
- Full web platform support for problematic images
- Example app showing how to use the approach