didvan-app/lib/views/widgets/skeleton_image.dart

92 lines
3.4 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:cached_network_image/cached_network_image.dart';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
// ignore: depend_on_referenced_packages
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
class SkeletonImage extends StatelessWidget {
final String imageUrl;
final double? width;
final double? height;
final double? pWidth;
final double? pHeight;
final BorderRadius? borderRadius;
final double? aspectRatio;
/// نحوه‌ی fit کردن تصویر در container. مقدار پیش‌فرض `BoxFit.cover` است
/// (برای کارت‌های سبک پادکست/خبر). برای صفحه‌هایی مثل اینفوگرافی که
/// می‌خواهیم کل تصویر پیدا باشد، `BoxFit.contain` پاس داده می‌شود.
final BoxFit? fit;
const SkeletonImage({
Key? key,
required this.imageUrl,
this.borderRadius = DesignConfig.lowBorderRadius,
this.aspectRatio,
this.width,
this.height,
this.pWidth,
this.pHeight,
this.fit,
}) : super(key: key);
@override
Widget build(BuildContext context) {
// URL نهاییِ تصویر را می‌سازیم.
final finalUrl =
imageUrl.startsWith('http') || imageUrl.contains(RequestHelper.baseUrl)
? imageUrl.replaceAll('\n', '')
: RequestHelper.baseUrl + imageUrl.replaceAll('\n', '');
// Bearer token را فقط برای دامنه‌های خودمان می‌فرستیم.
// URLهای signed-شده‌ی S3 (Arvan) signature خاص دارند و اگر هدر
// Authorization اضافه شود، با 400 رد می‌شوند.
final isOwnDomain = finalUrl.contains('didvan.app') ||
finalUrl.contains('didvan.com');
final headers = <String, String>{
if (isOwnDomain && RequestService.token != null)
'Authorization': 'Bearer ${RequestService.token}',
};
return _aspectRatioGenerator(
child: ClipRRect(
borderRadius: borderRadius ?? BorderRadius.zero,
child: CachedNetworkImage(
errorWidget: (context, url, error) {
if (kDebugMode) {
print('image fetch compelete with Error: $error');
}
return Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.disabledBackground),
child: const Icon(Icons.image_not_supported_outlined));
},
errorListener: (value) {},
fit: fit ?? (kIsWeb ? BoxFit.fill : BoxFit.cover),
imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet,
httpHeaders: headers,
width: width,
height: height,
imageUrl: finalUrl,
placeholder: (context, _) => ShimmerPlaceholder(
width: pWidth,
height: pHeight,
),
),
),
);
}
Widget _aspectRatioGenerator({required Widget child}) => aspectRatio == null
? child
: AspectRatio(
key: ValueKey(imageUrl),
aspectRatio: aspectRatio!,
child: child,
);
}