Files
PiliPlus/lib/common/widgets/network_img_layer.dart
bggRGjQaUbCoE ff80385a2e fix: dyn square widget
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
2025-01-22 21:32:48 +08:00

125 lines
4.0 KiB
Dart

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/global_data.dart';
import '../constants.dart';
class NetworkImgLayer extends StatelessWidget {
const NetworkImgLayer({
super.key,
this.src,
required this.width,
required this.height,
this.type,
this.fadeOutDuration,
this.fadeInDuration,
// 图片质量 默认1%
this.quality,
this.semanticsLabel,
this.ignoreHeight,
this.radius,
this.imageBuilder,
this.isLongPic,
this.callback,
this.getPlaceHolder,
});
final String? src;
final double width;
final double height;
final String? type;
final Duration? fadeOutDuration;
final Duration? fadeInDuration;
final int? quality;
final String? semanticsLabel;
final bool? ignoreHeight;
final double? radius;
final ImageWidgetBuilder? imageBuilder;
final Function? isLongPic;
final Function? callback;
final Function? getPlaceHolder;
@override
Widget build(BuildContext context) {
return src.isNullOrEmpty.not
? type == 'avatar'
? ClipOval(child: _buildImage(context))
: radius == 0 || type == 'emote'
? _buildImage(context)
: ClipRRect(
borderRadius: BorderRadius.circular(
radius ?? StyleString.imgRadius.x,
),
child: _buildImage(context),
)
: getPlaceHolder?.call() ?? placeholder(context);
}
Widget _buildImage(context) {
late final int defaultImgQuality = GlobalData().imgQuality;
bool thumbnail = true;
int? memCacheWidth, memCacheHeight;
if (callback?.call() == true || width <= height) {
memCacheWidth = width.cacheSize(context);
} else {
memCacheHeight = height.cacheSize(context);
}
return CachedNetworkImage(
imageUrl:
'${src?.startsWith('//') == true ? 'https:$src' : src?.http2https}${type != 'emote' && type != 'cover' && thumbnail ? '@${quality ?? defaultImgQuality}q.webp' : ''}',
width: width,
height: ignoreHeight == null || ignoreHeight == false ? height : null,
memCacheWidth: memCacheWidth,
memCacheHeight: memCacheHeight,
fit: BoxFit.cover,
alignment:
isLongPic?.call() == true ? Alignment.topCenter : Alignment.center,
fadeOutDuration: fadeOutDuration ?? const Duration(milliseconds: 120),
fadeInDuration: fadeInDuration ?? const Duration(milliseconds: 120),
filterQuality: FilterQuality.low,
// errorWidget: (BuildContext context, String url, Object error) =>
// placeholder(context),
placeholder: (BuildContext context, String url) =>
getPlaceHolder?.call() ?? placeholder(context),
imageBuilder: imageBuilder,
// errorListener: (value) {
// thumbnail = false;
// if (context.mounted) {
// (context as Element).markNeedsBuild();
// }
// },
);
}
Widget placeholder(BuildContext context) {
int cacheWidth = width.cacheSize(context);
return Container(
width: width,
height: height,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: type == 'avatar' ? BoxShape.circle : BoxShape.rectangle,
color: Theme.of(context).colorScheme.onInverseSurface.withOpacity(0.4),
borderRadius: type == 'avatar' || type == 'emote' || radius == 0
? null
: BorderRadius.circular(
radius ?? StyleString.imgRadius.x,
),
),
child: type == 'bg'
? const SizedBox()
: Center(
child: Image.asset(
type == 'avatar'
? 'assets/images/noface.jpeg'
: 'assets/images/loading.png',
width: width,
height: height,
cacheWidth: cacheWidth == 0 ? null : cacheWidth,
// cacheHeight: height.cacheSize(context),
),
),
);
}
}