mod: article: show code

Closes #759

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-04-27 10:10:22 +08:00
parent c591b57f22
commit 3dad24e7b4
18 changed files with 78 additions and 25 deletions

View File

@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
class StyleString { class StyleString {
static const double cardSpace = 8; static const double cardSpace = 8;
static const double safeSpace = 12; static const double safeSpace = 12;
static const BorderRadius mdRadius = BorderRadius.all(Radius.circular(10)); static const BorderRadius mdRadius = BorderRadius.all(imgRadius);
static const Radius imgRadius = Radius.circular(10); static const Radius imgRadius = Radius.circular(10);
static const double aspectRatio = 16 / 10; static const double aspectRatio = 16 / 10;
} }

View File

@@ -88,7 +88,7 @@ class VideoCardHMemberVideo extends StatelessWidget {
Positioned.fill( Positioned.fill(
child: DecoratedBox( child: DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: StyleString.mdRadius,
color: Colors.black54, color: Colors.black54,
), ),
child: Center( child: Center(

View File

@@ -1,11 +1,12 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
Widget videoProgressIndicator(double progress) => ClipRect( Widget videoProgressIndicator(double progress) => ClipRect(
clipper: ProgressClipper(), clipper: ProgressClipper(),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10), bottomLeft: StyleString.imgRadius,
bottomRight: Radius.circular(10), bottomRight: StyleString.imgRadius,
), ),
child: LinearProgressIndicator( child: LinearProgressIndicator(
minHeight: 10, minHeight: 10,

View File

@@ -1114,7 +1114,7 @@ class VideoHttp {
'csrf': Accounts.main.csrf, 'csrf': Accounts.main.csrf,
}); });
if (res.data['code'] == 0) { if (res.data['code'] == 0) {
if (res.data['data']['noteIds'] != null) { if (res.data['data']?['noteIds'] != null) {
noteId = res.data['data']['noteIds'].first; noteId = res.data['data']['noteIds'].first;
} }
} }

View File

@@ -8,6 +8,7 @@ class Paragraph {
Pic? pic; Pic? pic;
Line? line; Line? line;
LinkCard? linkCard; LinkCard? linkCard;
Code? code;
Paragraph({ Paragraph({
this.align, this.align,
@@ -16,6 +17,7 @@ class Paragraph {
this.pic, this.pic,
this.line, this.line,
this.linkCard, this.linkCard,
this.code,
}); });
factory Paragraph.fromJson(Map<String, dynamic> json) => Paragraph( factory Paragraph.fromJson(Map<String, dynamic> json) => Paragraph(
@@ -31,6 +33,7 @@ class Paragraph {
linkCard: json['link_card'] == null linkCard: json['link_card'] == null
? null ? null
: LinkCard.fromJson(json['link_card']), : LinkCard.fromJson(json['link_card']),
code: json['code'] == null ? null : Code.fromJson(json['code']),
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
@@ -41,6 +44,16 @@ class Paragraph {
}; };
} }
class Code {
String? content;
String? lang;
Code.fromJson(Map<String, dynamic> json) {
content = json['content'];
lang = json['lang'];
}
}
class Ugc { class Ugc {
String? cover; String? cover;
String? descSecond; String? descSecond;

View File

@@ -85,7 +85,7 @@ class RcmdStat implements BaseStat {
class RcmdOwner extends BaseOwner { class RcmdOwner extends BaseOwner {
RcmdOwner.fromJson(Map<String, dynamic> json) { RcmdOwner.fromJson(Map<String, dynamic> json) {
name = json['goto'] == 'av' name = json['goto'] == 'av'
? (json['args']?['up_name']) ? (json['args']?['up_name'] ?? '')
: (json['desc_button']?['text'] ?? ''); : (json['desc_button']?['text'] ?? '');
mid = json['args']?['up_id'] ?? 0; mid = json['args']?['up_id'] ?? 0;
} }

View File

@@ -1,3 +1,4 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart' import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'
show SourceModel; show SourceModel;
import 'package:PiliPlus/common/widgets/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/network_img_layer.dart';
@@ -9,6 +10,9 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:re_highlight/languages/all.dart';
import 'package:re_highlight/re_highlight.dart';
import 'package:re_highlight/styles/all.dart';
Widget opusContent({ Widget opusContent({
required BuildContext context, required BuildContext context,
@@ -95,7 +99,7 @@ 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?.map<TextSpan>((item) {
if (item.rich != null) { if (item.rich != null) {
return TextSpan( return TextSpan(
text: '\u{1F517}${item.rich?.text}', text: '\u{1F517}${item.rich?.text}',
@@ -149,10 +153,7 @@ Widget opusContent({
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
if (callback != null) { if (callback != null) {
callback( callback([element.pic!.pics!.first.url!], 0);
[element.pic!.pics!.first.url!],
0,
);
} else { } else {
context.imageView( context.imageView(
initialPage: 0, initialPage: 0,
@@ -183,8 +184,7 @@ Widget opusContent({
if (element.paraType == 6) { if (element.paraType == 6) {
if (element.linkCard?.card?.ugc != null) { if (element.linkCard?.card?.ugc != null) {
return Card( return Material(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: borderRadius:
const BorderRadius.all(Radius.circular(8)), const BorderRadius.all(Radius.circular(8)),
@@ -207,7 +207,7 @@ Widget opusContent({
children: [ children: [
NetworkImgLayer( NetworkImgLayer(
radius: 6, radius: 6,
width: 65 * 16 / 10, width: 65 * StyleString.aspectRatio,
height: 65, height: 65,
src: element.linkCard!.card!.ugc!.cover, src: element.linkCard!.card!.ugc!.cover,
), ),
@@ -237,6 +237,32 @@ Widget opusContent({
} }
} }
if (element.paraType == 7) {
final Highlight highlight = Highlight()
..registerLanguages(builtinAllLanguages);
final HighlightResult result = highlight.highlightAuto(
element.code!.content!,
element.code!.lang == 'language-clike'
? ['c', 'java']
: [
element.code!.lang!
.replaceAll('language-', '')
.replaceAll('like', ''),
]);
final TextSpanRenderer renderer = TextSpanRenderer(
const TextStyle(), builtinAllThemes['github']!);
result.render(renderer);
return Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(8)),
color: Theme.of(context).colorScheme.onInverseSurface,
),
width: double.infinity,
child: SelectableText.rich(renderer.span!),
);
}
return const SizedBox.shrink(); return const SizedBox.shrink();
}, },
separatorBuilder: (BuildContext context, int index) => separatorBuilder: (BuildContext context, int index) =>

View File

@@ -118,7 +118,7 @@ class FavNoteItem extends StatelessWidget {
width: constraints.maxHeight * width: constraints.maxHeight *
StyleString.aspectRatio, StyleString.aspectRatio,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: StyleString.mdRadius,
color: Colors.black.withOpacity(0.6), color: Colors.black.withOpacity(0.6),
), ),
child: SizedBox( child: SizedBox(

View File

@@ -534,7 +534,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
width: constraints.maxHeight * width: constraints.maxHeight *
StyleString.aspectRatio, StyleString.aspectRatio,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: StyleString.mdRadius,
color: Colors.black.withOpacity(0.6), color: Colors.black.withOpacity(0.6),
), ),
child: SizedBox( child: SizedBox(

View File

@@ -182,7 +182,7 @@ class HistoryItem extends StatelessWidget {
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: StyleString.mdRadius,
color: Colors.black.withOpacity(0.6), color: Colors.black.withOpacity(0.6),
), ),
child: SizedBox( child: SizedBox(

View File

@@ -1,3 +1,4 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/models/common/dynamic_badge_mode.dart'; import 'package:PiliPlus/models/common/dynamic_badge_mode.dart';
import 'package:PiliPlus/pages/main/index.dart'; import 'package:PiliPlus/pages/main/index.dart';
import 'package:PiliPlus/pages/mine/controller.dart'; import 'package:PiliPlus/pages/mine/controller.dart';
@@ -52,7 +53,7 @@ class _HomePageState extends State<HomePage>
dividerColor: Colors.transparent, dividerColor: Colors.transparent,
dividerHeight: 0, dividerHeight: 0,
enableFeedback: true, enableFeedback: true,
splashBorderRadius: BorderRadius.circular(10), splashBorderRadius: StyleString.mdRadius,
tabAlignment: TabAlignment.center, tabAlignment: TabAlignment.center,
onTap: (value) { onTap: (value) {
feedBack(); feedBack();

View File

@@ -132,7 +132,7 @@ class _LaterViewChildPageState extends State<LaterViewChildPage>
width: constraints.maxHeight * width: constraints.maxHeight *
StyleString.aspectRatio, StyleString.aspectRatio,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: StyleString.mdRadius,
color: Colors.black.withOpacity(0.6), color: Colors.black.withOpacity(0.6),
), ),
child: SizedBox( child: SizedBox(

View File

@@ -1,3 +1,4 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/avatar.dart'; import 'package:PiliPlus/common/widgets/avatar.dart';
import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart' import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'
show SourceModel; show SourceModel;
@@ -145,8 +146,9 @@ class UserInfoCard extends StatelessWidget {
padding: padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 3), const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(10)), borderRadius: StyleString.mdRadius,
color: context.vipColor), color: context.vipColor,
),
child: Text( child: Text(
card.vip?.label?.text ?? '大会员', card.vip?.label?.text ?? '大会员',
strutStyle: const StrutStyle( strutStyle: const StrutStyle(

View File

@@ -564,7 +564,7 @@ class _PostPanelState extends CommonCollapseSlidePageState<PostPanel> {
} }
} else { } else {
if (const [301, 302, 303, 307, 308].contains(res.statusCode)) { if (const [301, 302, 303, 307, 308].contains(res.statusCode)) {
String? redirectUrl = res.headers['location']?.first; String? redirectUrl = res.headers['location']?.firstOrNull;
if (redirectUrl != null) { if (redirectUrl != null) {
_onPost(url: redirectUrl); _onPost(url: redirectUrl);
return; return;

View File

@@ -1,3 +1,4 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/pages/webdav/webdav.dart'; import 'package:PiliPlus/pages/webdav/webdav.dart';
import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -83,7 +84,7 @@ class _WebDavSettingPageState extends State<WebDavSettingPage> {
child: FilledButton.tonal( child: FilledButton.tonal(
style: FilledButton.styleFrom( style: FilledButton.styleFrom(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius: StyleString.mdRadius,
), ),
), ),
onPressed: WebDav().backup, onPressed: WebDav().backup,
@@ -95,7 +96,7 @@ class _WebDavSettingPageState extends State<WebDavSettingPage> {
child: FilledButton.tonal( child: FilledButton.tonal(
style: FilledButton.styleFrom( style: FilledButton.styleFrom(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius: StyleString.mdRadius,
), ),
), ),
onPressed: WebDav().restore, onPressed: WebDav().restore,

View File

@@ -25,7 +25,7 @@ class UrlUtils {
), ),
); );
if (response.statusCode == 302 || response.statusCode == 301) { if (response.statusCode == 302 || response.statusCode == 301) {
String? redirectUrl = response.headers['location']?.first; String? redirectUrl = response.headers['location']?.firstOrNull;
debugPrint('redirectUrl: $redirectUrl'); debugPrint('redirectUrl: $redirectUrl');
if (redirectUrl != null) { if (redirectUrl != null) {
if (redirectUrl.startsWith('/')) { if (redirectUrl.startsWith('/')) {

View File

@@ -1480,6 +1480,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.0.2"
re_highlight:
dependency: "direct main"
description:
name: re_highlight
sha256: "6c4ac3f76f939fb7ca9df013df98526634e17d8f7460e028bd23a035870024f2"
url: "https://pub.dev"
source: hosted
version: "0.0.3"
rxdart: rxdart:
dependency: "direct overridden" dependency: "direct overridden"
description: description:

View File

@@ -190,6 +190,7 @@ dependencies:
synchronized: ^3.3.0 synchronized: ^3.3.0
document_file_save_plus: ^2.0.0 document_file_save_plus: ^2.0.0
webdav_client: ^1.2.2 webdav_client: ^1.2.2
re_highlight: ^0.0.3
dependency_overrides: dependency_overrides:
screen_brightness: ^2.0.1 screen_brightness: ^2.0.1