getPresentationWidgetsCommonCachedImageTemplate function

String getPresentationWidgetsCommonCachedImageTemplate(
  1. String projectName
)

Implementation

String getPresentationWidgetsCommonCachedImageTemplate(String projectName) {
  return '''
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:${projectName}/presentation/widgets/shimmer_page.dart';

class CommonCachedImage extends StatelessWidget {
  final String? imageUrl;
  final double? width;
  final double? height;
  final BoxFit fit;
  final double borderRadius;

  final Widget? placeholder;
  final Widget? errorWidget;

  final Color placeholderColor;
  final Color? backgroundColor;

  final String? assetFallback;

  final Border? border;

  const CommonCachedImage({
    super.key,
    required this.imageUrl,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
    this.borderRadius = 0,
    this.placeholder,
    this.errorWidget,
    this.placeholderColor = const Color(0xFFF2F2F2),
    this.backgroundColor,
    this.assetFallback,
    this.border,
  });

  /// Validate network URL
  bool get _isValidUrl {
    if (imageUrl == null || imageUrl!.isEmpty) return false;

    final uri = Uri.tryParse(imageUrl!);

    return uri != null &&
        (uri.scheme == 'http' || uri.scheme == 'https') &&
        uri.host.isNotEmpty;
  }

  @override
  Widget build(BuildContext context) {
    final iconSize = _calculateIconSize();

    Widget imageWidget;

    if (_isValidUrl) {
      imageWidget = CachedNetworkImage(
        imageUrl: imageUrl!,
        width: width,
        height: height,
        fit: fit,
        fadeInDuration: const Duration(milliseconds: 200),

        /// Loading placeholder
        placeholder: (context, url) => placeholder ?? _defaultPlaceholder(),

        /// Error widget
        errorWidget: (context, url, error) =>
            errorWidget ?? _defaultError(iconSize),

        /// Optional performance tuning
        memCacheHeight: height?.toInt(),
        memCacheWidth: width?.toInt(),
      );
    } else {
      /// If URL invalid show fallback
      imageWidget = assetFallback != null
          ? Image.asset(assetFallback!, width: width, height: height, fit: fit)
          : _defaultError(iconSize);
    }

    return ClipRRect(
      borderRadius: BorderRadius.circular(borderRadius),
      child: Container(
        width: width,
        height: height,
        decoration: BoxDecoration(
          color: backgroundColor,
          border: border,
          borderRadius: BorderRadius.circular(borderRadius),
        ),
        child: imageWidget,
      ),
    );
  }

  /// Default shimmer placeholder
  Widget _defaultPlaceholder() {
    return Container(
      width: width,
      height: height,
      color: placeholderColor,
      alignment: Alignment.center,
      child: const ShimmerPage(),
    );
  }

  /// Default error widget
  Widget _defaultError(double iconSize) {
    return Container(
      width: width,
      height: height,
      color: placeholderColor,
      alignment: Alignment.center,
      child: Icon(
        Icons.image_not_supported_outlined,
        size: iconSize,
        color: Colors.grey.shade500,
      ),
    );
  }

  /// Auto calculate icon size based on container
  double _calculateIconSize() {
    if (width != null && height != null) {
      return (width! < height! ? width! : height!) * 0.35;
    }

    if (width != null) return width! * 0.35;

    if (height != null) return height! * 0.35;

    return 30;
  }
}
''';
}