mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-18 08:06:21 +08:00
* opt: unused layout * mod: semantics * opt: DanmakuMsg type * opt: avoid cast * opt: unnecessary_lambdas * opt: use isEven * opt: logger * opt: invalid common page * tweak * opt: unify DynController
135 lines
4.2 KiB
Dart
135 lines
4.2 KiB
Dart
import 'package:PiliPlus/common/constants.dart';
|
|
import 'package:PiliPlus/models/common/image_type.dart';
|
|
import 'package:PiliPlus/utils/extension.dart';
|
|
import 'package:PiliPlus/utils/image_util.dart';
|
|
import 'package:PiliPlus/utils/storage_pref.dart';
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
class NetworkImgLayer extends StatelessWidget {
|
|
const NetworkImgLayer({
|
|
super.key,
|
|
required this.src,
|
|
required this.width,
|
|
this.height,
|
|
this.type = ImageType.def,
|
|
this.fadeOutDuration,
|
|
this.fadeInDuration,
|
|
// 图片质量 默认1%
|
|
this.quality,
|
|
this.semanticsLabel,
|
|
this.radius,
|
|
this.imageBuilder,
|
|
this.isLongPic = false,
|
|
this.forceUseCacheWidth = false,
|
|
this.getPlaceHolder,
|
|
this.boxFit,
|
|
});
|
|
|
|
final String? src;
|
|
final double width;
|
|
final double? height;
|
|
final ImageType type;
|
|
final Duration? fadeOutDuration;
|
|
final Duration? fadeInDuration;
|
|
final int? quality;
|
|
final String? semanticsLabel;
|
|
final double? radius;
|
|
final ImageWidgetBuilder? imageBuilder;
|
|
final bool isLongPic;
|
|
final bool forceUseCacheWidth;
|
|
final Widget Function()? getPlaceHolder;
|
|
final BoxFit? boxFit;
|
|
|
|
static Color? reduceLuxColor = Pref.reduceLuxColor;
|
|
static bool reduce = false;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final noRadius = type == ImageType.emote || radius == 0;
|
|
final Widget child;
|
|
|
|
if (src?.isNotEmpty == true) {
|
|
child = noRadius
|
|
? _buildImage(context, noRadius)
|
|
: type == ImageType.avatar
|
|
? ClipOval(child: _buildImage(context, noRadius))
|
|
: ClipRRect(
|
|
borderRadius: radius != null
|
|
? BorderRadius.circular(radius!)
|
|
: StyleString.mdRadius,
|
|
child: _buildImage(context, noRadius),
|
|
);
|
|
} else {
|
|
child = getPlaceHolder?.call() ?? _placeholder(context, noRadius);
|
|
}
|
|
|
|
return semanticsLabel?.isNotEmpty == true
|
|
? Semantics(
|
|
container: true,
|
|
image: true,
|
|
excludeSemantics: true,
|
|
label: semanticsLabel,
|
|
child: child,
|
|
)
|
|
: child;
|
|
}
|
|
|
|
Widget _buildImage(BuildContext context, bool noRadius) {
|
|
int? memCacheWidth, memCacheHeight;
|
|
if (height == null || forceUseCacheWidth || width <= height!) {
|
|
memCacheWidth = width.cacheSize(context);
|
|
} else {
|
|
memCacheHeight = height.cacheSize(context);
|
|
}
|
|
return CachedNetworkImage(
|
|
imageUrl: ImageUtil.thumbnailUrl(src, quality),
|
|
width: width,
|
|
height: height,
|
|
memCacheWidth: memCacheWidth,
|
|
memCacheHeight: memCacheHeight,
|
|
fit: boxFit ?? BoxFit.cover,
|
|
alignment: isLongPic ? Alignment.topCenter : Alignment.center,
|
|
fadeOutDuration: fadeOutDuration ?? const Duration(milliseconds: 120),
|
|
fadeInDuration: fadeInDuration ?? const Duration(milliseconds: 120),
|
|
filterQuality: FilterQuality.low,
|
|
placeholder: (BuildContext context, String url) =>
|
|
getPlaceHolder?.call() ?? _placeholder(context, noRadius),
|
|
imageBuilder: imageBuilder,
|
|
errorWidget: (context, url, error) => _placeholder(context, noRadius),
|
|
colorBlendMode: reduce ? BlendMode.modulate : null,
|
|
color: reduce ? reduceLuxColor : null,
|
|
);
|
|
}
|
|
|
|
Widget _placeholder(BuildContext context, bool noRadius) {
|
|
final isAvatar = type == ImageType.avatar;
|
|
return Container(
|
|
width: width,
|
|
height: height,
|
|
clipBehavior: noRadius ? Clip.none : Clip.antiAlias,
|
|
decoration: BoxDecoration(
|
|
shape: isAvatar ? BoxShape.circle : BoxShape.rectangle,
|
|
color: Theme.of(
|
|
context,
|
|
).colorScheme.onInverseSurface.withValues(alpha: 0.4),
|
|
borderRadius: noRadius || isAvatar
|
|
? null
|
|
: radius != null
|
|
? BorderRadius.circular(radius!)
|
|
: StyleString.mdRadius,
|
|
),
|
|
child: Center(
|
|
child: Image.asset(
|
|
isAvatar ? 'assets/images/noface.jpeg' : 'assets/images/loading.png',
|
|
width: width,
|
|
height: height,
|
|
cacheWidth: width.cacheSize(context),
|
|
colorBlendMode: reduce ? BlendMode.modulate : null,
|
|
color: reduce ? reduceLuxColor : null,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|