From 353287e053165e2e04a3552a5174c5d590aa7c56 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 14 Oct 2023 14:11:16 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E5=8A=A8=E6=80=81=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dynamics/widgets/additional_panel.dart | 110 ++++----- lib/pages/dynamics/widgets/content_panel.dart | 209 ++++++++++++++--- lib/pages/dynamics/widgets/dynamic_panel.dart | 2 +- .../dynamics/widgets/rich_node_panel.dart | 222 +++++++++--------- 4 files changed, 343 insertions(+), 200 deletions(-) diff --git a/lib/pages/dynamics/widgets/additional_panel.dart b/lib/pages/dynamics/widgets/additional_panel.dart index f25b913e..ee26e73e 100644 --- a/lib/pages/dynamics/widgets/additional_panel.dart +++ b/lib/pages/dynamics/widgets/additional_panel.dart @@ -124,60 +124,62 @@ Widget addWidget(item, context, type, {floor = 1}) { ) : const SizedBox(); case 'ADDITIONAL_TYPE_GOODS': - return Padding( - padding: const EdgeInsets.only(top: 6), - child: InkWell( - onTap: () {}, - child: Container( - padding: - const EdgeInsets.only(left: 12, top: 8, right: 12, bottom: 8), - decoration: BoxDecoration( - color: bgColor, - borderRadius: const BorderRadius.all(Radius.circular(6)), - ), - child: Row( - children: [ - NetworkImgLayer( - width: 75, - height: 75, - src: dynamicProperty[type].items.first.cover, - ), - const SizedBox(width: 10), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - dynamicProperty[type].items.first.name, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - Text( - dynamicProperty[type].items.first.brief, - maxLines: 1, - style: TextStyle( - color: Theme.of(context).colorScheme.outline, - fontSize: Theme.of(context) - .textTheme - .labelMedium! - .fontSize, - ), - ), - const SizedBox(height: 2), - Text( - dynamicProperty[type].items.first.price, - style: TextStyle( - color: Theme.of(context).colorScheme.primary, - ), - ), - ], - ), - ), - ], - ), - ), - )); + // 商品 + return const SizedBox(); + // return Padding( + // padding: const EdgeInsets.only(top: 6), + // child: InkWell( + // onTap: () {}, + // child: Container( + // padding: + // const EdgeInsets.only(left: 12, top: 8, right: 12, bottom: 8), + // decoration: BoxDecoration( + // color: bgColor, + // borderRadius: const BorderRadius.all(Radius.circular(6)), + // ), + // child: Row( + // children: [ + // NetworkImgLayer( + // width: 75, + // height: 75, + // src: dynamicProperty[type].items.first.cover, + // ), + // const SizedBox(width: 10), + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // Text( + // dynamicProperty[type].items.first.name, + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // ), + // Text( + // dynamicProperty[type].items.first.brief, + // maxLines: 1, + // style: TextStyle( + // color: Theme.of(context).colorScheme.outline, + // fontSize: Theme.of(context) + // .textTheme + // .labelMedium! + // .fontSize, + // ), + // ), + // const SizedBox(height: 2), + // Text( + // dynamicProperty[type].items.first.price, + // style: TextStyle( + // color: Theme.of(context).colorScheme.primary, + // ), + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // ),); case 'ADDITIONAL_TYPE_MATCH': return const SizedBox(); case 'ADDITIONAL_TYPE_COMMON': diff --git a/lib/pages/dynamics/widgets/content_panel.dart b/lib/pages/dynamics/widgets/content_panel.dart index d6174975..680d21a2 100644 --- a/lib/pages/dynamics/widgets/content_panel.dart +++ b/lib/pages/dynamics/widgets/content_panel.dart @@ -1,42 +1,183 @@ // 内容 import 'package:flutter/material.dart'; +import 'package:pilipala/common/widgets/network_img_layer.dart'; +import 'package:pilipala/models/dynamics/result.dart'; +import 'package:pilipala/pages/preview/index.dart'; import 'rich_node_panel.dart'; -Widget content(item, context, source) { - 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 (item.modules.moduleDynamic.topic != null) ...[ - GestureDetector( - child: Text( - '#${item.modules.moduleDynamic.topic.name}', - style: authorStyle, - ), - ), - ], - IgnorePointer( - // 禁用SelectableRegion的触摸交互功能 - ignoring: source == 'detail' ? false : true, - child: SelectableRegion( - magnifierConfiguration: const TextMagnifierConfiguration(), - focusNode: FocusNode(), - selectionControls: MaterialTextSelectionControls(), - child: Text.rich( - /// fix 默认20px高度 - style: const TextStyle(height: 0), - richNode(item, context), - maxLines: source == 'detail' ? 999 : 3, - overflow: TextOverflow.ellipsis, - ), +// 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) { + return GestureDetector( + onTap: () { + showDialog( + useSafeArea: false, + context: context, + builder: (context) { + return ImagePreview(initialPage: 0, imgList: picList); + }, + ); + }, + child: Padding( + padding: const EdgeInsets.only(top: 4), + child: NetworkImgLayer( + src: pictureItem.url, + width: box.maxWidth / 2, + height: box.maxWidth * + 0.5 * + (pictureItem.height != null && pictureItem.width != null + ? pictureItem.height! / pictureItem.width! + : 1), + ), + ), + ); + }, ), ), - ], - ), - ); + ); + } + if (len > 1) { + List list = []; + for (var i = 0; i < len; i++) { + picList.add(pics[i].url!); + list.add( + LayoutBuilder( + builder: (context, BoxConstraints box) { + return GestureDetector( + onTap: () { + showDialog( + useSafeArea: false, + context: context, + builder: (context) { + return ImagePreview(initialPage: i, imgList: picList); + }, + ); + }, + child: NetworkImgLayer( + src: pics[i].url, + width: box.maxWidth, + height: box.maxWidth, + ), + ); + }, + ), + ); + } + spanChilds.add( + WidgetSpan( + child: LayoutBuilder( + builder: (context, BoxConstraints box) { + double maxWidth = box.maxWidth; + 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, + ); + } + + @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()), + ] + ], + ), + ); + } } diff --git a/lib/pages/dynamics/widgets/dynamic_panel.dart b/lib/pages/dynamics/widgets/dynamic_panel.dart index 366f7ffe..c85cad45 100644 --- a/lib/pages/dynamics/widgets/dynamic_panel.dart +++ b/lib/pages/dynamics/widgets/dynamic_panel.dart @@ -43,7 +43,7 @@ class DynamicPanel extends StatelessWidget { ), if (item!.modules!.moduleDynamic!.desc != null || item!.modules!.moduleDynamic!.major != null) - content(item, context, source), + Content(item: item, source: source), forWard(item, context, _dynamicsController, source), const SizedBox(height: 2), if (source == null) ActionPanel(item: item), diff --git a/lib/pages/dynamics/widgets/rich_node_panel.dart b/lib/pages/dynamics/widgets/rich_node_panel.dart index 27820b27..cab42664 100644 --- a/lib/pages/dynamics/widgets/rich_node_panel.dart +++ b/lib/pages/dynamics/widgets/rich_node_panel.dart @@ -193,118 +193,118 @@ InlineSpan richNode(item, context) { ); } } - if (contentType == 'major' && - item.modules.moduleDynamic.major.opus.pics.isNotEmpty) { - // 图片可能跟其他widget重复渲染 - List pics = item.modules.moduleDynamic.major.opus.pics; - int len = pics.length; - List picList = []; + // if (contentType == 'major' && + // item.modules.moduleDynamic.major.opus.pics.isNotEmpty) { + // // 图片可能跟其他widget重复渲染 + // List pics = item.modules.moduleDynamic.major.opus.pics; + // 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) { - return GestureDetector( - onTap: () { - showDialog( - useSafeArea: false, - context: context, - builder: (context) { - return ImagePreview(initialPage: 0, imgList: picList); - }, - ); - }, - child: Padding( - padding: const EdgeInsets.only(top: 4), - child: NetworkImgLayer( - src: pictureItem.url, - width: box.maxWidth / 2, - height: box.maxWidth * - 0.5 * - (pictureItem.height != null && - pictureItem.width != null - ? pictureItem.height! / pictureItem.width! - : 1), - ), - ), - ); - }, - ), - ), - ); - } - if (len > 1) { - List list = []; - for (var i = 0; i < len; i++) { - picList.add(pics[i].url!); - list.add( - LayoutBuilder( - builder: (context, BoxConstraints box) { - return GestureDetector( - onTap: () { - showDialog( - useSafeArea: false, - context: context, - builder: (context) { - return ImagePreview(initialPage: i, imgList: picList); - }, - ); - }, - child: NetworkImgLayer( - src: pics[i].url, - width: box.maxWidth, - height: box.maxWidth, - ), - ); - }, - ), - ); - } - spanChilds.add( - WidgetSpan( - child: LayoutBuilder( - builder: (context, BoxConstraints box) { - double maxWidth = box.maxWidth; - 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, - ), - ); - }, - ), - ), - ); - } - // spanChilds.add( - // WidgetSpan( - // child: NetworkImgLayer( - // src: pics.first.url, - // type: 'emote', - // width: 100, - // height: 200, - // ), - // ), - // ); - } + // 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) { + // return GestureDetector( + // onTap: () { + // showDialog( + // useSafeArea: false, + // context: context, + // builder: (context) { + // return ImagePreview(initialPage: 0, imgList: picList); + // }, + // ); + // }, + // child: Padding( + // padding: const EdgeInsets.only(top: 4), + // child: NetworkImgLayer( + // src: pictureItem.url, + // width: box.maxWidth / 2, + // height: box.maxWidth * + // 0.5 * + // (pictureItem.height != null && + // pictureItem.width != null + // ? pictureItem.height! / pictureItem.width! + // : 1), + // ), + // ), + // ); + // }, + // ), + // ), + // ); + // } + // if (len > 1) { + // List list = []; + // for (var i = 0; i < len; i++) { + // picList.add(pics[i].url!); + // list.add( + // LayoutBuilder( + // builder: (context, BoxConstraints box) { + // return GestureDetector( + // onTap: () { + // showDialog( + // useSafeArea: false, + // context: context, + // builder: (context) { + // return ImagePreview(initialPage: i, imgList: picList); + // }, + // ); + // }, + // child: NetworkImgLayer( + // src: pics[i].url, + // width: box.maxWidth, + // height: box.maxWidth, + // ), + // ); + // }, + // ), + // ); + // } + // spanChilds.add( + // WidgetSpan( + // child: LayoutBuilder( + // builder: (context, BoxConstraints box) { + // double maxWidth = box.maxWidth; + // 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, + // ), + // ); + // }, + // ), + // ), + // ); + // } + // spanChilds.add( + // WidgetSpan( + // child: NetworkImgLayer( + // src: pics.first.url, + // type: 'emote', + // width: 100, + // height: 200, + // ), + // ), + // ); + // } return TextSpan( children: spanChilds, );