MIF_E31231623/android/wisata_app/lib/widgets/destination_image.dart

135 lines
3.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:wisata_app/widgets/platform_network_image.dart';
class DestinationImage extends StatelessWidget {
const DestinationImage({
super.key,
required this.path,
this.fit = BoxFit.cover,
this.width,
this.height,
this.fallbackMessage = 'Gambar gagal dimuat',
});
final String path;
final BoxFit fit;
final double? width;
final double? height;
final String fallbackMessage;
@override
Widget build(BuildContext context) {
final normalizedPath = path.trim().replaceAll('\\', '/');
if (normalizedPath.isEmpty) {
return _DestinationImageFallback(
message: fallbackMessage,
detail: 'URL gambar kosong',
);
}
if (normalizedPath.startsWith('assets/')) {
return Image.asset(
normalizedPath,
fit: fit,
width: width,
height: height,
errorBuilder: (context, error, stackTrace) {
debugPrint('ERROR ASSET IMAGE: $error');
debugPrint('FAILED ASSET: $normalizedPath');
return _DestinationImageFallback(
message: fallbackMessage,
detail: normalizedPath,
);
},
);
}
final uri = Uri.tryParse(normalizedPath);
if (uri == null || !uri.hasScheme || uri.host.isEmpty) {
debugPrint('INVALID IMAGE URL: $normalizedPath');
return _DestinationImageFallback(
message: fallbackMessage,
detail: normalizedPath,
);
}
return buildPlatformNetworkImage(
uri: uri,
fit: fit,
width: width,
height: height,
loadingBuilder: () => const ColoredBox(
color: Color(0xFFE5E7EB),
child: Center(
child: SizedBox.square(
dimension: 28,
child: CircularProgressIndicator(strokeWidth: 2.4),
),
),
),
errorBuilder: (error) {
debugPrint('ERROR IMAGE: $error');
debugPrint('FAILED URL: ${uri.toString()}');
return _DestinationImageFallback(
message: fallbackMessage,
detail: uri.toString(),
);
},
);
}
}
class _DestinationImageFallback extends StatelessWidget {
const _DestinationImageFallback({
required this.message,
required this.detail,
});
final String message;
final String detail;
@override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF083A63),
Color(0xFF0F4C81),
Color(0xFF2563EB),
],
),
),
child: Center(
child: Padding(
padding: const EdgeInsets.all(18),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.broken_image_rounded,
color: Colors.white,
size: 54,
),
const SizedBox(height: 10),
Text(
'$message\n$detail',
textAlign: TextAlign.center,
maxLines: 4,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w800,
),
),
],
),
),
),
);
}
}