diff --git a/lib/pages/dynamics/widgets/content_panel.dart b/lib/pages/dynamics/widgets/content_panel.dart index 5dda0b65..8d2e9a48 100644 --- a/lib/pages/dynamics/widgets/content_panel.dart +++ b/lib/pages/dynamics/widgets/content_panel.dart @@ -36,6 +36,7 @@ class Content extends StatelessWidget { Widget build(BuildContext context) { TextStyle authorStyle = TextStyle(color: Theme.of(context).colorScheme.primary); + InlineSpan? richNodes = richNode(item, context); return Container( width: double.infinity, @@ -51,25 +52,26 @@ class Content extends StatelessWidget { ), ), ], - IgnorePointer( - // 禁用SelectableRegion的触摸交互功能 - ignoring: source == 'detail' ? false : true, - child: SelectableRegion( - magnifierConfiguration: const TextMagnifierConfiguration(), - focusNode: FocusNode(), - selectionControls: MaterialTextSelectionControls(), - child: Text.rich( - /// fix 默认20px高度 - style: TextStyle( - height: 0, - fontSize: source == 'detail' ? 16 : 15, + if (richNodes != null) + IgnorePointer( + // 禁用SelectableRegion的触摸交互功能 + ignoring: source == 'detail' ? false : true, + child: SelectableRegion( + magnifierConfiguration: const TextMagnifierConfiguration(), + focusNode: FocusNode(), + selectionControls: MaterialTextSelectionControls(), + child: Text.rich( + /// fix 默认20px高度 + style: TextStyle( + height: 0, + fontSize: source == 'detail' ? 16 : 15, + ), + richNodes, + maxLines: source == 'detail' ? 999 : 6, + overflow: TextOverflow.ellipsis, ), - richNode(item, context), - maxLines: source == 'detail' ? 999 : 6, - overflow: TextOverflow.ellipsis, ), ), - ), if (item.modules.moduleDynamic.major != null && item.modules.moduleDynamic.major.opus != null && item.modules.moduleDynamic.major.opus.pics.isNotEmpty) diff --git a/lib/pages/dynamics/widgets/content_panel_grpc.dart b/lib/pages/dynamics/widgets/content_panel_grpc.dart index 0e6e5da7..111c5f37 100644 --- a/lib/pages/dynamics/widgets/content_panel_grpc.dart +++ b/lib/pages/dynamics/widgets/content_panel_grpc.dart @@ -38,7 +38,7 @@ class ContentGrpc extends StatelessWidget { Widget build(BuildContext context) { TextStyle authorStyle = TextStyle(color: Theme.of(context).colorScheme.primary); - + InlineSpan? richNodes = richNode(item, context); return Container( width: double.infinity, padding: const EdgeInsets.fromLTRB(12, 0, 12, 6), @@ -53,22 +53,23 @@ class ContentGrpc extends StatelessWidget { ), ), ], - 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 : 6, - overflow: TextOverflow.ellipsis, + if (richNodes != null) + 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), + richNodes, + maxLines: source == 'detail' ? 999 : 6, + overflow: TextOverflow.ellipsis, + ), ), ), - ), if (item.modules.first.moduleDynamic.hasDynDraw()) Text.rich( picsNodes(), diff --git a/lib/pages/dynamics/widgets/forward_panel.dart b/lib/pages/dynamics/widgets/forward_panel.dart index a08e7ca7..4e1538e0 100644 --- a/lib/pages/dynamics/widgets/forward_panel.dart +++ b/lib/pages/dynamics/widgets/forward_panel.dart @@ -45,6 +45,7 @@ Widget forWard(item, context, ctr, source, {floor = 1}) { if (hasPics) { pics = item.modules.moduleDynamic.major.opus.pics; } + InlineSpan? richNodes = richNode(item, context); switch (item.type) { // 图文 case 'DYNAMIC_TYPE_DRAW': @@ -89,12 +90,13 @@ Widget forWard(item, context, ctr, source, {floor = 1}) { // ), // ), // ], - Text.rich( - richNode(item, context), - // 被转发状态(floor=2) 隐藏 - maxLines: source == 'detail' && floor != 2 ? 999 : 4, - overflow: TextOverflow.ellipsis, - ), + if (richNodes != null) + Text.rich( + richNodes, + // 被转发状态(floor=2) 隐藏 + maxLines: source == 'detail' && floor != 2 ? 999 : 4, + overflow: TextOverflow.ellipsis, + ), if (hasPics) ...[ Text.rich( picsNodes(pics), @@ -180,12 +182,13 @@ Widget forWard(item, context, ctr, source, {floor = 1}) { ], ), const SizedBox(height: 8), - Text.rich( - richNode(item, context), - // 被转发状态(floor=2) 隐藏 - maxLines: source == 'detail' && floor != 2 ? 999 : 4, - overflow: TextOverflow.ellipsis, - ), + if (richNodes != null) + Text.rich( + richNodes, + // 被转发状态(floor=2) 隐藏 + maxLines: source == 'detail' && floor != 2 ? 999 : 4, + overflow: TextOverflow.ellipsis, + ), ], ) : item.modules.moduleDynamic.additional != null diff --git a/lib/pages/dynamics/widgets/live_panel.dart b/lib/pages/dynamics/widgets/live_panel.dart index 486ce700..7c5962ab 100644 --- a/lib/pages/dynamics/widgets/live_panel.dart +++ b/lib/pages/dynamics/widgets/live_panel.dart @@ -9,6 +9,7 @@ Widget livePanel(item, context, {floor = 1}) { dynamic content = item.modules.moduleDynamic.major; TextStyle authorStyle = TextStyle(color: Theme.of(context).colorScheme.primary); + InlineSpan? richNodes = richNode(item, context); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -50,7 +51,7 @@ Widget livePanel(item, context, {floor = 1}) { const SizedBox(height: 6), ], if (floor == 2 && item.modules.moduleDynamic.desc != null) ...[ - Text.rich(richNode(item, context)), + if (richNodes != null) Text.rich(richNodes), const SizedBox(height: 6), ], GestureDetector( diff --git a/lib/pages/dynamics/widgets/live_rcmd_panel.dart b/lib/pages/dynamics/widgets/live_rcmd_panel.dart index 255b423b..c7798947 100644 --- a/lib/pages/dynamics/widgets/live_rcmd_panel.dart +++ b/lib/pages/dynamics/widgets/live_rcmd_panel.dart @@ -16,6 +16,7 @@ Widget liveRcmdPanel(item, context, {floor = 1}) { DynamicLiveModel liveRcmd = item.modules.moduleDynamic.major.liveRcmd; int liveStatus = liveRcmd.liveStatus!; Map watchedShow = liveRcmd.watchedShow!; + InlineSpan? richNodes = richNode(item, context); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -56,7 +57,7 @@ Widget liveRcmdPanel(item, context, {floor = 1}) { const SizedBox(height: 6), ], if (floor == 2 && item.modules.moduleDynamic.desc != null) ...[ - Text.rich(richNode(item, context)), + if (richNodes != null) Text.rich(richNodes), const SizedBox(height: 6), ], Padding( diff --git a/lib/pages/dynamics/widgets/rich_node_panel.dart b/lib/pages/dynamics/widgets/rich_node_panel.dart index 4442e126..18c3a8da 100644 --- a/lib/pages/dynamics/widgets/rich_node_panel.dart +++ b/lib/pages/dynamics/widgets/rich_node_panel.dart @@ -1,3 +1,4 @@ +import 'package:PiliPalaX/models/dynamics/result.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; @@ -6,21 +7,21 @@ import 'package:PiliPalaX/http/search.dart'; import 'package:PiliPalaX/utils/app_scheme.dart'; // 富文本 -InlineSpan richNode(item, context) { +InlineSpan? richNode(item, context) { final spacer = _VerticalSpaceSpan(0.0); try { TextStyle authorStyle = TextStyle(color: Theme.of(context).colorScheme.primary); List spanChildren = []; - dynamic richTextNodes; + List? richTextNodes; if (item.modules.moduleDynamic.desc != null) { richTextNodes = item.modules.moduleDynamic.desc.richTextNodes; } else if (item.modules.moduleDynamic.major != null) { // 动态页面 richTextNodes 层级可能与主页动态层级不同 richTextNodes = - item.modules.moduleDynamic.major.opus.summary.richTextNodes; - if (item.modules.moduleDynamic.major.opus.title != null) { + item.modules.moduleDynamic.major.opus?.summary?.richTextNodes; + if (item.modules.moduleDynamic.major.opus?.title != null) { spanChildren.add( TextSpan( text: item.modules.moduleDynamic.major.opus.title + '\n', @@ -33,7 +34,7 @@ InlineSpan richNode(item, context) { } } if (richTextNodes == null || richTextNodes.isEmpty) { - return spacer; + return null; } else { for (var i in richTextNodes) { /// fix 渲染专栏时内容会重复 @@ -96,7 +97,11 @@ InlineSpan richNode(item, context) { alignment: PlaceholderAlignment.middle, child: GestureDetector( onTap: () { - String url = i.origText; + String? url = i.origText; + if (url == null) { + SmartDialog.showToast('未获取到链接'); + return; + } if (url.startsWith('//')) { url = url.replaceFirst('//', 'https://'); PiliScheme.routePush(Uri.parse(url)); @@ -114,7 +119,7 @@ InlineSpan richNode(item, context) { ); }, child: Text( - i.text, + i.text ?? '', style: authorStyle, ), ), @@ -150,14 +155,14 @@ InlineSpan richNode(item, context) { ); } // 表情 - if (i.type == 'RICH_TEXT_NODE_TYPE_EMOJI') { + if (i.type == 'RICH_TEXT_NODE_TYPE_EMOJI' && i.emoji != null) { spanChildren.add( WidgetSpan( child: NetworkImgLayer( - src: i.emoji.iconUrl, + src: i.emoji!.iconUrl, type: 'emote', - width: i.emoji.size * 20, - height: i.emoji.size * 20, + width: (i.emoji!.size ?? 1) * 20, + height: (i.emoji!.size ?? 1) * 20, ), ), ); diff --git a/lib/pages/dynamics/widgets/video_panel.dart b/lib/pages/dynamics/widgets/video_panel.dart index 8b8fc10d..4757785b 100644 --- a/lib/pages/dynamics/widgets/video_panel.dart +++ b/lib/pages/dynamics/widgets/video_panel.dart @@ -24,7 +24,7 @@ Widget videoSeasonWidget(item, context, type, {floor = 1}) { 'pgc': item.modules.moduleDynamic.major.pgc }; dynamic content = dynamicProperty[type]; - + InlineSpan? richNodes = richNode(item, context); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -73,7 +73,7 @@ Widget videoSeasonWidget(item, context, type, {floor = 1}) { // const SizedBox(height: 6), // ], if (floor == 2 && item.modules.moduleDynamic.desc != null) ...[ - Text.rich(richNode(item, context)), + if (richNodes != null) Text.rich(richNodes), const SizedBox(height: 6), ], Padding(