// 内容 import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/widgets/badge.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/models/dynamics/result.dart'; import 'package:pilipala/plugin/pl_gallery/index.dart'; import 'rich_node_panel.dart'; // ignore: must_be_immutable class Content extends StatefulWidget { dynamic item; String? source; Content({ super.key, this.item, this.source, }); @override State createState() => _ContentState(); } class _ContentState extends State { late bool hasPics; List pics = []; @override void initState() { super.initState(); hasPics = widget.item.modules.moduleDynamic.major != null && widget.item.modules.moduleDynamic.major.opus != null && widget.item.modules.moduleDynamic.major.opus.pics.isNotEmpty; if (hasPics) { pics = widget.item.modules.moduleDynamic.major.opus.pics; } } InlineSpan picsNodes() { List spanChilds = []; int len = pics.length; List picList = []; if (len == 1) { OpusPicsModel pictureItem = pics.first; picList.add(pictureItem.url!); /// 图片上方的空白间隔 // spanChilds.add(const TextSpan(text: '\n')); spanChilds.add( WidgetSpan( child: LayoutBuilder( builder: (context, BoxConstraints box) { double maxWidth = box.maxWidth.truncateToDouble(); double maxHeight = box.maxWidth * 0.6; // 设置最大高度 double height = maxWidth * 0.5 * (pictureItem.height != null && pictureItem.width != null ? pictureItem.height! / pictureItem.width! : 1); return Hero( tag: pictureItem.url!, placeholderBuilder: (BuildContext context, Size heroSize, Widget child) { return child; }, child: GestureDetector( onTap: () => onPreviewImg(picList, 1, context), child: Container( padding: const EdgeInsets.only(top: 4), constraints: BoxConstraints(maxHeight: maxHeight), width: box.maxWidth / 2, height: height, child: Stack( children: [ Positioned.fill( child: NetworkImgLayer( src: pictureItem.url, width: maxWidth / 2, height: height, ), ), height > Get.size.height * 0.9 ? const PBadge( text: '长图', right: 8, bottom: 8, ) : const SizedBox(), ], ), ), ), ); }, ), ), ); } if (len > 1) { List list = []; for (var i = 0; i < len; i++) { picList.add(pics[i].url!); } for (var i = 0; i < len; i++) { list.add( LayoutBuilder( builder: (context, BoxConstraints box) { double maxWidth = box.maxWidth.truncateToDouble(); return Hero( tag: picList[i], child: GestureDetector( onTap: () => onPreviewImg(picList, i, context), child: NetworkImgLayer( src: pics[i].url, width: maxWidth, height: maxWidth, origAspectRatio: pics[i].width!.toInt() / pics[i].height!.toInt(), ), ), ); }, ), ); } spanChilds.add( WidgetSpan( child: LayoutBuilder( builder: (context, BoxConstraints box) { double maxWidth = box.maxWidth.truncateToDouble(); double crossCount = len < 3 ? 2 : 3; double height = maxWidth / crossCount * (len % crossCount == 0 ? len ~/ crossCount : len ~/ crossCount + 1) + 6; return Container( padding: const EdgeInsets.only(top: 6), height: height, child: GridView.count( padding: EdgeInsets.zero, physics: const NeverScrollableScrollPhysics(), crossAxisCount: crossCount.toInt(), mainAxisSpacing: 4.0, crossAxisSpacing: 4.0, childAspectRatio: 1, children: list, ), ); }, ), ), ); } return TextSpan( children: spanChilds, ); } void onPreviewImg(picList, initIndex, context) { Navigator.of(context).push( HeroDialogRoute( builder: (BuildContext context) => InteractiveviewerGallery( sources: picList, initIndex: initIndex, itemBuilder: ( BuildContext context, int index, bool isFocus, bool enablePageView, ) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { if (enablePageView) { Navigator.of(context).pop(); } }, child: Center( child: Hero( tag: picList[index], child: CachedNetworkImage( fadeInDuration: const Duration(milliseconds: 0), imageUrl: picList[index], fit: BoxFit.contain, ), ), ), ); }, onPageChanged: (int pageIndex) {}, ), ), ); } @override Widget build(BuildContext context) { TextStyle authorStyle = TextStyle(color: Theme.of(context).colorScheme.primary); return Container( width: double.infinity, padding: const EdgeInsets.fromLTRB(12, 0, 12, 6), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (widget.item.modules.moduleDynamic.topic != null) ...[ GestureDetector( child: Text( '#${widget.item.modules.moduleDynamic.topic.name}', style: authorStyle, ), ), ], IgnorePointer( // 禁用SelectableRegion的触摸交互功能 ignoring: widget.source == 'detail' ? false : true, child: SelectableRegion( magnifierConfiguration: const TextMagnifierConfiguration(), focusNode: FocusNode(), selectionControls: MaterialTextSelectionControls(), child: Text.rich( /// fix 默认20px高度 style: const TextStyle(height: 0), richNode(widget.item, context), maxLines: widget.source == 'detail' ? 999 : 3, overflow: TextOverflow.ellipsis, ), ), ), if (hasPics) ...[ Text.rich(picsNodes()), ] ], ), ); } }