opt: opus quote (#771)

This commit is contained in:
My-Responsitories
2025-04-28 20:57:30 +08:00
committed by GitHub
parent e65ec1b0b9
commit 451a84e696
2 changed files with 247 additions and 250 deletions

View File

@@ -357,8 +357,7 @@ class _ArticlePageState extends State<ArticlePage>
);
} else {
debugPrint('json page');
content = opusContent(
context: context,
content = OpusContent(
opus: _articleCtr.opus!,
callback: _getImageCallback,
maxWidth: maxWidth,

View File

@@ -3,7 +3,7 @@ import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactivevie
show SourceModel;
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
import 'package:PiliPlus/models/dynamics/article_content_model.dart'
show ArticleContentModel;
show ArticleContentModel, Style, Word;
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/utils.dart';
@@ -15,12 +15,38 @@ import 'package:re_highlight/languages/all.dart';
import 'package:re_highlight/re_highlight.dart';
import 'package:re_highlight/styles/all.dart';
Widget opusContent({
required BuildContext context,
required List<ArticleContentModel> opus,
Function(List<String>, int)? callback,
required double maxWidth,
}) {
class OpusContent extends StatelessWidget {
final List<ArticleContentModel> opus;
final void Function(List<String>, int)? callback;
final double maxWidth;
const OpusContent({
super.key,
required this.opus,
this.callback,
required this.maxWidth,
});
static TextStyle _getStyle(Style? style, [Color? color, double? fontSize]) =>
TextStyle(
decoration:
style?.strikethrough == true ? TextDecoration.lineThrough : null,
fontStyle: style?.italic == true ? FontStyle.italic : null,
fontWeight: style?.bold == true ? FontWeight.bold : null,
color: color,
fontSize: fontSize,
);
static TextSpan _getSpan(Word? word) => TextSpan(
text: word?.words,
style: _getStyle(
word?.style,
word?.color != null ? Color(word!.color!) : null,
word?.fontSize,
));
@override
Widget build(BuildContext context) {
debugPrint('opusContent');
if (opus.isEmpty) {
@@ -33,7 +59,7 @@ Widget opusContent({
final element = opus[index];
try {
switch (element.paraType) {
case 1 || 4:
case 1:
return SelectableText.rich(
textAlign: element.align == 1 ? TextAlign.center : null,
TextSpan(
@@ -41,44 +67,54 @@ Widget opusContent({
if (item.rich != null) {
return TextSpan(
text: '\u{1F517}${item.rich?.text}',
style: TextStyle(
decoration: item.rich?.style?.strikethrough == true
? TextDecoration.lineThrough
: null,
fontStyle: item.rich?.style?.italic == true
? FontStyle.italic
: null,
fontWeight: item.rich?.style?.bold == true
? FontWeight.bold
: null,
color: colorScheme.primary,
),
recognizer: TapGestureRecognizer()
style: _getStyle(item.rich?.style, colorScheme.primary),
recognizer: item.rich?.jumpUrl == null
? null
: (TapGestureRecognizer()
..onTap = () {
if (item.rich?.jumpUrl != null) {
PiliScheme.routePushFromUrl(item.rich!.jumpUrl!);
}),
);
}
},
return _getSpan(item.word);
}).toList()),
);
case 4:
return Container(
padding: const EdgeInsets.only(left: 8),
decoration: const BoxDecoration(
border: Border(
left: BorderSide(color: Color(0xFFE0E0E0), width: 4),
),
),
child: SelectableText.rich(
textAlign: element.align == 1 ? TextAlign.center : null,
TextSpan(
children: element.text?.nodes?.map<TextSpan>((item) {
if (item.rich != null) {
return TextSpan(
text: '\u{1F517}${item.rich?.text}',
style: _getStyle(item.rich?.style, colorScheme.primary),
recognizer: item.rich?.jumpUrl == null
? null
: (TapGestureRecognizer()
..onTap = () {
PiliScheme.routePushFromUrl(
item.rich!.jumpUrl!);
}),
);
}
return TextSpan(
text: item.word?.words,
style: TextStyle(
decoration: item.word?.style?.strikethrough == true
? TextDecoration.lineThrough
: null,
fontStyle: item.word?.style?.italic == true
? FontStyle.italic
: null,
fontWeight:
item.word?.style?.bold == true ? FontWeight.bold : null,
color: item.word?.color != null
? Color(item.word!.color!)
: null,
fontSize: item.word?.fontSize,
),
);
style: _getStyle(
item.word?.style,
item.word?.color != null
? Color(item.word!.color!).withOpacity(0.7)
: colorScheme.onSurface.withOpacity(0.7),
item.word?.fontSize,
));
}).toList()),
),
);
case 2 when (element.pic != null):
element.pic!.pics!.first.onCalHeight(maxWidth);
@@ -87,7 +123,7 @@ Widget opusContent({
child: GestureDetector(
onTap: () {
if (callback != null) {
callback([element.pic!.pics!.first.url!], 0);
callback!([element.pic!.pics!.first.url!], 0);
} else {
context.imageView(
initialPage: 0,
@@ -109,45 +145,23 @@ Widget opusContent({
return CachedNetworkImage(
width: maxWidth,
fit: BoxFit.contain,
height: element.line?.pic?.height?.toDouble(),
height: element.line!.pic!.height?.toDouble(),
imageUrl: Utils.thumbnailImgUrl(element.line!.pic!.url!),
);
case 5 when (element.list != null):
return SelectableText.rich(
TextSpan(
children: element.list!.items?.asMap().entries.map((entry) {
children: element.list!.items?.indexed.map((entry) {
return TextSpan(
children: [
WidgetSpan(
child: Icon(MdiIcons.circleMedium),
alignment: PlaceholderAlignment.middle,
),
...entry.value.nodes!.map((item) {
return TextSpan(
children: [
TextSpan(
text: item.word?.words,
style: TextStyle(
decoration:
item.word?.style?.strikethrough == true
? TextDecoration.lineThrough
: null,
fontStyle: item.word?.style?.italic == true
? FontStyle.italic
: null,
fontWeight: item.word?.style?.bold == true
? FontWeight.bold
: null,
color: item.word?.color != null
? Color(item.word!.color!)
: null,
fontSize: item.word?.fontSize,
),
),
],
);
...entry.$2.nodes!.map((item) {
return _getSpan(item.word);
}),
if (entry.key < element.list!.items!.length - 1)
if (entry.$1 < element.list!.items!.length - 1)
const TextSpan(text: '\n'),
],
);
@@ -231,26 +245,9 @@ Widget opusContent({
return SelectableText.rich(
textAlign: element.align == 1 ? TextAlign.center : null,
TextSpan(
children: element.text!.nodes!.map<TextSpan>((item) {
return TextSpan(
text: item.word?.words,
style: TextStyle(
decoration: item.word?.style?.strikethrough == true
? TextDecoration.lineThrough
: null,
fontStyle: item.word?.style?.italic == true
? FontStyle.italic
: null,
fontWeight: item.word?.style?.bold == true
? FontWeight.bold
: null,
color: item.word?.color != null
? Color(item.word!.color!)
: null,
fontSize: item.word?.fontSize,
),
);
}).toList()),
children: element.text!.nodes!
.map<TextSpan>((item) => _getSpan(item.word))
.toList()),
);
}
@@ -270,4 +267,5 @@ Widget opusContent({
},
separatorBuilder: (context, index) => const SizedBox(height: 10),
);
}
}