Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-02-26 20:09:03 +08:00
parent fdb3bf3edc
commit 65ad8a0fdc
8 changed files with 74 additions and 31 deletions

View File

@@ -0,0 +1,26 @@
import 'package:flutter/widgets.dart';
Widget fromHero({
required Object tag,
required Widget child,
}) => Hero(
tag: tag,
createRectTween: createEndRectTween,
child: child,
);
RectTween createEndRectTween(Rect? begin, Rect? end) {
if (begin != null && end != null) {
final endWidth = end.width;
final endHeight = end.height;
// TODO: use real image rect
final beginRect = Rect.fromLTWH(
begin.left + (begin.width - endWidth) / 2,
begin.top + (begin.height - endHeight) / 2,
endWidth,
endHeight,
);
return RectTween(begin: beginRect, end: end);
}
return RectTween(begin: begin, end: end);
}

View File

@@ -1,3 +1,4 @@
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart';
import 'package:PiliPlus/utils/image_utils.dart';
@@ -54,7 +55,7 @@ Widget htmlRender({
imgList: [SourceModel(url: imgUrl)],
quality: 60,
),
child: Hero(
child: fromHero(
tag: imgUrl,
child: CachedNetworkImage(
width: width,

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/cached_network_svg_image.dart';
import 'package:PiliPlus/common/widgets/image/custom_grid_view.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
import 'package:PiliPlus/http/constants.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/models/common/image_type.dart';
@@ -222,26 +223,28 @@ class OpusContent extends StatelessWidget {
? null
: width * pic.height! / pic.width!;
width ??= maxWidth;
Widget child = CachedNetworkImage(
width: width,
height: height,
memCacheWidth: width.cacheSize(context),
imageUrl: ImageUtils.thumbnailUrl(pic.url!, 60),
fadeInDuration: const Duration(milliseconds: 120),
fadeOutDuration: const Duration(milliseconds: 120),
placeholder: (_, _) =>
Image.asset('assets/images/loading.png'),
);
if (!(pic.isLongPic ?? false)) {
child = fromHero(
tag: pic.url!,
child: child,
);
}
return GestureDetector(
onTap: () => PageUtils.imageView(
imgList: [SourceModel(url: pic.url!)],
quality: 60,
),
child: Center(
child: Hero(
tag: pic.url!,
child: CachedNetworkImage(
width: width,
height: height,
memCacheWidth: width.cacheSize(context),
imageUrl: ImageUtils.thumbnailUrl(pic.url!, 60),
fadeInDuration: const Duration(milliseconds: 120),
fadeOutDuration: const Duration(milliseconds: 120),
placeholder: (_, _) =>
Image.asset('assets/images/loading.png'),
),
),
),
child: child,
);
} else {
return CustomGridView(

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.dart';
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
import 'package:PiliPlus/grpc/bilibili/app/listener/v1.pb.dart';
@@ -893,7 +894,7 @@ class _AudioPageState extends State<AudioPage> {
onTap: () => PageUtils.imageView(
imgList: [SourceModel(url: cover)],
),
child: Hero(
child: fromHero(
tag: cover,
child: NetworkImgLayer(
src: cover,

View File

@@ -1,5 +1,6 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/avatars.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart';
@@ -125,7 +126,7 @@ class UserInfoCard extends StatelessWidget {
.http2https;
return GestureDetector(
onTap: () => PageUtils.imageView(imgList: [SourceModel(url: imgUrl)]),
child: Hero(
child: fromHero(
tag: imgUrl,
child: CachedNetworkImage(
fit: .cover,
@@ -454,7 +455,7 @@ class UserInfoCard extends StatelessWidget {
],
);
Widget get _buildAvatar => Hero(
Widget get _buildAvatar => fromHero(
tag: card.face ?? '',
child: PendantAvatar(
avatar: card.face,

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/custom_icon.dart';
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
import 'package:PiliPlus/common/widgets/marquee.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/music.dart';
@@ -439,7 +440,7 @@ class _MusicDetailPageState extends CommonDynPageState<MusicDetailPage> {
onTap: () => PageUtils.imageView(
imgList: [SourceModel(url: item.mvCover!)],
),
child: Hero(
child: fromHero(
tag: item.mvCover!,
child: NetworkImgLayer(
src: item.mvCover,

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
import 'package:PiliPlus/common/widgets/stat/stat.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/models/common/image_type.dart';
@@ -147,7 +148,7 @@ class _PgcIntroPageState extends State<PgcIntroPage> {
onTap: () => PageUtils.imageView(
imgList: [SourceModel(url: item.cover!)],
),
child: Hero(
child: fromHero(
tag: item.cover!,
child: NetworkImgLayer(
width: 115,

View File

@@ -1,10 +1,11 @@
import 'dart:convert';
import 'dart:math';
import 'dart:math' as math;
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
import 'package:PiliPlus/grpc/bilibili/im/interfaces/v1.pb.dart'
show EmotionInfo;
import 'package:PiliPlus/grpc/bilibili/im/type.pb.dart' show Msg, MsgType;
@@ -590,16 +591,24 @@ class ChatItem extends StatelessWidget {
Widget msgTypePic_2(Map content) {
final url = content['url'];
final imgWidth = (content['width'] as num).toDouble();
final imgHeight = (content['height'] as num).toDouble();
final width = math.min(220.0, imgWidth);
final ratio = imgHeight / imgWidth;
Widget child = NetworkImgLayer(
width: width,
height: width * ratio,
src: url,
);
if (ratio <= StyleString.imgMaxRatio) {
child = fromHero(
tag: url,
child: child,
);
}
return GestureDetector(
onTap: () => PageUtils.imageView(imgList: [SourceModel(url: url)]),
child: Hero(
tag: url,
child: NetworkImgLayer(
width: 220,
height: 220 * content['height'] / content['width'],
src: url,
),
),
child: child,
);
}
@@ -750,7 +759,7 @@ class ChatItem extends StatelessWidget {
final String? url = content['jump_url'];
return LayoutBuilder(
builder: (context, constraints) {
final maxWidth = max(400.0, constraints.maxWidth);
final maxWidth = math.max(400.0, constraints.maxWidth);
Widget child = ClipRRect(
borderRadius: StyleString.mdRadius,
child: CachedNetworkImage(