feat: custom horizontal preview

Closes #117

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-01-08 19:13:37 +08:00
parent 0b9d4d970a
commit 8d4294ba75
22 changed files with 255 additions and 97 deletions

View File

@@ -4,7 +4,7 @@ import 'package:PiliPlus/utils/utils.dart';
import '../../../common/constants.dart';
import 'pic_panel.dart';
Widget articlePanel(item, context, {floor = 1}) {
Widget articlePanel(item, context, callback, {floor = 1}) {
TextStyle authorStyle =
TextStyle(color: Theme.of(context).colorScheme.primary);
return Padding(
@@ -52,7 +52,7 @@ Widget articlePanel(item, context, {floor = 1}) {
),
const SizedBox(height: 2),
],
picWidget(item, context)
picWidget(item, context, callback)
],
),
);

View File

@@ -4,15 +4,7 @@ import 'package:flutter/material.dart';
import 'rich_node_panel.dart';
class Content extends StatelessWidget {
final dynamic item;
final String? source;
const Content({
super.key,
this.item,
this.source,
});
Widget content(context, item, source, callback) {
InlineSpan picsNodes() {
return WidgetSpan(
child: LayoutBuilder(
@@ -27,60 +19,58 @@ class Content extends StatelessWidget {
),
)
.toList(),
callback: callback,
),
),
);
}
@override
Widget build(BuildContext context) {
TextStyle authorStyle =
TextStyle(color: Theme.of(context).colorScheme.primary);
InlineSpan? richNodes = richNode(item, 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),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item.modules.moduleDynamic.topic != null) ...[
GestureDetector(
child: Text(
'#${item.modules.moduleDynamic.topic.name}',
style: authorStyle,
),
),
],
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,
),
),
),
if (item.modules.moduleDynamic.major != null &&
item.modules.moduleDynamic.major.opus != null &&
item.modules.moduleDynamic.major.opus.pics.isNotEmpty)
Text.rich(
picsNodes(),
// semanticsLabel: '动态图片',
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,
),
),
],
),
);
}
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,
),
),
),
if (item.modules.moduleDynamic.major != null &&
item.modules.moduleDynamic.major.opus != null &&
item.modules.moduleDynamic.major.opus.pics.isNotEmpty)
Text.rich(
picsNodes(),
// semanticsLabel: '动态图片',
),
],
),
);
}

View File

@@ -10,11 +10,13 @@ class DynamicPanel extends StatelessWidget {
final dynamic item;
final String? source;
final Function? onRemove;
final Function(List<String>, int)? callback;
DynamicPanel({
required this.item,
this.source,
this.onRemove,
this.callback,
super.key,
});
@@ -58,8 +60,8 @@ class DynamicPanel extends StatelessWidget {
),
if (item!.modules!.moduleDynamic!.desc != null ||
item!.modules!.moduleDynamic!.major != null)
Content(item: item, source: source),
forWard(item, context, _dynamicsController, source),
content(context, item, source, callback),
forWard(item, context, _dynamicsController, source, callback),
const SizedBox(height: 2),
if (source == null) ActionPanel(item: item),
],

View File

@@ -15,7 +15,7 @@ import 'pic_panel.dart';
import 'rich_node_panel.dart';
import 'video_panel.dart';
InlineSpan picsNodes(List<OpusPicsModel> pics) {
InlineSpan picsNodes(List<OpusPicsModel> pics, callback) {
return WidgetSpan(
child: LayoutBuilder(
builder: (context, constraints) => imageview(
@@ -29,12 +29,13 @@ InlineSpan picsNodes(List<OpusPicsModel> pics) {
),
)
.toList(),
callback: callback,
),
),
);
}
Widget forWard(item, context, ctr, source, {floor = 1}) {
Widget forWard(item, context, ctr, source, callback, {floor = 1}) {
TextStyle authorStyle =
TextStyle(color: Theme.of(context).colorScheme.primary);
@@ -100,7 +101,7 @@ Widget forWard(item, context, ctr, source, {floor = 1}) {
),
if (hasPics) ...[
Text.rich(
picsNodes(pics),
picsNodes(pics, callback),
// semanticsLabel: '动态图片',
),
],
@@ -110,7 +111,7 @@ Widget forWard(item, context, ctr, source, {floor = 1}) {
padding: floor == 2
? EdgeInsets.zero
: const EdgeInsets.only(left: 12, right: 12),
child: picWidget(item, context),
child: picWidget(item, context, callback),
),
/// 附加内容 商品信息、直播预约等等
@@ -129,7 +130,7 @@ Widget forWard(item, context, ctr, source, {floor = 1}) {
// 文章
case 'DYNAMIC_TYPE_ARTICLE':
return item is ItemOrigModel
? articlePanel(item, context, floor: floor)
? articlePanel(item, context, callback, floor: floor)
: const SizedBox.shrink();
// return Container(
// padding:
@@ -144,7 +145,8 @@ Widget forWard(item, context, ctr, source, {floor = 1}) {
padding:
const EdgeInsets.only(left: 15, top: 10, right: 15, bottom: 8),
color: Theme.of(context).dividerColor.withOpacity(0.08),
child: forWard(item.orig, context, ctr, source, floor: floor + 1),
child: forWard(item.orig, context, ctr, source, callback,
floor: floor + 1),
),
);
// 直播

View File

@@ -1,7 +1,7 @@
import 'package:PiliPlus/common/widgets/imageview.dart';
import 'package:flutter/material.dart';
Widget picWidget(item, context) {
Widget picWidget(item, context, callback) {
String type = item.modules.moduleDynamic.major.type;
if (type == 'MAJOR_TYPE_OPUS') {
/// fix 图片跟rich_node_panel重复
@@ -20,6 +20,7 @@ Widget picWidget(item, context) {
),
)
.toList(),
callback: callback,
),
);
}