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 { } else {
debugPrint('json page'); debugPrint('json page');
content = opusContent( content = OpusContent(
context: context,
opus: _articleCtr.opus!, opus: _articleCtr.opus!,
callback: _getImageCallback, callback: _getImageCallback,
maxWidth: maxWidth, maxWidth: maxWidth,

View File

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